Compare commits

..

603 Commits

Author SHA1 Message Date
Jamie Snape
5d5bb52ec2 Fix paths in pkg-config file (#556)
pkg-config should be giving absolute paths rather than relative paths.
2018-02-02 09:12:34 -06:00
Jesse Beder
f5d5604a2c Update README. 2018-01-28 10:36:23 -06:00
Jesse Beder
aac4df342b Bump version to 0.6.0. 2018-01-28 10:23:36 -06:00
Guillaume Dumont
4c9e3d87e1 Fix build for shared libraries with MSVC 12 (#380) 2018-01-28 10:20:57 -06:00
Denis Gladkikh
cfb7606a84 Fix tag parsing with () (#532) 2018-01-28 10:18:55 -06:00
Cybel
86ae3a5aa7 Change None in C/C++ source to NoneType. (#545)
* Change None in C/C++ source to NoneType.

Prevent name conflict with X11 None definition.
2017-11-29 13:12:01 -06:00
Matthew Woehlke
752804372c Separate tests and tools
Don't build tests if the confusingly named YAML_CPP_BUILD_TOOLS is ON.
Instead, add a new option that controls only if the tests are built.
(Also, default tests to OFF.)
2017-11-14 08:43:53 -08:00
Ryan Schmidt
3f33f337a7 Only use -Wno-c99-extensions for clang 2017-11-14 07:07:37 -08:00
Matthew Woehlke
5a519a4c6c Fix NullEventHandler overloads
Fix some virtual methods of NullEventHandler that were apparently
intended to overload base class methods, but did not. Add override
keyword to prevent these getting out of sync again.
2017-11-10 15:17:46 -08:00
Matthew Woehlke
58687ee7c4 Add explicit virtual dtor
Add explicit virtual dtor to GraphBuilderInterface. This avoids tripping
a -Wnon-virtual-dtor warning, and also ensures that the correct
(virtual) dtor is called if an instance is deleted via a pointer to the
base type.
2017-11-10 15:17:46 -08:00
Matthew Woehlke
dc9c750efd Avoid absolute install destinations
Remove use of CMAKE_INSTALL_PREFIX when specifying install destinations.
It is preferred that install destinations are specified as relative
paths, not absolute paths. This is also needed to create relocatable
installs, and thus should fix #526.
2017-11-09 18:26:52 -08:00
Matthew Woehlke
d96826f12b Fix Windows library install location
Don't install LIBRARIES on Windows to `bin`; they belong in `lib`. (This
appears to have been done in a mistaken attempt to install the DLL's to
`bin`, which do need to be there, but RUNTIME DESTINATION already takes
care of this.)
2017-11-09 18:26:52 -08:00
Alain Vaucher
46dcdc3ea2 Add missing include directive 2017-11-08 07:08:59 -08:00
Roger Leigh
beb44b872c travis: Exclude linux/clang from the build matrix
The combination of clang++ 3.4 with libstdc++ from GCC 4.6
doesn't work.
2017-08-24 22:49:17 -05:00
Roger Leigh
5e24f35816 test: Upgrade googlemock 1.7.0 to googletest 1.8.0
Note that with the release of 1.8.0, googlemock and
googletest are unified into a single release.
2017-08-24 22:49:17 -05:00
Petr Bena
e2818c423e Replace noexcept with macro compatible with VS (#517)
This way it's possible to build using older MSVC (<13) that don't
support this yet. Macro is undefined in each file where it is used so it
should stack well with other libs and sources.
2017-07-25 07:11:10 -05:00
Peter-Levine
efbfa1c7c7 Fix segfault in gmock when running tests (#514)
Taken from https://github.com/google/googletest/issues/705#issuecomment-235067917
2017-07-24 09:14:23 -05:00
Dan Ibanez
11607eb5bf fix some warnings in public headers (#486)
* fix two compile warnings in public headers

both warnings have to do with variable
name shadowing
2017-04-03 13:32:35 -05:00
devnoname120
0fdb1b910c Add Stackoverflow yaml-cpp tag URL to the README (#474) 2017-03-07 14:17:51 -06:00
Andrew
c5457e1c6a Make YAML::detail::iterator_base comparison operators const (#472) 2017-03-02 08:06:17 -08:00
Liosan
bedb28fdb4 Add missing YAML_CPP_API to exceptions.h, fixing MSVC compilation with BUILD_SHARED_LIBS (#462) 2017-02-02 08:32:27 +11:00
Jens Breitbart
86c69bb73c Fixed compiler warning -Wdeprecated with clang. (#452)
* Fixed compiler warning -Wdeprecated with clang.

Starting with C++11 implicit copy-constructors are deprecated when the class
has a user defined destructor.

* Fixes -Wdocumentation warning.

yaml-cpp/parser.h:50:65: warning: parameter 'eventHandler}.' not found in the function
      declaration [-Wdocumentation]
   * Handles the next document by calling events on the {@param eventHandler}.
                                                                ^~~~~~~~~~~~~~
yaml-cpp/parser.h:50:65: note: did you mean 'eventHandler'?
   * Handles the next document by calling events on the {@param eventHandler}.
                                                                ^~~~~~~~~~~~~~
                                                                eventHandler
2017-01-04 23:54:34 -06:00
butataatawa
f82861001a Fix sequence sometimes not turning into a map (#450)
Previously, just referencing the next element in the sequence (and so constructing it, as an undefined element) would allow you to skip defining an element without turning the sequence into a map. E.g:

node[0] = "foo"; // sequence of size 1
node[1]; // sequence of size 1, with an undefined element at 1
node[2] = "bar"; // FIX: should be map of size 2 (since there's no element at index 1)
2017-01-02 15:44:22 -06:00
Raul Tambre
3757b2023b Fix compiler warnings in MSVC, #448 (#453) 2016-12-13 16:37:29 -05:00
butataatawa
147d909fe6 Fix inconsistent Node::size when removing a key with unassigned node (#327) (#449) 2016-12-06 08:40:00 -06:00
Jens Breitbart
e3492bb3fa Fix warnings generated by #438 (comparing unsigned value with <0). 2016-12-03 17:55:50 -06:00
Raul Tambre
8ff7d76e19 Fix compiler warnings about truncations. 2016-12-03 10:09:22 -06:00
Jens Breitbart
2b58c9bc42 Add Intel Compiler support to CMake config. 2016-12-03 09:59:39 -06:00
Jens Breitbart
0f20ddcdcb Fix -Wweak-vtables warnings in exception classes. 2016-12-03 09:58:44 -06:00
butataatawa
d025040049 Fix input strings with quotes giving "!" tagging artifacts. 2016-12-02 08:58:48 -06:00
Ovidiu-Florin BOGDAN
1f4b6d5c85 Remove prefix duplication in yaml-cpp.pc.cmake 2016-12-02 08:51:07 -06:00
Jesse Beder
3d9ad75af7 Add <cstdlib> for std::atoi. 2016-11-21 20:22:26 -06:00
michaelkonecny
380ecb404e Clarify the README description about cmake for Windows
Add hint for 64-bit solution in the cmake's generator argument.
2016-11-10 23:43:10 -06:00
Victor Mataré
994cf97b59 Remove const from as_if::operator()() return (#425)
Returning a const value prevents the use of non-copyable return types
such as unique_ptr.
2016-11-10 23:29:41 -06:00
James E. King, III
96598c5c25 Fix compiler flags for MSVC_STATIC_RT=OFF builds
Fix compiler flags for MSVC_STATIC_RT=OFF builds
2016-11-10 23:28:30 -06:00
Jesse Beder
b5b03bb9ad Run clang-format. 2016-10-12 00:00:39 -05:00
Jesse Beder
086fec5c35 Fix formatting when writing \ as a character. 2016-10-11 23:58:03 -05:00
Jamie Snape
85af926ddc Enable rpath on OS X when the CMake version supports it (#418)
CMake policy CMP0042 changes the default value of the MACOSX_RPATH target property to TRUE, therefore setting the directory portion of the install_name field of a shared library to be @rpath on OS X.
2016-10-01 23:23:07 -05:00
Joseph Langley
519d33fea3 Add YAML_CPP_API decorator to RegEx class and friend operators. (#407) 2016-08-18 08:47:09 -05:00
c0nk
f0b15cd6a0 Change node_map type from map<ptr,ptr> to vector<pair<ptr,ptr>> (#386)
* Change node_map type from map<ptr,ptr> to vector<pair<ptr,ptr>>

Map nodes are now iterated over in document order.

* Change insert_map_pair to always append

Always append in insert_map_pair even if the key is already present.
This breaks the behavior of force_insert which now always inserts KVs
even if the key is already present. The first insert for duplicated keys
now takes precedence for lookups.
2016-07-18 08:54:10 -05:00
Vincent Cogne
f74ae543b4 Fix some clang warnings (#378)
* Remove extra semicolon

* Fix automatic type conversion

* Replace dynamic exception specifications by C++11 noexcept

* Fix deprecated definition of implicit copy constructor for 'Exception'
2016-06-12 22:10:14 -05:00
Vincent Cogne
7c33b3cdab Add convert specialization for std::array. 2016-06-12 21:59:31 -05:00
Jesse Beder
728e26e426 Update doc, formatting for emit.h. 2016-05-12 23:23:05 -05:00
Jesse Beder
3392ab980e Update doc, formatting for parse.h. 2016-05-12 23:20:03 -05:00
Jesse Beder
6c569e58b0 Update docs, formatting for Parser. 2016-05-12 23:13:55 -05:00
Jesse Beder
148da47114 Update documentation for Scanner and AnchorDict, and fix formatting. 2016-05-12 23:05:28 -05:00
Jesse Beder
a45a61742b Remove ptr_stack<T>, in favor of vector<unique_ptr<T>>.
(Not stack<unique_ptr<T>> because it wasn't quite a stack; we needed to get the second-to-last element sometimes.)
2016-05-12 22:44:59 -05:00
Paul Novotny
6e79997bb2 Use CodeDocs.xyz for Doxygen documentation (#375)
Add the .codedocs config file and badge to the README.md file.
2016-05-12 08:55:45 -05:00
SirLoxley
f35f4a19fa Fix for broken build on cygwin using gcc - "error '[fileno, strdup, fdopen]' are not in scope" (#374) 2016-05-11 23:00:34 -05:00
Jesse Beder
7d2873ce9f Fix scalar parsing when a line starts with a comment. 2016-04-02 16:02:26 -05:00
Jesse Beder
091ddfa52d Turn travis email notifications back on.
Apparently the default is

on_success: change
on_failure: always

which seems reasonable.
2016-04-01 20:27:26 -05:00
Jesse Beder
883a1e8540 Revert "Add missing include."
Reason: broken build.

This reverts commit 0d810ad6d5.
2016-04-01 20:18:11 -05:00
Tatsuyuki Ishi
0d810ad6d5 Add missing include. 2016-04-01 20:11:01 -05:00
Jesse Beder
51b59d11ba Update .clang-format to use C++ 11 style. 2016-04-01 20:06:28 -05:00
Jesse Beder
bfb5703ce9 Add test to verify that ~ is loaded as null. 2016-04-01 20:01:01 -05:00
Jesse Beder
cc229e87b3 Turn off travis email notifications. 2016-04-01 18:26:52 -05:00
Jesse Beder
ca34a379c7 Add build status to README 2016-04-01 18:26:12 -05:00
Jesse Beder
2a02cee1c8 Fix typos in travis config.
Hooray for testing travis configs via pushing to master.
2016-04-01 18:17:58 -05:00
Jesse Beder
2176fd994e Add osx to travis config. 2016-04-01 18:11:37 -05:00
Jesse Beder
0535811c18 Fix gcc version typo in travis config. 2016-04-01 17:58:36 -05:00
Jesse Beder
c5f6482325 Use gcc 4.7 with travis.
gcc 4.6 (the default) does have some C++11 support, but its flag is -std=c++0x. Since 4.7 was released in 2012, I think it's reasonable to require it.
2016-04-01 17:53:46 -05:00
Jesse Beder
d155b0d0d2 Add .travis.yml for running test/run-tests. 2016-04-01 17:32:11 -05:00
TripleWhy
52bcefa1f1 Make null handling YAML 1.2 compliant. 2016-04-01 17:14:59 -05:00
Jesse Beder
34bd1a7083 Update CONTRIBUTING.md 2016-03-28 23:47:21 -05:00
Paul Novotny
500db60f89 Include cmake files in install
This adds yaml-cpp-config.cmake, yaml-cpp-config-version.cmake, and
yaml-cpp-targets.cmake to the cmake install. As a result, cmake's
find_package can easily find yaml-cpp for software that depends on
yaml-cpp.

Add code to install cmake files to $CMAKE_INSTALL_PREFIX/CMake on
Windows, which is the de-facto standard.

Closes jbeder/yaml-cpp#336 jbeder/yaml-cpp#127
2016-03-27 20:39:41 -04:00
Jesse Beder
178c8d1f27 Add test for parser exceptions for incomplete JSON. 2016-03-26 16:01:00 -04:00
Scott Wolchok
0a1352525a add some tests for RegEx 2016-03-26 14:52:11 -04:00
Craig M. Brandenburg
f327b565ba Fix line-wrapping in comment in dll.h 2016-03-16 10:41:12 -07:00
Rodrigo Hernandez
57805dfd6a Removed quoted variables to avoid CMP0054 policy warnings on CMake 3.3.0. 2016-01-31 11:44:04 -06:00
Scott Wolchok
005a6a19ee Avoid copying cached RegExes for scalars
This improves performance on the test.yaml attached to #158 by about
25% on my machine as compared to the previous commit (0.25s -> 0.20s),
as measured by `time build/util/parse < test.yaml > /dev/null`.
2016-01-30 18:32:00 -06:00
Scott Wolchok
8c35a8ffab Cache scalar regexes
This improves performance on the test.yaml attached to #158 by about
35% on my machine (0.39s -> 0.25s), as measured by
`time build/util/parse < test.yaml > /dev/null`.
2016-01-30 18:31:55 -06:00
Jesse Beder
9e37409b4b Add features to read binary:
Flag -n N repeats parsing N times.
Flag -c (--cache) caches the input in a string and uses that to parse.
2016-01-30 18:28:27 -06:00
Scott Wolchok
a5b72f7ae6 read benchmark: accept a filename as an argument
On my Macbook Pro, reading from standard input incurs a bunch of locking
overhead, which complicates profiling and (IMO) adds noise to
results. This adds the option to read from a file, which doesn't incur
this overhead.
2016-01-30 17:41:28 -06:00
Jesse Beder
dfbb388409 Remove unnecessary forward declaration. 2016-01-30 17:36:47 -06:00
Jesse Beder
e92321aee5 Update current version. 2016-01-12 08:51:30 -06:00
Matt Blair
24fa1b3380 Replace Boost usage with C++11 features
- Adds 'std=c++11' compiler flags
 - Replaces boost::type_traits with std::type_traits
 - Replaces boost::shared_ptr with std::shared_ptr
 - Replaces std::auto_ptr with std::unique_ptr
 - Replaces raw pointers with std::unique_ptr in ptr_vector, ptr_stack, and SettingChanges
 - Replaces boost::noncopyable with deleted copy and assignment operators
 - Replaces boost::next with std::next
 - Replaces boost::enable_if with std::enable_if
 - Replaces boost::is_convertible with std::is_convertible
 - Replaces ptrdiff_t with std::ptrdiff_t
 - Replaces boost::iterator_facade and boost::iterator_adaptor with std::iterator, borrowing the 'proxy reference' technique from boost
 - Removes Boost dependency from CMakeLists
 - Formats changed files using clang-format
2016-01-10 22:44:15 -05:00
Jiri Hoogland
4376ebacaa Add PIC compile flag for GNU/CLang.
- ensures shared library code is position-independent.
2016-01-10 20:58:47 -06:00
Jesse Beder
b57efe94e7 Bump version to 0.5.3. 2016-01-10 12:11:40 -06:00
Jesse Beder
36fd93a8d5 Fix formatting when writing " as a character. 2016-01-10 12:08:42 -06:00
Jesse Beder
97d56c3f36 Remove 'const' modifier on return of Node::as.
This enables the return value to be moved, rather than copied.
2015-11-22 11:27:55 -06:00
Michael Welsh Duggan
320b02b14a Allow using a Node as the key in force_insert.
Node::force_insert() uses convert<> to convert its key to a node.
Add a specialization for convert<Node>.
2015-11-22 11:21:08 -06:00
Haydn Trigg
03d6e7d672 Removed boost requirement from memory.h (detail)
Removed the boost requirement from memory.h using the shared_memory type defined in ptr.h
2015-07-25 11:45:10 +09:30
Jonathan Hamilton
b426fafff6 Fix some Node::operator[] regressions from 0.5.1
"const Node Node::operator[](const Key& key) const" changed from
returning new empty node if the key was missing in 0.5.1 to returning
a shared 'zombie' node in 0.5.2 to resolve a memory leak.

(Specifically 1025f76df1 was where this
was introduced)

This caused some regressions where this 'zombie' object threw exceptions
in some functions where the 'empty' object would not.

This change fixes the Node::as(fallback) method (to return the
'fallback' instead of throwing an exception) and the
Node::begin()/Node::end() methods to return default-constructed
iterators (so begin() == end() in such cases) instead of another
exception.
2015-06-08 11:47:10 -07:00
Sébastien Rombauts
b0a4de3dd9 Fix missing/TODO links to 0.3.0 and 0.5.2 releases in README 2015-05-26 18:24:22 +02:00
Jesse Beder
b43db54810 Add CONTRIBUTING file.
Initial description of style, tests, and pull request process.
2015-04-08 14:30:07 -05:00
Jesse Beder
5c390e8d6c Merge pull request #303 from bdutro/patch-1-squashed
Fix compiler error by updating node_data::remove to use new equals() method.
2015-04-08 13:59:56 -05:00
bdutro
aa928b925b Update node_data::remove to use new equals() method
- Update the call to equals() in node_data::remove() to match the new implementation
- Add unit test for node::remove() to catch this type of bug in the future
2015-04-08 13:41:59 -05:00
Jesse Beder
908d38ebef Merge pull request #296 from WrinklyNinja/useful-conversion-errors
Add more error messages that include the location in a parsed file.
2015-04-03 09:41:02 -05:00
Oliver Hamlet
ec8aa4fa62 More useful error messages.
Applied the patch given in jbeder/yaml-cpp#200 with the correct code
style.
2015-04-02 20:50:11 +01:00
Jesse Beder
5de38a76b6 Merge pull request #294 from WrinklyNinja/add-gitignore
Add a .gitignore file.
2015-03-31 08:11:28 -05:00
Oliver Hamlet
25f3935b7c Add a .gitignore file.
Ignore the CMake build directory.
2015-03-31 09:33:49 +01:00
Jesse Beder
4d44602a5d Remove mercurial files 2015-03-30 20:33:45 -05:00
Jesse Beder
897cfd5b2e Rename license file and update copyright date. 2015-03-30 20:32:46 -05:00
Jesse Beder
1a6cb7376a Add README. 2015-03-30 20:31:59 -05:00
Jesse Beder
66acd0d54b Added tag release-0.5.2 for changeset 90238df1f398 2015-03-29 21:32:17 -05:00
Jesse Beder
998d7bf31e Bump version to 0.5.2 2015-03-29 21:31:56 -05:00
Jesse Beder
25c466a152 Run clang-format 2015-03-29 21:27:20 -05:00
Jesse Beder
7092a0b099 Fixed linker error on Visual Studio with a shared lib by moving the static methods node_data::equals to an instance method on node. 2015-03-29 21:11:53 -05:00
Jesse Beder
25b2ed0787 Fix operator bool() exception on zombie node 2015-03-29 14:31:22 -05:00
Jesse Beder
67e37d000a Merge from core 2015-02-21 12:34:19 -06:00
Jesse Beder
b1322770c2 Remove the extraneous gtest library from the test's link args, since gmock covers it 2015-02-21 12:33:36 -06:00
Jesse Beder
39e7b651dc Fix test that depended on the order of map outputs 2015-02-21 12:14:53 -06:00
Jesse Beder
0970a108bd Remove stray field 2015-01-24 17:58:58 -06:00
Jesse Beder
f9ff72dee7 Add test for an empty string not being null 2015-01-24 17:30:12 -06:00
Jesse Beder
1025f76df1 Fix memory leak when accessing a const Node with a key that doesn't exist. 2015-01-24 17:22:45 -06:00
Jesse Beder
a5e86cde59 Merge core 2015-01-24 16:30:27 -06:00
Jesse Beder
77c90a08e8 Refactor plain scalar validation in the emitter to precompute the invalid regexes 2015-01-24 16:29:57 -06:00
Jesse Beder
1006bee48a Default-initialize all sub-iterators in node_iterator_base 2015-01-24 16:23:35 -06:00
Jesse Beder
899b6614c1 Merge from core 2015-01-24 16:07:36 -06:00
Jesse Beder
bc86fd4aec Force null to be quoted if written as a string 2015-01-24 16:07:10 -06:00
Jesse Beder
7d932f0a10 Merge from core 2015-01-24 15:59:24 -06:00
Jesse Beder
087e0673f3 Renamed the None enumeration vaules to NoType to avoid a collision with X11's macro 2015-01-24 15:58:14 -06:00
Jesse Beder
c9729b26a4 Remove stray 'auto' that leaked in without C++11 2015-01-24 15:34:39 -06:00
Jesse Beder
f1a889a0b9 Fix initialize ordering warning 2015-01-24 15:32:04 -06:00
Jesse Beder
fcbec237c9 Add conversion for signed char 2015-01-24 15:19:49 -06:00
Jesse Beder
c324bf8a7d Merge core 2015-01-24 14:47:29 -06:00
Jesse Beder
2b2e607118 Fix gcc warning 2015-01-24 14:47:00 -06:00
Jesse Beder
891c7338bf Add test to CMake config 2015-01-24 14:45:40 -06:00
Jesse Beder
391111c055 Merge core 2015-01-24 14:40:55 -06:00
Jesse Beder
570ab9d3fb Fix unused arg warnings for EmitterStyle 2015-01-24 14:39:17 -06:00
Jesse Beder
0c8a539361 Fix warnings on visual studio, including changing unsigned to std::size_t 2015-01-24 14:38:22 -06:00
Jesse Beder
9eae039c91 Merge 2015-01-24 13:24:08 -06:00
Jesse Beder
0c280724e9 Add flow/block style setting on Nodes 2015-01-24 13:11:43 -06:00
Jesse Beder
9880b608b9 Merge from core 2015-01-24 12:26:16 -06:00
Jesse Beder
ad712c4f2d Add EmitterStyle, which will allow sequence or map style (i.e., flow or block) to be preserved between parsing and emitting 2015-01-24 12:19:20 -06:00
Jesse Beder
a397ad2925 Add yaml-cpp-config.cmake and yaml-cpp-config-version.cmake files for importing yaml-cpp into external projects (through find_package). 2015-01-24 11:21:26 -06:00
Jesse Beder
c7752ca336 Fix build warning from gcc about std::copy 2015-01-24 11:14:53 -06:00
Jesse Beder
2c340f0546 Fixed memory corruption when using a node as a key 2014-08-16 10:52:51 -05:00
Jesse Beder
1aa25e7679 Wrap the #pragma warning for msvc in an ifdef 2014-03-25 22:08:34 -05:00
Jesse Beder
541fef1545 Merge from core 2014-03-25 22:07:21 -05:00
Jesse Beder
a499d2edad Add missing include to scanscalar.cpp 2014-03-25 22:04:53 -05:00
Jesse Beder
47af59f09c Add dll tag to Binary 2014-03-25 22:03:27 -05:00
Jesse Beder
66e5c07b4f Extend format build target to all build tools 2014-03-25 22:01:35 -05:00
Jesse Beder
13130ec20d clang-format 2014-03-25 00:11:17 -05:00
Jesse Beder
dea3428ce0 Merge from core 2014-03-25 00:07:38 -05:00
Jesse Beder
edf8ebe246 Remove stray log message in cmake 2014-03-25 00:04:04 -05:00
Jesse Beder
e0b293e757 Add test and util sources to make format 2014-03-25 00:02:16 -05:00
Jesse Beder
a4a79835c9 Suppress gtest warnings on xcode 2014-03-24 23:47:46 -05:00
Jesse Beder
dc8d91ce45 Add make format target to run clang-format 2014-03-24 23:46:03 -05:00
Jesse Beder
d59586630e Fix clang compiler settings, and properly set up warnings so they don't interfere with gtest and gmock 2014-03-24 23:34:26 -05:00
Jesse Beder
066359802b Merge from core, and update several missing DLL exports. This does not resolve them all (in particular, node_data::equals seems to be still missing, even though it is inlined in a header, which seems strange). 2014-03-24 00:31:43 -05:00
Jesse Beder
fe8ca77a1b Add missing DLL export, and set up gtest/gmock to properly import their symbols. 2014-03-23 23:56:17 -05:00
Jesse Beder
833f2996bc Fix MSVC static/shared library mismatch with gtest. 2014-03-23 23:26:02 -05:00
Jesse Beder
7a68eaafd9 Disable warning:
warning C4800: forcing value to bool 'true' or 'false' (performance warning)

for the node test, since it really doesn't make any sense in this context. (It's exactly what we intended with the "unspecified bool type".)
2014-03-23 22:42:06 -05:00
Jesse Beder
98a181c7a7 Merge from core 2014-03-23 22:25:53 -05:00
Jesse Beder
fcfd6635b0 Removed unicode control sequence from test, since it's not guaranteed that the source code is UTF-8 2014-03-23 22:25:25 -05:00
Jesse Beder
bf6482c07e Merge from core 2014-03-23 22:08:31 -05:00
Jesse Beder
a2a096f2f3 Add clang formatting file 2014-03-23 22:07:59 -05:00
Jesse Beder
3bd412ccc3 Merge from core 2014-03-23 20:25:13 -05:00
Jesse Beder
114db22335 Fix UTF16 parsing for multi-byte characters 2014-03-23 20:24:36 -05:00
Jesse Beder
253c80d09e Merge from core 2014-03-23 20:17:34 -05:00
Jesse Beder
06bf012d81 clang-format 2014-03-23 20:08:54 -05:00
Jesse Beder
ad0a3311a7 Convert node tests to gtest 2014-03-23 19:21:13 -05:00
Jesse Beder
33424ecb65 Merge from core 2014-03-23 18:14:51 -05:00
Jesse Beder
d508a7cb0d Import encoding test from old-api 2014-03-23 18:12:23 -05:00
Jesse Beder
2e8841c6fa Merge from core 2014-03-23 16:39:33 -05:00
Jesse Beder
ad2953f660 Converted gen emitter tests to gtest, and removed the old testing framework from core 2014-03-23 16:35:26 -05:00
Jesse Beder
ebf14ec83a Factored out HandlerTest as a base class 2014-03-23 16:26:44 -05:00
Jesse Beder
066b71a755 Factored out mock event handler 2014-03-23 16:17:16 -05:00
Jesse Beder
f946473437 Merge from core 2014-03-23 15:01:08 -05:00
Jesse Beder
90d7562be3 Fixed uninteresting mock 2014-03-23 14:50:58 -05:00
Jesse Beder
1327ce6d73 Convert core parser tests to gtest 2014-03-23 14:47:30 -05:00
Jesse Beder
05834520e5 Merge from core 2014-03-23 14:06:56 -05:00
Jesse Beder
dfa32c7f44 Renamed SpecTest to HandlerSpecTest 2014-03-23 14:06:37 -05:00
Jesse Beder
a4382b1370 Merge from core, plus convert the node spec tests to gtest 2014-03-23 14:02:51 -05:00
Jesse Beder
ace9c49e31 Convert spec tests to gtest with gmock 2014-03-23 12:49:30 -05:00
Jesse Beder
e3f120b99d Add gmock as dependency 2014-03-23 12:04:03 -05:00
Jesse Beder
be85bb3212 Merge from core 2014-03-23 11:55:30 -05:00
Jesse Beder
f6a6f46ba4 Move EmitterTests to gtest 2014-03-23 11:49:32 -05:00
Jesse Beder
da118bbb0d Add test for cloning a null node 2014-03-22 23:29:14 -05:00
Jesse Beder
5a24459ea1 Merge ostream_wrapper fix from core 2014-03-22 23:22:14 -05:00
Jesse Beder
80bdfa6dba Add missing include to otream_wrapper 2014-03-22 23:21:36 -05:00
Jesse Beder
599d050eb2 Merge read fix from core 2014-03-22 23:19:07 -05:00
Jesse Beder
314baa6e13 Add missing include to read.cpp 2014-03-22 23:18:27 -05:00
Jesse Beder
4b40441cee Run IWYU 2014-03-22 23:14:48 -05:00
Jesse Beder
8d7eb02c46 Merge IWYU from core 2014-03-22 23:08:09 -05:00
Jesse Beder
5fd25df859 Run IWYU 2014-03-22 22:46:04 -05:00
Jesse Beder
c7567b7b07 Add missing includes to node_data.h 2014-03-22 19:32:53 -05:00
Jesse Beder
d98ab9f342 Merge ostream_wrapper fix from core 2014-03-22 19:27:54 -05:00
Jesse Beder
0fbeac8f4f Add more ostream_wrapper tests 2014-03-22 19:22:23 -05:00
Jesse Beder
396a97050d Fix SEGV in ostream_wrapper 2014-03-22 19:15:49 -05:00
Jesse Beder
9583d1ab07 Merge gtest from core 2014-03-22 19:09:22 -05:00
Jesse Beder
db82302ed0 Add gtest, as separate set of tests (that just follow the ad-hoc tests that already exist) 2014-03-22 19:06:46 -05:00
Jesse Beder
32125697f2 Rename regex.h and regex.cpp to regex_yaml, so they don't interfere with the posix variant 2014-03-22 19:03:49 -05:00
Jesse Beder
d63ec48c8a Run clang-format 2014-03-22 13:05:03 -05:00
Jesse Beder
3355bbb399 Merge clang-format from core 2014-03-22 13:03:18 -05:00
Jesse Beder
9b4db068bb Run clang-format 2014-03-22 12:49:16 -05:00
Jesse Beder
5b88931143 Fixed bug while reading a single space char 2013-11-10 14:50:35 -06:00
Jesse Beder
25881c4f96 Add ifdef to check if BOOST_FOREACH is defined, and disable tests that use it if it is not available 2013-10-13 11:14:34 -05:00
Jesse Beder
0305ad13e4 Fixed crash when emitting empty node 2013-07-10 08:29:11 -05:00
Jesse Beder
dd0f2577ae Merged make build fix from core 2013-06-18 08:20:51 -05:00
Jesse Beder
e40ed4f94e Restrict make-specific targets to only be added with make 2013-06-18 08:12:23 -05:00
Jesse Beder
4f858a47d6 Added tag release-0.5.1 for changeset 98e9aefe6778 2013-04-13 18:45:50 -05:00
Jesse Beder
fa6a71e37f Bumped version to 0.5.1 2013-04-13 18:37:33 -05:00
Jesse Beder
e5aa599b27 Merge null string bug fix from core, plus bug fix regarding use-after-delete for a token that seems to have been ignored. 2013-04-13 18:25:37 -05:00
Jesse Beder
2375f2c66b Fix bug where the string "null" (without quotes) is deserialized as a string, instead of null. 2013-04-13 18:21:06 -05:00
Jesse Beder
895af26226 Fix floating point precision on input. 2013-04-13 13:10:36 -05:00
Jesse Beder
ae42def6cf Merge to fix default precision for floats. 2013-04-13 00:09:40 -05:00
Jesse Beder
e0ae477b8f Switch default precision to one more than the number of digits allows.
See, e.g., http://stackoverflow.com/questions/4738768/printing-double-without-losing-precision.
2013-04-13 00:00:58 -05:00
Jesse Beder
434c6a5697 Add better exception reporting when incorrectly dereferencing an iterator. 2013-04-12 23:41:02 -05:00
Jesse Beder
097ac171c6 Add std::pair conversion specialization. 2013-04-02 21:04:17 -05:00
Jesse Beder
0482463569 Rename clear() to reset(), and it now takes an optional node parameter. 2013-04-02 20:39:54 -05:00
Jesse Beder
5dbcf7eeb1 Fix conversion for C-strings (both literals and normal C-strings) so it compiles on Visual Studio. 2013-04-01 22:25:53 -05:00
Jesse Beder
f5418306d6 Explicity disallow get_idx for boolean type, to avoid ambiguity with a map. 2013-04-01 22:06:09 -05:00
Jesse Beder
04937649b7 Add missing line from previous fix. 2013-04-01 21:52:32 -05:00
Jesse Beder
71f35b1104 Fix warning in Visual Studio:
warning C4146: unary minus operator applied to unsigned type, result still unsigned
2013-04-01 21:43:09 -05:00
Jesse Beder
c335c8dd75 Added tag release-0.5.0 for changeset d042aa2fa32d 2012-12-28 18:59:29 -06:00
Jesse Beder
6276189716 Merged ? fix from core 2012-11-08 19:12:22 -06:00
Jesse Beder
8c517bf0fd Fixed parsing ? when attached to a scalar 2012-11-08 19:11:41 -06:00
Jesse Beder
15b60e2a3b Added failing test for parsing a ? at the start of a value 2012-11-08 19:00:46 -06:00
Jesse Beder
4e1bdd08d3 Removed that failing test - I don't think the parser is correct here 2012-11-08 18:54:53 -06:00
Jesse Beder
490265cf22 Added failing tests for emitter ? at the start of a value 2012-11-08 18:52:54 -06:00
Jesse Beder
bcdda4027f Added Node::clear() function 2012-11-08 18:47:22 -06:00
Jesse Beder
eb02dd8dc3 Fixed typo from null fix 2012-11-08 18:40:44 -06:00
Jesse Beder
5721ac6194 Pulled 'null' renaming fix 2012-11-08 18:39:06 -06:00
Jesse Beder
0c72825303 Renamed all variables named 'null' (for real now, and only that) 2012-11-08 18:38:20 -06:00
Jesse Beder
6539648dac Merge from core + revert 2012-11-08 18:34:09 -06:00
Jesse Beder
b12e4b0781 Merged from core, rfaef276b1f6e 2012-11-08 18:33:12 -06:00
Jesse Beder
16f05e73b9 Reverted last change 2012-11-08 18:24:00 -06:00
Jesse Beder
06e09d1d64 Renamed all variables named 'null' 2012-11-08 18:21:00 -06:00
Jesse Beder
0c772c4c3f Set LoadFile and LoadAllFromFile to throw an exception if we can't load the file 2012-11-08 18:14:26 -06:00
Jesse Beder
a03e861d8c Switched map's convert<> specialization to use the new force_insert 2012-10-31 19:10:45 -05:00
Jesse Beder
09b4706faf Added force_insert for mapping nodes that doesn't check to see if the key exists already (so it could duplicate keys) 2012-10-31 19:08:09 -05:00
Jesse Beder
a645866ffa Simplified Node::operator[] interface by removing the C-string overloads, using a helper to_value 2012-10-31 18:55:07 -05:00
Jesse Beder
979a91692f Added small 'read' program to test reading a single doc (from stdin) 2012-09-15 16:29:07 -07:00
Jesse Beder
1d1d6886cc Fixed typo in the core parser tests 2012-09-15 15:50:44 -07:00
Jeff Wang
d770a7dc97 workaround for gcc 3 2012-07-17 11:55:45 -05:00
Jesse Beder
823311384f Added free Clone() function for Nodes 2012-07-04 15:26:37 -05:00
Jesse Beder
f29ea4b070 Merged end of map/seq flow fix from core 2012-06-09 14:42:00 -05:00
Jesse Beder
68dd9b5d18 Fixed bug where the parser doesn't find the end of a map or seq flow 2012-06-09 14:39:00 -05:00
Jesse Beder
2d815c5d6a Added extra parser tests for the core; in particular, one that asserts instead of throwing 2012-06-09 14:26:44 -05:00
Jesse Beder
c722684f0d Removed unnecessary forward declarations 2012-06-08 10:26:49 -05:00
Jesse Beder
5c097d417a Removed stray GetNextDocument declaration from the parser (it's from the old API, and not the new one) 2012-06-08 10:25:42 -05:00
Jesse Beder
ab36ca930f Updated from core (emitter) 2012-05-25 19:39:15 -05:00
Jesse Beder
d5130a4109 Changed Emitter::size() to return std::size_t instead of unsigned 2012-05-25 19:38:58 -05:00
Jesse Beder
6c690e8294 Updated the ostream emitting overload to user the new ostream-handling emitters 2012-05-25 19:38:20 -05:00
Jesse Beder
a78069a6e2 Merged ostreams for the emitter change from the core 2012-05-25 19:35:24 -05:00
Jesse Beder
bc3f72b565 Switched the stream << for c-strings to take a templated array param (since we never stream user-built c-strings, only string literals). For this, refactored the escape character display 2012-05-25 19:33:34 -05:00
Jesse Beder
772969270d Refactored stream overloads 2012-05-25 18:24:07 -05:00
Jesse Beder
2ffdc5b4d1 Added constructor to the Emitter with a stream, so you can write directly to a stream instead of our temp 2012-05-25 18:22:33 -05:00
Jesse Beder
e6d4a915dc Switched the ostream wrapper to wrap a std::vector<char> instead of our manually managed memory 2012-05-25 18:17:14 -05:00
Jesse Beder
7c85e9d5de Updated ostream wrapper with a write() and update_pos 2012-05-25 17:39:14 -05:00
Jesse Beder
1602f78974 Renamed ostream -> ostream_wrapper 2012-05-25 17:28:35 -05:00
Jesse Beder
4116d89f2c Merged emitter refactor from core 2012-05-23 15:30:03 -05:00
Jesse Beder
2dd1cf4596 Added compiler flag to compile the generated tests, since gcc takes *forever* to compile them 2012-05-23 15:16:34 -05:00
Jesse Beder
f011975769 Fixed handler macros to remove warnings in gcc 2012-05-23 15:12:36 -05:00
Jesse Beder
288c7e51f2 Added seq/map gen emitter tests 2012-05-23 11:20:36 -05:00
Jesse Beder
52813050d2 Fixed map/comment/seq emitting 2012-05-23 11:18:53 -05:00
Jesse Beder
1ab9469f10 Added map/seq gen emitter tests, including some failing ones 2012-05-23 11:16:32 -05:00
Jesse Beder
3ddfeff4f5 Added seq gen emitter tests 2012-05-23 11:11:50 -05:00
Jesse Beder
fdfffb0916 Added gen emitter tests 2012-05-23 11:02:42 -05:00
Jesse Beder
52d01ff154 Fixed top-level comment emitting 2012-05-23 11:02:17 -05:00
Jesse Beder
c197d822c1 Updated gen emitter tests 2012-05-23 11:00:33 -05:00
Jesse Beder
277132a21f Refactored emitter test template code 2012-05-23 10:56:16 -05:00
Jesse Beder
5af3fc04c6 Registered all the generated emitter tests 2012-05-22 22:17:50 -05:00
Jesse Beder
0fb59c18dd Split test struct and handler macros out for the emitter/spec tests 2012-05-22 22:10:47 -05:00
Jesse Beder
115101d25d Updated emitter test script, and moved handler macros to own include file 2012-05-22 21:59:12 -05:00
Jesse Beder
8d529cbcf2 Started emitting test generator 2012-05-22 19:31:23 -05:00
Jesse Beder
7d7075fdf9 Set indentation to be at least 2 2012-05-22 18:01:48 -05:00
Jesse Beder
8aabc0766b Fixed indentation test - all emitter tests now pass 2012-05-22 17:56:07 -05:00
Jesse Beder
abd49d8bca Added null 2012-05-22 17:55:17 -05:00
Jesse Beder
8b3778a639 Fixed warnings 2012-05-22 17:50:40 -05:00
Jesse Beder
0abbf650b5 Fixed char output 2012-05-22 17:50:10 -05:00
Jesse Beder
c664d50d5c Fixed double quote escapes (e.g., \n is now that instead of \x0a) 2012-05-22 17:45:31 -05:00
Jesse Beder
ad275901b2 Switched single quoted test to positive test (since we just convert to double quoted) 2012-05-22 16:59:39 -05:00
Jesse Beder
a6fe313d32 Removed key/value error checks (since we don't require asking them) 2012-05-22 16:57:30 -05:00
Jesse Beder
4123583159 Fixed end seq/map error msg 2012-05-22 16:56:10 -05:00
Jesse Beder
2c2b788391 Fixed doc start/end 2012-05-22 16:53:40 -05:00
Jesse Beder
bc884061e2 Fixed some newline/comma tests 2012-05-22 16:49:09 -05:00
Jesse Beder
611d243b84 Fixed global setting indentation 2012-05-22 16:47:08 -05:00
Jesse Beder
b2f9a61c46 Fixed emitter tests with newlines 2012-05-22 16:44:49 -05:00
Jesse Beder
f4278fe39f Added long key flow map 2012-05-22 16:41:03 -05:00
Jesse Beder
676e0b94ac Fixed flow seq/map indentation 2012-05-22 16:39:03 -05:00
Jesse Beder
0e3e6791ff Added flow map, simple key/value 2012-05-22 16:36:07 -05:00
Jesse Beder
b8a87c43bc Added flow seq 2012-05-22 15:42:45 -05:00
Jesse Beder
2670ce8aaf Fixed bool formatting 2012-05-22 15:08:21 -05:00
Jesse Beder
faa2e50605 Forced literal scalars to use long keys 2012-05-22 15:07:11 -05:00
Jesse Beder
cdfbac1fd7 Fixed some tests with the new compact long keys 2012-05-22 15:02:36 -05:00
Jesse Beder
944ebb7d1e Fixed settings reverting properly 2012-05-22 15:00:10 -05:00
Jesse Beder
bf07af52ff Added long key 2012-05-22 14:26:34 -05:00
Jesse Beder
41e4cd3308 Split block map simple/long key for both key/value 2012-05-22 14:20:50 -05:00
Jesse Beder
952fe51c73 Added writing float/double 2012-05-22 13:59:31 -05:00
Jesse Beder
c95bcae49f Added writing integral types 2012-05-22 13:57:44 -05:00
Jesse Beder
cc559956a0 Added bool, char, binary 2012-05-22 13:53:03 -05:00
Jesse Beder
879f96d2f6 Tweak sandbox 2012-05-22 12:59:58 -05:00
Jesse Beder
5e0886db87 Fixed block map prepare value (where the colon goes) 2012-05-22 12:59:07 -05:00
Jesse Beder
a626424baa Split the block map prepare into key/value 2012-05-22 12:56:40 -05:00
Jesse Beder
80823583a0 Tweaked spacing for comments 2012-05-22 12:54:54 -05:00
Jesse Beder
eef692d7b2 Fixed when we emit the doc start (only if there already is a document in the stream, and we're about to emit a new node) 2012-05-22 12:37:00 -05:00
Jesse Beder
0814813302 Added comments, not entirely correct 2012-05-22 12:29:36 -05:00
Jesse Beder
0f3f1e26a7 Fixed map/value 2012-05-21 23:47:57 -05:00
Jesse Beder
f72e325c40 Renamed begin/end scalar/group to started/ended scalar/group 2012-05-21 23:39:45 -05:00
Jesse Beder
07e88a78cb Added alias 2012-05-21 23:37:49 -05:00
Jesse Beder
c5e4bdee94 Fixed newline 2012-05-21 23:34:42 -05:00
Jesse Beder
d3801b7482 Added newlines, fixed map/map 2012-05-21 23:29:59 -05:00
Jesse Beder
b0dd0f862a Fixed anchor/tag in seq > map 2012-05-21 23:23:53 -05:00
Jesse Beder
3cae26a75e Added tags and anchors 2012-05-21 23:19:29 -05:00
Jesse Beder
91eac5d93d Implemented block seq and block map indentation/newlines 2012-05-21 22:14:26 -05:00
Jesse Beder
35d827f187 Structured emitter node handling better 2012-05-21 21:57:25 -05:00
Jesse Beder
23fb2dc811 Fixed basic block seq indentation 2012-05-21 21:11:03 -05:00
Jesse Beder
b5d8241dfa Added block seq indentation 2012-05-21 21:04:10 -05:00
Jesse Beder
d86cfc1c63 Implemented the Write for scalars (including checking which type of scalar it should be) 2012-05-21 19:07:56 -05:00
Jesse Beder
65d80ebc11 Started prepare node 2012-05-21 17:06:12 -05:00
Jesse Beder
923ccc8fed Implemented begin/end doc 2012-05-21 16:54:45 -05:00
Jesse Beder
5a2183f55b Removed old emitter state machine 2012-05-21 16:31:07 -05:00
Jesse Beder
41c2ddc03e Switched the emitter state enums to scoped enums 2012-05-21 15:05:17 -05:00
Jesse Beder
39165338e0 Added sandbox to play with 2012-05-20 01:46:08 -05:00
Jesse Beder
d8bdeb5b51 Added failing test for compact map with newline 2012-05-20 01:31:57 -05:00
Jesse Beder
16fd111a6b Fixed formatting for spec tests 2012-05-20 01:19:27 -05:00
Jesse Beder
f17cfacdbb Updated from core 2012-05-19 22:39:36 -05:00
Jesse Beder
030f48583a Fixed tag for implicit map 2012-05-19 22:38:12 -05:00
Jesse Beder
729ac991c7 Added 8.x tests 2012-05-19 22:24:20 -05:00
Jesse Beder
7d57209033 Added 7.x tests 2012-05-19 21:43:22 -05:00
Jesse Beder
4086c285fa Added 6.x tests 2012-05-19 21:08:58 -05:00
Jesse Beder
4245c36a84 Added 5.x tests 2012-05-19 20:40:42 -05:00
Jesse Beder
84b68c3868 Added all the 2.x tests 2012-05-19 18:43:02 -05:00
Jesse Beder
c2b22d6129 Added framework for spectests with event handling 2012-05-19 17:53:43 -05:00
Jesse Beder
58d4fedfc3 Backed out of removing parse 2012-05-19 15:55:13 -05:00
Jesse Beder
55fc800989 Updated from core 2012-05-19 15:54:52 -05:00
Jesse Beder
1f4d8ee3b4 Removed parse 2012-05-19 15:52:43 -05:00
Jesse Beder
e09fbacd35 Updated from core 2012-05-19 15:40:30 -05:00
Jesse Beder
06cb65c6b3 Removed stl node, which was from the old-api but never deleted 2012-05-19 15:37:39 -05:00
Jesse Beder
6c8b369312 Updated CMakeLists from new-api 2012-05-19 15:36:22 -05:00
Jesse Beder
be92547264 Added old parse utility 2012-05-19 15:34:49 -05:00
Jesse Beder
c22512649e Copied all files from new-api branch of old repo 2012-05-19 15:34:02 -05:00
Jesse Beder
c8a539f4f4 Removed old api exceptions 2012-05-19 01:32:10 -05:00
Jesse Beder
683c60f490 Removed traces of old-api Node 2012-05-19 01:19:03 -05:00
Jesse Beder
a183293ff0 Removed old-api tests, added (empty) core spec tests 2012-05-19 01:16:54 -05:00
Jesse Beder
0d32d19ed8 First pass at spearating out a 'core' library from the old api (default) branch 2012-05-19 01:04:43 -05:00
Jesse Beder
fca7b7e190 Fixed reading bad memory error 2012-05-14 23:09:25 -05:00
Jesse Beder
4ca9269e24 Patched signed -> unsigned warning (issue 98) 2012-02-14 10:11:44 -06:00
Jesse Beder
d6a0fc6f01 Fixed warning about binary's shadowing members functions 2012-01-25 17:40:16 -06:00
Jesse Beder
5d6e09d699 Added tag release-0.3.0 for changeset 6d37925fb440 2012-01-21 02:52:18 -06:00
Jesse Beder
572e940c83 Bumped version to 0.3.0 2012-01-21 02:51:56 -06:00
Jesse Beder
01eb370300 Added operator >> overload for Binary 2012-01-21 02:01:37 -06:00
Jesse Beder
d760d037ca 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
Jesse Beder
6105d4cfeb 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
Jesse Beder
e145488547 Added back yaml.h (since it used to be generated) 2012-01-21 00:08:35 -06:00
Jesse Beder
b688c93050 Put all the old-api stuff back in the main folder, for simplicity 2012-01-20 23:55:39 -06:00
Jesse Beder
1723523c43 Removed the new API from the default branch 2012-01-20 23:50:39 -06:00
Jesse Beder
d772361f15 Fixed hex and oct emitting (it now adds the 0x or 0 prefix) 2012-01-13 00:00:11 -06:00
Jesse Beder
a441e1a14c Added test for new API octal/hex conversion 2012-01-12 23:55:15 -06:00
Jesse Beder
fb0802097c Fixed double -> int conversion (now throws) for old API 2012-01-12 23:52:51 -06:00
Jesse Beder
643ea61a98 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
Jesse Beder
d1e4c2640c Added default parameters for the as<> function (new API) 2012-01-12 01:03:31 -06:00
Jesse Beder
ddc578dbd7 Added LoadFile and LoadAllFromFile (new API) 2012-01-11 21:31:01 -06:00
Jesse Beder
8906ae9a0d Fixed bug in parsing escaped newline (it was being clipped like a regular newline) 2012-01-11 17:55:27 -06:00
Jesse Beder
4e350e5808 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
Jesse Beder
7ace0e93d2 Fixed signed/unsigned mismatch with the new precision code 2012-01-11 16:50:06 -06:00
Jesse Beder
0e61ddb6d9 Added parsing emitter tests with the new API, two fail 2012-01-11 16:41:13 -06:00
Jesse Beder
97fa02a484 Disallowed a plain scalar with just a dash 2012-01-11 16:39:24 -06:00
Jesse Beder
5024caa69c Added float/double precision setters 2012-01-11 14:34:04 -06:00
Jesse Beder
21ed2b5817 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
Jesse Beder
92a35581d7 Added boost find/includes to the new API CMake instructions 2012-01-11 13:19:31 -06:00
Jesse Beder
5b32d89222 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
Jesse Beder
812a2dc684 Fixed assignment with an empty node (new API) - a segfault that only showed up in debuggable 2011-12-20 22:19:54 -06:00
Jesse Beder
add460947b Added overload for emitting unsigned char 2011-11-14 17:00:28 -06:00
Jesse Beder
3099d51ba4 Added single character emitting 2011-11-14 16:23:14 -06:00
Jesse Beder
6f4608ce05 Added missing includes (iostream) for the tests 2011-11-13 16:12:39 -06:00
Jesse Beder
5abfbf5aac Added (unspecified-type) bool conversions for Node (new API) 2011-11-13 16:05:42 -06:00
Jesse Beder
d78d16532a 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
Jesse Beder
62634f53ec Fixed emitter bug with colon at the end of a scalar in a flow collection 2011-10-31 19:16:17 -05:00
Jesse Beder
860365b263 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
Jesse Beder
e8e5d4bc40 Fixed typo in computing private headers (no effect on the build, just for the project files) 2011-10-20 21:50:47 -05:00
Jesse Beder
b077e8390e Added parser test for single char input (that fails) 2011-10-20 13:53:27 -05:00
Jesse Beder
c953ce0b07 Fixed broken includes when using the old api 2011-10-18 15:13:10 -05:00
Jesse Beder
f87dced5c9 Fixed installation (we now install the whole include header tree) 2011-10-18 14:55:31 -05:00
Jesse Beder
62361e6f27 Added a .hgignore file that ignores the generated yaml.h 2011-10-18 14:48:07 -05:00
Jesse Beder
70e1eb3f9c Fixed the #ifdefs for the api stuff 2011-10-18 14:47:35 -05:00
Jesse Beder
77cc54585f Couldn't get the copy command to work for yaml.h, so switched to configure_file 2011-10-18 14:43:48 -05:00
Jesse Beder
e69f51ee16 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
Jesse Beder
ee795d7e3e Merged with the main branch, which just updated version count to 0.2.7 2011-09-18 00:26:18 -05:00
Jesse Beder
f6d6c90aa9 Updated old api spectests with common spec examples 2011-09-17 23:57:40 -05:00
Jesse Beder
d9c7bcf32f 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
Jesse Beder
f3b230693a Moved conversion.cpp to the old api, where it belongs 2011-09-14 01:49:06 -05:00
Jesse Beder
f64f619c29 Added bool conversions 2011-09-14 01:48:36 -05:00
Jesse Beder
8e5fc0e304 Added tag release-0.2.7 for changeset d0bed6918076 2011-09-14 01:23:25 -05:00
Jesse Beder
976e8b184c Bumped version to 0.2.7 2011-09-14 01:23:15 -05:00
Jesse Beder
e5d0366797 Added Dump() 2011-09-13 14:49:00 -05:00
Jesse Beder
c3798d9bd4 Added tags to Node emitter output 2011-09-13 14:47:33 -05:00
Jesse Beder
40c47f6312 Finished adding old spec tests 2011-09-13 14:31:00 -05:00
Jesse Beder
e3d5ec189d Switched YAML::Parse to YAML::Load, and added LoadAll 2011-09-13 14:24:47 -05:00
Jesse Beder
5be19ccbfd 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
Jesse Beder
98830a4a15 Added 6.x tests with tags 2011-09-13 14:18:00 -05:00
Jesse Beder
3a88c4b4a1 Added IsNull, IsScalar, IsSequence, IsMap functions, so you don't have to query Type() 2011-09-13 14:10:27 -05:00
Jesse Beder
69af9b420a Copied 2.x tests with tags 2011-09-13 14:07:22 -05:00
Jesse Beder
0987b234c3 Added tags to Node 2011-09-13 14:00:47 -05:00
Jesse Beder
2dfccbb945 Added a convert<> specialization for YAML::_Null (so you can say node[YAML::Null]) 2011-09-13 02:03:56 -05:00
Jesse Beder
a9be4849d8 Copied over the 8.x tests that don't have tags 2011-09-13 01:56:44 -05:00
Jesse Beder
b1100d7c54 Copied over the 7.x tests that don't have tags 2011-09-13 01:46:42 -05:00
Jesse Beder
64e381f2c1 Copied over the 6.x tests that don't have tags 2011-09-13 01:36:27 -05:00
Jesse Beder
f6b728d56c Copied over the 5.x tests 2011-09-13 01:28:32 -05:00
Jesse Beder
edd6650536 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
Jesse Beder
a04dfdeb07 Factored out spec examples, and sketched skeleton for spec tests for new API 2011-09-12 22:55:37 -05:00
Jesse Beder
1721750d9e Added temp variable tests 2011-09-12 22:09:16 -05:00
Jesse Beder
a8f82af604 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
Jesse Beder
0c321a6dc6 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
Jesse Beder
08b3ddfd3e 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
Jesse Beder
fddc991b60 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
Jesse Beder
3337df7ca2 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
Jesse Beder
41533a8c49 Added failing self-reference tests 2011-09-12 12:48:51 -05:00
Jesse Beder
a6e1d4cf74 Added two alias tests 2011-09-12 12:42:23 -05:00
Jesse Beder
5397a93702 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
Jesse Beder
b9583dde76 Added reading/writing std::list 2011-09-11 23:18:19 -05:00
Jesse Beder
f22f38f7f2 Added reading/writing std::vector 2011-09-11 23:14:52 -05:00
Jesse Beder
9e62bf8349 Removed the (unimplemented) operator <, and added operator == (in place of is()) for nodes 2011-09-11 22:56:04 -05:00
Jesse Beder
f9d826c22a 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
Jesse Beder
4770ec798c Implemented operator[] specialization, but only const (should the sequence be mutable?) 2011-09-11 21:51:04 -05:00
Jesse Beder
4568dd0b19 Started specialization for operator[] for integers 2011-09-11 21:32:47 -05:00
Jesse Beder
a308b73e8a Set the map iterator to filter over undefined items 2011-09-11 19:44:27 -05:00
Jesse Beder
c2a8a2c1f7 Added failing map iterator count test 2011-09-11 17:36:08 -05:00
Jesse Beder
a03af5dd73 Implemented the map size computation 2011-09-11 17:16:26 -05:00
Jesse Beder
b50264e74d Switched the implementation of maps from list<pair> to map (but just pointer comparison) 2011-09-11 16:56:38 -05:00
Jesse Beder
ecdd9cc66d Added computing and caching the sequence size 2011-09-11 16:21:36 -05:00
Jesse Beder
3a90454d50 Added some small map tests 2011-09-11 16:02:31 -05:00
Jesse Beder
2d81e46655 Added dependency management (to cause nodes to become defined if their children do) 2011-09-11 15:59:53 -05:00
Jesse Beder
b4963ab0fa 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
Jesse Beder
432268917b Started Node tests (for the new API Node) 2011-09-10 23:22:30 -05:00
Jesse Beder
2d06df474b 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
Jesse Beder
03fc837236 Set up util/parse for the new API 2011-09-10 23:03:02 -05:00
Jesse Beder
80cf3c98db Fixed minor things that used the old API, compiles/links/runs\! 2011-09-10 22:59:27 -05:00
Jesse Beder
f7b2247217 Added stubs for spec and parser tests with the new API 2011-09-10 18:05:35 -05:00
Jesse Beder
36c63980b9 Moved old api tests to subfolder 2011-09-10 18:02:07 -05:00
Jesse Beder
0d1b5224c8 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
Jesse Beder
ac81d7c883 Start of moving Value -> Node and Node -> old API Node (with a #define toggle) 2011-09-10 17:18:15 -05:00
Jesse Beder
78b7a1b8a9 Added helper emitter functions, but we have a problem: YAML::Value is already a manipulator 2011-09-10 16:50:44 -05:00
Jesse Beder
12364895cb Implemented value events emitter 2011-09-10 16:23:18 -05:00
Jesse Beder
5012063143 Fixed node iterator 2011-09-10 14:36:10 -05:00
Jesse Beder
c3b0ba9d61 New iterators work\! 2011-09-10 14:16:50 -05:00
Jesse Beder
4fdbb748ec 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
Jesse Beder
b1730ea3da Finished the main iterator stuff, now have to hook it to the nodes/values 2011-09-10 14:06:49 -05:00
Jesse Beder
3865d37bc7 Halfway towards factoring out a node_iterator, and then building iterator on top of it 2011-09-10 13:20:22 -05:00
Jesse Beder
f5a9d4c8e3 Started emitting events for Values 2011-09-10 12:42:42 -05:00
Jesse Beder
09beb5c47a Implemented sugar Parse() functions 2011-09-09 23:40:19 -05:00
Jesse Beder
6e03bebeb0 Implemented (untested) the value builder 2011-09-09 23:28:21 -05:00
Jesse Beder
a7bdf08c7e Map iterator works\! 2011-09-09 19:25:11 -05:00
Jesse Beder
cf198080d0 Sequence iterator works\! 2011-09-09 19:22:17 -05:00
Jesse Beder
190a556756 Switched iterators to typedef's, with a bit of finagling so we can forward-declare them 2011-09-09 19:07:37 -05:00
Jesse Beder
9aa3eb56f2 Base iterator stuff compiles :) 2011-09-09 18:46:37 -05:00
Jesse Beder
ff1a8fc59a Started writing new iterators 2011-09-09 16:17:59 -05:00
Jesse Beder
7bbf712c36 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
Jesse Beder
9b985c5ce2 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
Jesse Beder
d3bbd08273 Added append() 2011-09-09 02:51:35 -05:00
Jesse Beder
4f8680b540 Switched operator[] access to node reference equality, not node equality 2011-09-09 02:39:36 -05:00
Jesse Beder
ec95e61c04 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
Jesse Beder
6ffc9ac788 Added half of the std::map conversion (we don't have reading from Values yet) 2011-09-08 02:10:04 -05:00
Jesse Beder
0e197b8723 Added back the streamable conversions 2011-09-08 02:05:03 -05:00
Jesse Beder
3d84f57008 Switched convert to a templated struct that can be specialized (so we can partially specialize it) 2011-09-08 02:02:15 -05:00
Jesse Beder
a7ebb3615a Added streamable conversions 2011-09-08 00:48:40 -05:00
Jesse Beder
a95baeafd6 Implemented conversion for std::string, including a bypass-accessor to the scalar value 2011-09-07 15:49:01 -05:00
Jesse Beder
1ab16bac62 Set the 'memory' to only store node_refs, not nodes 2011-09-07 14:56:04 -05:00
Jesse Beder
4aa61944fe Implemented is() 2011-09-07 14:46:25 -05:00
Jesse Beder
e225509210 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
Jesse Beder
d1eca90216 Implemented map get(), and it would work (I think) if we implemented convert() for strings 2011-09-07 03:36:50 -05:00
Jesse Beder
020cd97915 Set up map searching by templated key 2011-09-07 03:21:24 -05:00
Jesse Beder
f0174ca08b Reorganized so that we don't have cyclic include problems 2011-09-07 02:59:58 -05:00
Jesse Beder
fed95c5da4 Implemented map access by already-existing node 2011-09-07 02:39:59 -05:00
Jesse Beder
a530630f1c Started implementing node_data 2011-09-07 00:45:28 -05:00
Jesse Beder
00e4a56d15 Compiles/links assignment to string 2011-09-07 00:20:23 -05:00
Jesse Beder
1e6877043e Value stuff compiles/links with lots of placeholder functions 2011-09-07 00:12:24 -05:00
Jesse Beder
248b18a2d0 Sketched more of the implementation 2011-09-06 23:11:38 -05:00
Jesse Beder
7e79edc058 Moved the value header to its own subfolder 2011-09-06 16:06:46 -05:00
Jesse Beder
8b97dfe77e Sketched out interface for YAML::Value 2011-09-06 01:43:15 -05:00
Jesse Beder
3eeb270ef5 Merged from trunk 2011-09-06 01:10:27 -05:00
Jesse Beder
c1d75dd4f7 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
Jesse Beder
dd1eb715c4 Switched YAML::Binary interface to use unsigned chars, not chars 2011-09-06 00:39:31 -05:00
Jesse Beder
fadca5a89d Added overload for operator [] for char * (non-const version) 2011-09-06 00:32:53 -05:00
Jesse Beder
7e129c9b64 Fixed empty string emitter bug (it now with auto-quote it 2011-09-06 00:24:10 -05:00
Jesse Beder
3e94c0a037 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
Jesse Beder
d7feb2e9b9 Added api sketch 2011-09-04 19:50:08 -05:00
Jesse Beder
8ba5e3fbf6 Added .hgeol for native eols 2011-08-24 02:59:58 -05:00
Jesse Beder
857c7d93a0 update tags 2011-08-24 13:44:56 +00:00
Jesse Beder
b690648308 Removed ATOMIC_TYPE, an old enum that wasn't used any more 2011-08-22 21:37:51 +00:00
Jesse Beder
d904b600a9 Added test for anchor/alias in flow 2011-08-04 21:50:04 +00:00
Jesse Beder
bacb74e8ec Forced a newline after any comments 2011-08-04 21:47:57 +00:00
Jesse Beder
b1ac3289b8 Included <cstddef> for NULL 2011-08-04 18:47:37 +00:00
Jesse Beder
835b86d9f7 Fixed negative infinity parsing 2011-07-10 18:29:44 +00:00
Jesse Beder
94dc63af04 Added parsing .inf and .nan (and friend) 2011-07-10 16:27:40 +00:00
Jesse Beder
50474b6b9f Fixed includedir for the .pc.cmake file 2011-05-29 02:17:49 +00:00
Jesse Beder
4c3926a5c7 Added emitting std::set (and refactored the stl emitters a bit) 2011-05-18 21:07:25 +00:00
Jesse Beder
9fbcfe9ec5 Added include <cstdlib> for using 'NULL' (apparently gcc 4.6 is more strict) 2011-05-03 21:55:49 +00:00
Jesse Beder
d98687afc3 Set version to 0.2.6 2011-03-30 01:33:02 +00:00
Jesse Beder
f42580be41 Switched project label to use 'nicer' suffix (e.g., md instead of /MD) 2011-03-21 23:03:01 +00:00
Jesse Beder
6e0e9554c6 Added eol-style=native prop to missing files 2011-03-17 02:06:10 +00:00
Jesse Beder
dc5bd4afce Fixed mixed line endings 2011-03-17 02:04:34 +00:00
Jesse Beder
c67b41c966 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
Jesse Beder
221d17b0c6 Set eol-style to native for all sources 2011-03-16 01:13:41 +00:00
Jesse Beder
9a72702a61 Added option to disable compilation of contrib code 2011-03-16 01:10:57 +00:00
Jesse Beder
ebdfeb0349 Removed comparison/implicit conversion operators for Node, and renamed Node::Read<T>() to Node::to<T>() 2011-03-15 05:49:56 +00:00
Jesse Beder
6152fb345e Added newline at the end 2011-03-10 00:23:15 +00:00
Jesse Beder
f9e1a882e8 Updated for error in spec test 2011-03-04 04:19:34 +00:00
Jesse Beder
681c862f54 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
Jesse Beder
bb463d8d8b Fixed folding bug (detecting indentation, example 8.2), and clipping/stripping empty strings (example 8.6) 2011-03-04 02:26:59 +00:00
Jesse Beder
943d000ab3 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
Jesse Beder
cb632b3968 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
Jesse Beder
b9d4ccd254 Removed the default --- at the start of all emitter output 2011-03-03 08:57:00 +00:00
Jesse Beder
d6aeb16450 Switched the scanner list of owned indent markers to a ptr_vector 2011-03-03 08:34:30 +00:00
Jesse Beder
a518d87cfc Switched the emitter state's stack of groups to a ptr_stack 2011-03-03 08:11:14 +00:00
Jesse Beder
27617ec2be Added parsing of output to emitter tests 2011-03-03 08:04:30 +00:00
Jesse Beder
1f9cc2d327 Compressed the sequence-of-maps emitting (got rid of the unnecessary newline) - issue 61 2011-03-03 03:37:54 +00:00
Jesse Beder
9128d841f5 Set the precision of emitting float/double to 15 2011-03-03 02:38:35 +00:00
Jesse Beder
ca5992b971 Merged r444:449 from the node refactoring branch to the trunk 2011-03-03 00:19:26 +00:00
Jesse Beder
ced50538fe Tiny formatting change in CMake file 2011-03-02 21:09:38 +00:00
Jesse Beder
1371fc446c Removed the old, unsupported Visual Studio files (just build with CMake) 2011-03-02 21:03:03 +00:00
Jesse Beder
7998db8397 Prettied up the bool formatting code 2011-03-02 20:59:39 +00:00
Jesse Beder
39c396ab01 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
Jesse Beder
1e0c36c5cc 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
Jesse Beder
f34d60ca65 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
Jesse Beder
4caedfda74 Small changes to eliminate compiler warnings for 'nite' in issue 83 2011-03-02 05:29:46 +00:00
Jesse Beder
2faeb76e2d 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
Jesse Beder
75a2fbe564 Fixed 'long long' error in VS 2002, issue 90 2011-03-02 05:15:36 +00:00
Jesse Beder
4d95e4da74 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
Jesse Beder
802cc6bcd6 Merged contrib folders from the graphbuilder-api branch, including the recursive search in CMakeLists.txt 2011-03-02 04:48:04 +00:00
Jesse Beder
04bc13caf8 Merged CMakeLists.txt from issue 87 - now it's cleaner, and supports Windows much better 2011-03-02 04:37:55 +00:00
Jesse Beder
c65a7dfc7c 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
Jesse Beder
d1cb1aa74f Included cstddef to stream.h 2011-02-05 22:28:08 +00:00
Jesse Beder
be1b14f369 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
Jesse Beder
337cb553d0 Fixed emitting colon at end of scalar bug 2010-12-03 21:52:04 +00:00
Jesse Beder
99089bf218 Added long long types to the emitter 2010-11-15 01:46:33 +00:00
Jesse Beder
e293d4af8a Updated Visual Studio project file. 2010-11-09 19:59:25 +00:00
Jesse Beder
a6afaabcb0 Refactored tags so we can emit secondary tags (and named local tags) 2010-10-28 23:06:16 +00:00
Jesse Beder
d508203ed8 Implemented binary emitting without the binary tag 2010-10-28 21:53:54 +00:00
Jesse Beder
f1697dea15 Refactored emitter so that it emits the : for an implicit key right away 2010-10-22 04:19:01 +00:00
Jesse Beder
6b7cb45ac8 Added more tests for the newline, and disallowed newlines after implicit block keys 2010-10-22 03:53:33 +00:00
Jesse Beder
1e4210401f Added YAML::Newline manipulator for the emitter 2010-10-21 22:02:29 +00:00
Jesse Beder
a04e2da1ff Merged the extra tests from other-tags into the trunk (forgot last commit) 2010-10-19 06:51:54 +00:00
Jesse Beder
51c84f1c02 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
Jesse Beder
18a805e46c Updated CMake iPhone settings 2010-10-18 21:35:34 +00:00
Jesse Beder
a19336fd98 Made emitter noncopyable, which should fix any auto_ptr warnings 2010-10-18 07:24:42 +00:00
Jesse Beder
9ad3a1b905 Fixed the rest of the includes to explicitly state yaml-cpp/ 2010-10-18 07:22:53 +00:00
Jesse Beder
21be19d493 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
Jesse Beder
5b8ca9ce01 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
Jesse Beder
a71c03a18b Merged r366:387 from the jbeder-event-api branch 2010-10-18 06:45:03 +00:00
Jesse Beder
0a02403fb0 Fixed missing header 2010-05-01 20:05:15 +00:00
Jesse Beder
9820d13840 Tagged version 0.2.5 2010-03-15 19:25:02 +00:00
Jesse Beder
326899815f Added overloads for parsing stl maps and vectors 2010-03-15 04:25:17 +00:00
Jesse Beder
083a97b171 Set alias nodes to return the tag of their anchor 2010-03-15 04:10:36 +00:00
Jesse Beder
2226987442 Disabled those warnings in the release version of the .svn too. 2010-03-03 05:33:07 +00:00
Jesse Beder
bca7737463 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
Jesse Beder
6f40b09525 Added newline to install and license files 2009-12-21 20:35:27 +00:00
Jesse Beder
3a755de572 Added missing include 2009-12-02 05:59:18 +00:00
Jesse Beder
9718e58120 Added test for duplicate key 2009-12-02 01:29:16 +00:00
Jesse Beder
8723b8f358 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
Jesse Beder
03df73a7b0 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
Jesse Beder
3307f0941c 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
Jesse Beder
54b68230ae Small bug from switching static initialized regexes to lazy ones 2009-11-12 05:45:47 +00:00
Jesse Beder
32491166ac Replaced conversion macros with SFINAE 2009-11-10 21:23:52 +00:00
Jesse Beder
6f94f954bb Overloaded more integral types for emitting 2009-11-06 03:24:12 +00:00
Jesse Beder
90fd24d149 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
Jesse Beder
9a21a3ec8d Switched the Exp:: regexes to functions that lazily evaluate their regexes 2009-11-04 22:56:59 +00:00
Jesse Beder
3779e4255d Fixed silly bug in node cloning 2009-10-30 20:29:14 +00:00
Jesse Beder
ec62dc547e Added some block scalar tests (with errors) 2009-10-30 18:16:26 +00:00
Jesse Beder
a9b9e1ccec Updated the Visual Studio solution for the new files/renaming. 2009-10-30 04:52:13 +00:00
Jesse Beder
e04be7890a 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
Jesse Beder
ecb30132e9 Fixed the whitespace tracking when we escape a newline in a double-quoted string 2009-10-29 22:55:50 +00:00
Jesse Beder
52be1ccfb9 Fixed mistake in test 2009-10-29 22:39:53 +00:00
Jesse Beder
3405a6fe01 Refactored the compact map notation, which made it easy to implement explicit keys for compact maps 2009-10-29 22:09:50 +00:00
Jesse Beder
d372729b92 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
Jesse Beder
fadc2ad39f Implemented adjacent key:value pairs when the key is JSON-like 2009-10-29 21:05:48 +00:00
Jesse Beder
a5607f82a3 Added test 2009-10-29 20:45:20 +00:00
Jesse Beder
f4c683ac22 Added flow collection tests 2009-10-29 20:35:07 +00:00
Jesse Beder
8c9c9d90da Added ability to read compact maps in a flow sequence 2009-10-29 19:41:46 +00:00
Jesse Beder
a372bfdc60 Merged r295:305 from the tags branch to the trunk 2009-10-29 15:48:06 +00:00
Jesse Beder
fe57829aca Removed crt stuff (we can do memory leak checking in Linux easier) 2009-10-27 14:55:01 +00:00
Jesse Beder
b5c53d9e3a Removed unused test yaml file 2009-10-27 14:48:01 +00:00
Jesse Beder
f2a2d25ec0 Now actually removed yaml-reader 2009-10-27 14:47:08 +00:00
Jesse Beder
a706ffaf62 Reverted yaml-reader name change 2009-10-27 14:45:14 +00:00
Jesse Beder
8f48e693fe Renamed yaml-reader test (try 2) 2009-10-27 14:39:48 +00:00
Jesse Beder
a0bf12e7a1 Renamed yaml-reader test 2009-10-27 14:38:53 +00:00
Jesse Beder
2314c04d5d Tagged version 0.2.4 2009-10-25 20:27:31 +00:00
Jesse Beder
22410f46f5 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
Jesse Beder
9559a661aa Tagged version 0.2.3 2009-10-22 21:55:44 +00:00
Jesse Beder
beb524489c Small refactoring 2009-10-22 21:51:32 +00:00
Jesse Beder
4ffb93c12b Switch to flow map when emitting an empty block map 2009-10-22 14:21:12 +00:00
Jesse Beder
ae06a40fe6 Switch to flow sequence when emitting an empty sequence 2009-10-22 14:17:12 +00:00
Jesse Beder
315b00065b Fixed bug in plain scalar folding 2009-10-20 14:47:16 +00:00
Jesse Beder
6f02f7556e Added a bunch of tests, simplified the testing code 2009-10-20 14:43:24 +00:00
Jesse Beder
fa0af88dfe Merged r270:HEAD of the emitting-unicode branch 2009-10-19 23:31:11 +00:00
Jesse Beder
bce845bb1f Fixed little bug in parser commit 2009-10-19 22:42:30 +00:00
Jesse Beder
ed570b9f7c Added default constructor to Parser, and cleaned it up a bit 2009-10-19 22:40:46 +00:00
Jesse Beder
59b0e986bf Update CMakeLists.txt to append, not overwrite CMAKE_CXX_FLAGS 2009-10-19 22:32:26 +00:00
Jesse Beder
cffb98d15b Patched for optional building of tests and tools 2009-10-12 05:21:00 +00:00
Jesse Beder
3e1ba0f3b4 Refactored the UTF-8 emitting 2009-10-08 21:05:56 +00:00
Jesse Beder
d0b5bf4b7b Fixed the emitter unicode output 2009-10-07 06:46:05 +00:00
Jesse Beder
7db39e66b8 Updated signature of Parser::GetNextDocument (issue 45) 2009-09-29 18:25:11 +00:00
Jesse Beder
94eb7f1dbd 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
Jesse Beder
5733b77b84 Patched for gcc version <= 3.3 (just fall back to original version of Node::Read) 2009-09-16 04:01:40 +00:00
Jesse Beder
98bebfb628 Tagged version 0.2.2 2009-09-09 01:37:23 +00:00
Jesse Beder
7c4cc9bf5f 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
Jesse Beder
fa885d1813 More tests, found bug in implicit keys in flow sequence 2009-09-08 05:35:39 +00:00
Jesse Beder
da4614eb8b 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
Jesse Beder
4dcd222d1f Tests through 6.29, skipping directives and tags 2009-09-08 04:16:45 +00:00
Jesse Beder
7bdd31b34b (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
Jesse Beder
a4b8521efe Fixed newlines in folded scalars bug 2009-09-07 22:48:32 +00:00
Jesse Beder
7037562998 Simplified testing output 2009-09-07 22:17:02 +00:00
Jesse Beder
f3ff6ffc55 Fixed bugs with tab as non-content whitespace 2009-09-07 17:12:45 +00:00
Jesse Beder
e3ff87ecde Fixed bugs in escape characters (both parsing and emitting) 2009-09-07 16:31:23 +00:00
Jesse Beder
45ac700fff Fixed error in test 2009-09-07 06:56:05 +00:00
Jesse Beder
2aab5acab4 Fixed last newline of folded scalar bug 2009-09-07 06:54:38 +00:00
Jesse Beder
e9d760eea9 Fixed bug in trailing newlines of plain scalars 2009-09-07 06:42:03 +00:00
Jesse Beder
d485d0a834 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
Jesse Beder
973ac4b3bd Added spec tests through example 2.13 2009-09-06 22:17:53 +00:00
Jesse Beder
e91a152e06 Tagged release 0.2.1 for patch with complex keys 2009-09-06 22:02:59 +00:00
493 changed files with 181084 additions and 8804 deletions

47
.clang-format Normal file
View File

@@ -0,0 +1,47 @@
---
# 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
.codedocs Normal file
View File

@@ -0,0 +1,50 @@
# 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/gtest-1.8.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 =

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
build/

28
.travis.yml Normal file
View File

@@ -0,0 +1,28 @@
language: c++
os:
- linux
- osx
compiler:
- clang
- gcc
before_install:
- |
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y \
&& sudo apt-get update -qq \
&& if [ "$CXX" == "g++" ]; then
sudo apt-get install -qq g++-4.7 && export CXX="g++-4.7" CC="gcc-4.7"
fi
fi
before_script:
- mkdir build
- cd build
- cmake ..
script:
- make
- test/run-tests
matrix:
exclude:
- os: linux
compiler: clang

View File

@@ -1,68 +1,365 @@
###
### CMake settings
###
## Due to Mac OSX we need to keep compatibility with CMake 2.6
# see http://www.cmake.org/Wiki/CMake_Policies
cmake_minimum_required(VERSION 2.6)
# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012
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()
# see https://cmake.org/cmake/help/latest/policy/CMP0042.html
if(POLICY CMP0042)
# Enable MACOSX_RPATH by default.
cmake_policy(SET CMP0042 NEW)
endif()
project (YAML_CPP)
include(CheckCXXCompilerFlag)
set(LIB_TYPE SHARED)
if(IPHONE)
set(CMAKE_OSX_SYSROOT iphoneos2.2.1)
set(LIB_TYPE)
endif(IPHONE)
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra")
endif(CMAKE_COMPILER_IS_GNUCC)
###
### Project settings
###
project(YAML_CPP)
set(YAML_CPP_VERSION_MAJOR "0")
set(YAML_CPP_VERSION_MINOR "2")
set(YAML_CPP_VERSION_MINOR "6")
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_TESTS "Enable testing" ON)
option(YAML_CPP_BUILD_TOOLS "Enable 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
###
# From http://www.cmake.org/pipermail/cmake/2010-March/035992.html:
# function to collect all the sources from sub-directories
# into a single list
function(add_sources)
get_property(is_defined GLOBAL PROPERTY SRCS_LIST DEFINED)
if(NOT is_defined)
define_property(GLOBAL PROPERTY SRCS_LIST
BRIEF_DOCS "List of source files"
FULL_DOCS "List of all source files in the entire project")
endif()
# make absolute paths
set(SRCS)
foreach(s IN LISTS ARGN)
if(NOT IS_ABSOLUTE "${s}")
get_filename_component(s "${s}" ABSOLUTE)
endif()
list(APPEND SRCS "${s}")
endforeach()
# append to global list
set_property(GLOBAL APPEND PROPERTY SRCS_LIST "${SRCS}")
endfunction(add_sources)
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()
add_definitions(-DYAML_CPP_NO_CONTRIB)
endif()
set(library_sources
${sources}
${public_headers}
${private_headers}
${contrib_sources}
${contrib_public_headers}
${contrib_private_headers}
)
add_sources(${library_sources})
if(VERBOSE)
message(STATUS "sources: ${sources}")
message(STATUS "public_headers: ${public_headers}")
message(STATUS "private_headers: ${private_headers}")
message(STATUS "contrib_sources: ${contrib_sources}")
message(STATUS "contrib_public_headers: ${contrib_public_headers}")
message(STATUS "contrib_private_headers: ${contrib_private_headers}")
endif()
include_directories(${YAML_CPP_SOURCE_DIR}/src)
include_directories(${YAML_CPP_SOURCE_DIR}/include)
###
### General compilation settings
###
set(yaml_c_flags ${CMAKE_C_FLAGS})
set(yaml_cxx_flags ${CMAKE_CXX_FLAGS})
if(BUILD_SHARED_LIBS)
set(LABEL_SUFFIX "shared")
else()
set(LABEL_SUFFIX "static")
endif()
if(APPLE)
if(APPLE_UNIVERSAL_BIN)
set(CMAKE_OSX_ARCHITECTURES ppc;i386)
endif()
endif()
if(IPHONE)
set(CMAKE_OSX_SYSROOT "iphoneos4.2")
set(CMAKE_OSX_ARCHITECTURES "armv6;armv7")
endif()
if(WIN32)
set(_library_dir bin) # .dll are in PATH, like executables
else(WIN32)
set(_library_dir lib)
endif(WIN32)
if(BUILD_SHARED_LIBS)
add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "C:/")
endif()
endif()
set(INCLUDE_INSTALL_DIR include/yaml-cpp)
set(LIB_INSTALL_DIR ${_library_dir}${LIB_SUFFIX})
# GCC or Clang or Intel Compiler specialities
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID MATCHES "Intel")
### General stuff
if(WIN32)
set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix
set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs
set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3)
endif()
### Project stuff
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
#
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
#
set(GCC_EXTRA_OPTIONS "")
#
if(BUILD_SHARED_LIBS)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
endif()
#
set(FLAG_TESTED "-Wextra")
check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
if(FLAG_WEXTRA)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
endif()
#
set(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long -std=c++11 ${yaml_cxx_flags}")
### Make specific
if(${CMAKE_BUILD_TOOL} MATCHES make OR ${CMAKE_BUILD_TOOL} MATCHES gmake)
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}}")
set(${var_name} "${${var_name}}" CACHE STRING "" FORCE)
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(yaml_cxx_flags "/W3 /wd4127 /wd4355 ${yaml_cxx_flags}")
endif()
###
### General install settings
###
set(INCLUDE_INSTALL_ROOT_DIR include)
set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
#
set(_INSTALL_DESTINATIONS
RUNTIME DESTINATION bin
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
)
#
file(GLOB public_headers include/*.h)
file(GLOB private_headers src/*.h)
file(GLOB sources src/*.cpp)
include_directories(${YAML_CPP_SOURCE_DIR}/include)
add_library(yaml-cpp
${LIB_TYPE}
${public_headers}
${private_headers}
${sources}
###
### Library
###
add_library(yaml-cpp ${library_sources})
set_target_properties(yaml-cpp PROPERTIES
COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}"
)
set_target_properties(yaml-cpp PROPERTIES
VERSION "${YAML_CPP_VERSION}"
SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}"
PROJECT_LABEL "yaml-cpp ${LABEL_SUFFIX}"
)
install(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS})
if(IPHONE)
set_target_properties(yaml-cpp PROPERTIES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0"
)
endif()
if(MSVC)
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()
install(TARGETS yaml-cpp EXPORT yaml-cpp-targets ${_INSTALL_DESTINATIONS})
install(
FILES ${public_headers}
DIRECTORY ${header_directory}
DESTINATION ${INCLUDE_INSTALL_DIR}
FILES_MATCHING PATTERN "*.h"
)
export(
TARGETS yaml-cpp
FILE "${PROJECT_BINARY_DIR}/yaml-cpp-targets.cmake")
export(PACKAGE yaml-cpp)
set(EXPORT_TARGETS yaml-cpp CACHE INTERNAL "export targets")
set(CONFIG_INCLUDE_DIRS "${YAML_CPP_SOURCE_DIR}/include")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" @ONLY)
if(WIN32 AND NOT CYGWIN)
set(INSTALL_CMAKE_DIR CMake)
else()
set(INSTALL_CMAKE_DIR ${LIB_INSTALL_DIR}/cmake/yaml-cpp)
endif()
file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_ROOT_DIR}")
set(CONFIG_INCLUDE_DIRS "\${YAML_CPP_CMAKE_DIR}/${REL_INCLUDE_DIR}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake" @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config-version.cmake.in
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" @ONLY)
install(FILES
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
install(EXPORT yaml-cpp-targets DESTINATION ${INSTALL_CMAKE_DIR})
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(UNIX)
endif()
add_subdirectory (yaml-reader)
add_subdirectory (util)
###
### Extras
###
if(YAML_CPP_BUILD_TESTS)
add_subdirectory(test)
endif()
if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util)
endif()
### Formatting
get_property(all_sources GLOBAL PROPERTY SRCS_LIST)
add_custom_target(format
COMMAND clang-format --style=file -i ${all_sources}
COMMENT "Running clang-format"
VERBATIM)

26
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,26 @@
# 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 running the target `tests/run_tests`.
If you are adding functionality, add tests accordingly.
# 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.

View File

@@ -1,19 +1,19 @@
Copyright (c) 2008 Jesse Beder.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Copyright (c) 2008-2015 Jesse Beder.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

51
README.md Normal file
View File

@@ -0,0 +1,51 @@
# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
# 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. The basic steps to build are:
1. Download and install [CMake](http://www.cmake.org) (Resources -> Download).
**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path.
2. Navigate into the source directory, and type:
```
mkdir build
cd build
```
3. Run CMake. The basic syntax is:
```
cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
```
* The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
* On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution.
* On OS X, you might use "Xcode" to generate an Xcode project
* On a UNIX-y system, simply omit the option to generate a makefile
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`.
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
4. Build it!
5. To clean up, just remove the `build` directory.
# Recent Release #
[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) has been released! This release requires C++11, and no longer depends on Boost.
[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.
**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases.

View File

@@ -1,43 +0,0 @@
#pragma once
#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "null.h"
#include <string>
#include <sstream>
namespace YAML
{
inline bool Convert(const std::string& input, std::string& output) {
output = input;
return true;
}
bool Convert(const std::string& input, bool& output);
bool Convert(const std::string& input, _Null& output);
#define YAML_MAKE_STREAM_CONVERT(type) \
inline bool Convert(const std::string& input, type& output) { \
std::stringstream stream(input); \
stream >> output; \
return !stream.fail(); \
}
YAML_MAKE_STREAM_CONVERT(char)
YAML_MAKE_STREAM_CONVERT(unsigned char)
YAML_MAKE_STREAM_CONVERT(int)
YAML_MAKE_STREAM_CONVERT(unsigned int)
YAML_MAKE_STREAM_CONVERT(short)
YAML_MAKE_STREAM_CONVERT(unsigned short)
YAML_MAKE_STREAM_CONVERT(long)
YAML_MAKE_STREAM_CONVERT(unsigned long)
YAML_MAKE_STREAM_CONVERT(float)
YAML_MAKE_STREAM_CONVERT(double)
YAML_MAKE_STREAM_CONVERT(long double)
#undef YAML_MAKE_STREAM_CONVERT
}
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,17 +0,0 @@
#pragma once
#ifndef CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
// for detecting memory leaks
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif // _DEBUG
#endif // CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,94 +0,0 @@
#pragma once
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "emittermanip.h"
#include "ostream.h"
#include "null.h"
#include <memory>
#include <string>
namespace YAML
{
class EmitterState;
class Emitter
{
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 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);
// local setters
Emitter& SetLocalValue(EMITTER_MANIP value);
Emitter& SetLocalIndent(const _Indent& indent);
// overloads of write
Emitter& Write(const std::string& str);
Emitter& Write(const char *str);
Emitter& Write(int i);
Emitter& Write(bool b);
Emitter& Write(float f);
Emitter& Write(double d);
Emitter& Write(const _Alias& alias);
Emitter& Write(const _Anchor& anchor);
Emitter& Write(const _Comment& comment);
Emitter& Write(const _Null& null);
private:
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
void PreAtomicWrite();
bool GotoNextPreAtomicState();
void PostAtomicWrite();
void EmitSeparationIfNecessary();
void EmitBeginSeq();
void EmitEndSeq();
void EmitBeginMap();
void EmitEndMap();
void EmitKey();
void EmitValue();
private:
ostream m_stream;
std::auto_ptr <EmitterState> m_pState;
};
// overloads of insertion
template <typename T>
inline Emitter& operator << (Emitter& emitter, T v) {
return emitter.Write(v);
}
template <>
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
return emitter.SetLocalValue(value);
}
template <>
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent);
}
}
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,90 +0,0 @@
#pragma once
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include <string>
namespace YAML
{
enum EMITTER_MANIP {
// general manipulators
Auto,
// 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,
// 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;
};
inline _Anchor Anchor(const std::string content) {
return _Anchor(content);
}
struct _Comment {
_Comment(const std::string& content_): content(content_) {}
std::string content;
};
inline _Comment Comment(const std::string content) {
return _Comment(content);
}
}
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,137 +0,0 @@
#pragma once
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "mark.h"
#include <exception>
#include <string>
#include <sstream>
namespace YAML
{
// error messages
namespace ErrorMsg
{
const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
const std::string YAML_VERSION = "bad YAML version: ";
const std::string YAML_MAJOR_VERSION = "YAML major version too large";
const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
const std::string END_OF_MAP = "end of map not found";
const std::string END_OF_MAP_FLOW = "end of map flow not found";
const std::string END_OF_SEQ = "end of sequence not found";
const std::string END_OF_SEQ_FLOW = "end of sequence flow not found";
const std::string MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
const std::string MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
const std::string MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
const std::string ALIAS_CONTENT = "aliases can't have any content, *including* tags";
const std::string INVALID_HEX = "bad character found while scanning hex number";
const std::string INVALID_UNICODE = "invalid unicode: ";
const std::string INVALID_ESCAPE = "unknown escape character: ";
const std::string UNKNOWN_TOKEN = "unknown token";
const std::string DOC_IN_SCALAR = "illegal document indicator in scalar";
const std::string EOF_IN_SCALAR = "illegal EOF in scalar";
const std::string CHAR_IN_SCALAR = "illegal character in scalar";
const std::string TAB_IN_INDENTATION = "illegal tab when looking for indentation";
const std::string FLOW_END = "illegal flow end";
const std::string BLOCK_ENTRY = "illegal block entry";
const std::string MAP_KEY = "illegal map key";
const std::string MAP_VALUE = "illegal map value";
const std::string ALIAS_NOT_FOUND = "alias not found after *";
const std::string ANCHOR_NOT_FOUND = "anchor not found after &";
const std::string CHAR_IN_ALIAS = "illegal character found while scanning alias";
const std::string CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
const std::string ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
const std::string CHAR_IN_BLOCK = "unexpected character in block scalar";
const std::string AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
const std::string UNKNOWN_ANCHOR = "the referenced anchor is not defined";
const std::string INVALID_SCALAR = "invalid scalar";
const std::string KEY_NOT_FOUND = "key not found";
const std::string BAD_DEREFERENCE = "bad dereference";
const std::string UNMATCHED_GROUP_TAG = "unmatched group tag";
const std::string UNEXPECTED_END_SEQ = "unexpected end sequence token";
const std::string UNEXPECTED_END_MAP = "unexpected end map token";
const std::string SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
const std::string INVALID_ANCHOR = "invalid anchor";
const std::string INVALID_ALIAS = "invalid alias";
const std::string EXPECTED_KEY_TOKEN = "expected key token";
const std::string EXPECTED_VALUE_TOKEN = "expected value token";
const std::string UNEXPECTED_KEY_TOKEN = "unexpected key token";
const std::string UNEXPECTED_VALUE_TOKEN = "unexpected value token";
}
class Exception: public std::exception {
public:
Exception(const Mark& mark_, const std::string& msg_)
: mark(mark_), msg(msg_) {
std::stringstream output;
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
what_ = output.str();
}
virtual ~Exception() throw() {}
virtual const char *what() const throw() { return what_.c_str(); }
Mark mark;
std::string msg;
private:
std::string what_;
};
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:
KeyNotFound(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {}
};
template <typename T>
class TypedKeyNotFound: public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_), key(key_) {}
~TypedKeyNotFound() throw() {}
T key;
};
template <typename T>
TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
return TypedKeyNotFound <T> (mark, key);
}
class BadDereference: public RepresentationException {
public:
BadDereference()
: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
};
class EmitterException: public Exception {
public:
EmitterException(const std::string& msg_)
: Exception(Mark::null(), msg_) {}
};
}
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,36 +0,0 @@
#pragma once
#ifndef ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
class Node;
struct IterPriv;
class Iterator
{
public:
Iterator();
Iterator(IterPriv *pData);
Iterator(const Iterator& rhs);
~Iterator();
Iterator& operator = (const Iterator& rhs);
Iterator& operator ++ ();
Iterator operator ++ (int);
const Node& operator * () const;
const Node *operator -> () const;
const Node& first() const;
const Node& second() const;
friend bool operator == (const Iterator& it, const Iterator& jt);
friend bool operator != (const Iterator& it, const Iterator& jt);
private:
IterPriv *m_pData;
};
}
#endif // ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,22 +0,0 @@
#pragma once
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
struct Mark {
Mark(): pos(0), line(0), column(0) {}
static const Mark null() { return Mark(-1, -1, -1); }
int pos;
int line, column;
private:
Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {}
};
}
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,138 +0,0 @@
#pragma once
#ifndef NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "conversion.h"
#include "exceptions.h"
#include "iterator.h"
#include "mark.h"
#include "noncopyable.h"
#include "parserstate.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
namespace YAML
{
class Content;
class Scanner;
class Emitter;
enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP };
class Node: private noncopyable
{
public:
Node();
~Node();
void Clear();
std::auto_ptr<Node> Clone() const;
void Parse(Scanner *pScanner, const ParserState& state);
CONTENT_TYPE GetType() const;
// file location of start of this node
const Mark GetMark() const { return m_mark; }
// accessors
Iterator begin() const;
Iterator end() const;
std::size_t size() const;
// extraction of scalars
bool GetScalar(std::string& s) const;
// we can specialize this for other values
template <typename T>
bool Read(T& value) const;
template <typename T>
const T Read() const;
template <typename T>
operator T() const;
template <typename T>
friend void operator >> (const Node& node, T& value);
// retrieval for maps and sequences
template <typename T>
const Node *FindValue(const T& key) const;
template <typename T>
const Node& operator [] (const T& key) const;
// specific to maps
const Node *FindValue(const char *key) const;
const Node& operator [] (const char *key) const;
// for anchors/aliases
const Node *Identity() const { return m_pIdentity; }
bool IsAlias() const { return m_alias; }
bool IsReferenced() const { return m_referenced; }
// emitting
friend Emitter& operator << (Emitter& out, const Node& node);
// ordering
int Compare(const Node& rhs) const;
friend bool operator < (const Node& n1, const Node& n2);
private:
// helper for sequences
template <typename, bool> friend struct _FindFromNodeAtIndex;
const Node *FindAtIndex(std::size_t i) const;
// helper for maps
template <typename T>
const Node& GetValue(const T& key) const;
template <typename T>
const Node *FindValueForKey(const T& key) const;
// helper for cloning
Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent);
// helpers for parsing
void ParseHeader(Scanner *pScanner, const ParserState& state);
void ParseTag(Scanner *pScanner, const ParserState& state);
void ParseAnchor(Scanner *pScanner, const ParserState& state);
void ParseAlias(Scanner *pScanner, const ParserState& state);
private:
Mark m_mark;
std::string m_anchor, m_tag;
Content *m_pContent;
bool m_alias;
const Node *m_pIdentity;
mutable bool m_referenced;
};
// comparisons with auto-conversion
template <typename T>
bool operator == (const T& value, const Node& node);
template <typename T>
bool operator == (const Node& node, const T& value);
template <typename T>
bool operator != (const T& value, const Node& node);
template <typename T>
bool operator != (const Node& node, const T& value);
bool operator == (const char *value, const Node& node);
bool operator == (const Node& node, const char *value);
bool operator != (const char *value, const Node& node);
bool operator != (const Node& node, const char *value);
}
#include "nodeimpl.h"
#include "nodereadimpl.h"
#endif // NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,118 +0,0 @@
#pragma once
#ifndef NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "nodeutil.h"
namespace YAML
{
// implementation of templated things
template <typename T>
inline const T Node::Read() const {
T value;
*this >> value;
return value;
}
template <typename T>
Node::operator T() const {
return Read<T>();
}
template <typename T>
inline void operator >> (const Node& node, T& value) {
if(!ConvertScalar(node, value))
throw InvalidScalar(node.m_mark);
}
template <typename T>
inline const Node *Node::FindValue(const T& key) const {
switch(GetType()) {
case CT_MAP:
return FindValueForKey(key);
case CT_SEQUENCE:
return FindFromNodeAtIndex(*this, key);
default:
return 0;
}
}
template <typename T>
inline const Node *Node::FindValueForKey(const T& key) const {
for(Iterator it=begin();it!=end();++it) {
T t;
if(it.first().Read(t)) {
if(key == t)
return &it.second();
}
}
return 0;
}
template <typename T>
inline const Node& Node::GetValue(const T& key) const {
if(!m_pContent)
throw BadDereference();
const Node *pValue = FindValue(key);
if(!pValue)
throw MakeTypedKeyNotFound(m_mark, key);
return *pValue;
}
template <typename T>
inline const Node& Node::operator [] (const T& key) const {
return GetValue(key);
}
inline const Node *Node::FindValue(const char *key) const {
return FindValue(std::string(key));
}
inline const Node& Node::operator [] (const char *key) const {
return GetValue(std::string(key));
}
template <typename T>
inline bool operator == (const T& value, const Node& node) {
return value == node.Read<T>();
}
template <typename T>
inline bool operator == (const Node& node, const T& value) {
return value == node.Read<T>();
}
template <typename T>
inline bool operator != (const T& value, const Node& node) {
return value != node.Read<T>();
}
template <typename T>
inline bool operator != (const Node& node, const T& value) {
return value != node.Read<T>();
}
inline bool operator == (const char *value, const Node& node) {
return std::string(value) == node;
}
inline bool operator == (const Node& node, const char *value) {
return std::string(value) == node;
}
inline bool operator != (const char *value, const Node& node) {
return std::string(value) != node;
}
inline bool operator != (const Node& node, const char *value) {
return std::string(value) != node;
}
}
#endif // NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,65 +0,0 @@
#pragma once
namespace YAML
{
// implementation for Node::Read
// (the goal is to call ConvertScalar if we can, and fall back to operator >> if not)
// thanks to litb from stackoverflow.com
// http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390
template<bool>
struct read_impl;
// ConvertScalar available
template<>
struct read_impl<true> {
template<typename T>
static bool read(const Node& node, T& value) {
return ConvertScalar(node, value);
}
};
// ConvertScalar not available
template<>
struct read_impl<false> {
template<typename T>
static bool read(const Node& node, T& value) {
try {
node >> value;
} catch(const Exception&) {
return false;
}
return true;
}
};
namespace fallback {
// sizeof > 1
struct flag { char c[2]; };
flag Convert(...);
char (& operator,(flag, flag) )[1];
template<typename T>
void operator,(flag, T const&);
char (& operator,(char(&)[1], flag) )[1];
}
template <typename T>
inline bool Node::Read(T& value) const {
using namespace fallback;
return read_impl<sizeof (fallback::flag(), Convert(std::string(), value), fallback::flag()) != 1>::read(*this, value);
}
// the main conversion function
template <typename T>
inline bool ConvertScalar(const Node& node, T& value) {
std::string scalar;
if(!node.GetScalar(scalar))
return false;
return Convert(scalar, value);
}
}

View File

@@ -1,60 +0,0 @@
#pragma once
#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
template <typename T, typename U>
struct is_same_type {
enum { value = false };
};
template <typename T>
struct is_same_type<T, T> {
enum { value = true };
};
template <typename T, bool check>
struct is_index_type_with_check {
enum { value = false };
};
template <> struct is_index_type_with_check<std::size_t, false> { enum { value = true }; };
#define MAKE_INDEX_TYPE(Type) \
template <> struct is_index_type_with_check<Type, is_same_type<Type, std::size_t>::value> { enum { value = true }; }
MAKE_INDEX_TYPE(int);
MAKE_INDEX_TYPE(unsigned);
MAKE_INDEX_TYPE(short);
MAKE_INDEX_TYPE(unsigned short);
MAKE_INDEX_TYPE(long);
MAKE_INDEX_TYPE(unsigned long);
#undef MAKE_INDEX_TYPE
template <typename T>
struct is_index_type: public is_index_type_with_check<T, false> {};
// messing around with template stuff to get the right overload for operator [] for a sequence
template <typename T, bool b>
struct _FindFromNodeAtIndex {
const Node *pRet;
_FindFromNodeAtIndex(const Node&, const T&): pRet(0) {}
};
template <typename T>
struct _FindFromNodeAtIndex<T, true> {
const Node *pRet;
_FindFromNodeAtIndex(const Node& node, const T& key): pRet(node.FindAtIndex(static_cast<std::size_t>(key))) {}
};
template <typename T>
inline const Node *FindFromNodeAtIndex(const Node& node, const T& key) {
return _FindFromNodeAtIndex<T, is_index_type<T>::value>(node, key).pRet;
}
}
#endif // NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,22 +0,0 @@
#pragma once
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
// this is basically boost::noncopyable
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable&);
const noncopyable& operator = (const noncopyable&);
};
}
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,21 +0,0 @@
#pragma once
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
class Node;
struct _Null {};
inline bool operator == (const _Null&, const _Null&) { return true; }
inline bool operator != (const _Null&, const _Null&) { return false; }
bool IsNull(const Node& node);
extern _Null Null;
}
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,38 +0,0 @@
#pragma once
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#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

View File

@@ -1,48 +0,0 @@
#pragma once
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include <ios>
#include <string>
#include <vector>
#include <map>
#include "node.h"
#include "parserstate.h"
namespace YAML
{
class Scanner;
struct Token;
class Parser
{
public:
Parser(std::istream& in);
~Parser();
operator bool() const;
void Load(std::istream& in);
void GetNextDocument(Node& document);
void PrintTokens(std::ostream& out);
private:
void ParseDirectives();
void HandleDirective(Token *pToken);
void HandleYamlDirective(Token *pToken);
void HandleTagDirective(Token *pToken);
private:
// can't copy this
Parser(const Parser&) {}
Parser& operator = (const Parser&) { return *this; }
private:
Scanner *m_pScanner;
ParserState m_state;
};
}
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,26 +0,0 @@
#pragma once
#ifndef PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include <string>
#include <map>
namespace YAML
{
struct Version {
int major, minor;
};
struct ParserState
{
Version version;
std::map <std::string, std::string> tags;
void Reset();
std::string TranslateTag(const std::string& handle) const;
};
}
#endif // PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,44 +0,0 @@
#pragma once
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include <vector>
#include <list>
#include <map>
namespace YAML
{
template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::vector <T>& v) {
typedef typename std::vector <T> vec;
emitter << BeginSeq;
for(typename vec::const_iterator it=v.begin();it!=v.end();++it)
emitter << *it;
emitter << EndSeq;
return emitter;
}
template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::list <T>& v) {
typedef typename std::list <T> list;
emitter << BeginSeq;
for(typename list::const_iterator it=v.begin();it!=v.end();++it)
emitter << *it;
emitter << EndSeq;
return emitter;
}
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;
}
}
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

17
include/yaml-cpp/anchor.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHOR_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 <cstddef>
namespace YAML {
typedef std::size_t anchor_t;
const anchor_t NullAnchor = 0;
}
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

67
include/yaml-cpp/binary.h Normal file
View File

@@ -0,0 +1,67 @@
#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define BASE64_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 {
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() : 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.begin());
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;
};
}
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,39 @@
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHORDICT_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 <vector>
#include "../anchor.h"
namespace YAML {
/**
* An object that stores and retrieves values correlating to {@link anchor_t}
* values.
*
* <p>Efficient implementation that can make assumptions about how
* {@code anchor_t} values are assigned by the {@link Parser} class.
*/
template <class T>
class AnchorDict {
public:
void Register(anchor_t anchor, T value) {
if (anchor > m_data.size()) {
m_data.resize(anchor);
}
m_data[anchor - 1] = value;
}
T Get(anchor_t anchor) const { return m_data[anchor - 1]; }
private:
std::vector<T> m_data;
};
}
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,149 @@
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDER_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/mark.h"
#include <string>
namespace YAML {
class Parser;
// GraphBuilderInterface
// . Abstraction of node creation
// . pParentNode is always NULL or the return value of one of the NewXXX()
// functions.
class GraphBuilderInterface {
public:
virtual ~GraphBuilderInterface() = 0;
// Create and return a new node with a null value.
virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
// Create and return a new node with the given tag and value.
virtual void *NewScalar(const Mark &mark, const std::string &tag,
void *pParentNode, const std::string &value) = 0;
// Create and return a new sequence node
virtual void *NewSequence(const Mark &mark, const std::string &tag,
void *pParentNode) = 0;
// Add pNode to pSequence. pNode was created with one of the NewXxx()
// functions and pSequence with NewSequence().
virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
// Note that no moew entries will be added to pSequence
virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
// Create and return a new map node
virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) = 0;
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
// were created with one of the NewXxx() methods and pMap with NewMap().
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
// Note that no more assignments will be made in pMap
virtual void MapComplete(void *pMap) { (void)pMap; }
// Return the node that should be used in place of an alias referencing
// pNode (pNode by default)
virtual void *AnchorReference(const Mark &mark, void *pNode) {
(void)mark;
return pNode;
}
};
// 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 = 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));
}
}
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

33
include/yaml-cpp/dll.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
// The following ifdef block is the standard way of creating macros which make
// exporting from a DLL simpler. All files within this DLL are compiled with the
// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
// be defined on any project that uses this DLL. This way any other project
// whose source files include this file see YAML_CPP_API functions as being
// imported from a DLL, whereas this DLL sees symbols defined with this macro as
// being exported.
#undef YAML_CPP_API
#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
// manually)
#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
// or defined manually)
// #pragma message( "Defining YAML_CPP_API for DLL export" )
#define YAML_CPP_API __declspec(dllexport)
#else // yaml_cpp_EXPORTS
// #pragma message( "Defining YAML_CPP_API for DLL import" )
#define YAML_CPP_API __declspec(dllimport)
#endif // yaml_cpp_EXPORTS
#else // YAML_CPP_DLL
#define YAML_CPP_API
#endif // YAML_CPP_DLL
#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,57 @@
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITFROMEVENTS_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 <stack>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
namespace YAML {
struct Mark;
} // namespace YAML
namespace YAML {
class Emitter;
class EmitFromEvents : public EventHandler {
public:
EmitFromEvents(Emitter& emitter);
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, EmitterStyle::value style);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd();
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

254
include/yaml-cpp/emitter.h Normal file
View File

@@ -0,0 +1,254 @@
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTER_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 <cstddef>
#include <memory>
#include <sstream>
#include <string>
#include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h"
namespace YAML {
class Binary;
struct _Null;
} // namespace YAML
namespace YAML {
class EmitterState;
class YAML_CPP_API Emitter : private noncopyable {
public:
Emitter();
explicit Emitter(std::ostream& stream);
~Emitter();
// output
const char* c_str() const;
std::size_t 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(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);
// 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& 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;
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;
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;
SetStreamablePrecision<T>(stream);
stream << value;
m_stream << stream.str();
StartedScalar();
return *this;
}
template <>
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
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);
}
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);
}
}
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,16 @@
#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

View File

@@ -0,0 +1,137 @@
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERMANIP_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 {
enum EMITTER_MANIP {
// general manipulators
Auto,
TagByKind,
Newline,
// output character set
EmitNonAscii,
EscapeNonAscii,
// 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;
};
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) {
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

View File

@@ -0,0 +1,16 @@
#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 {
struct EmitterStyle {
enum value { Default, Block, Flow };
};
}
#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,40 @@
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EVENTHANDLER_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 "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
namespace YAML {
struct Mark;
class EventHandler {
public:
virtual ~EventHandler() {}
virtual void OnDocumentStart(const Mark& mark) = 0;
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;
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;
};
}
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,267 @@
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_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/mark.h"
#include "yaml-cpp/traits.h"
#include <sstream>
#include <stdexcept>
#include <string>
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept
#ifdef _MSC_VER
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
namespace YAML {
// error messages
namespace ErrorMsg {
const char* const YAML_DIRECTIVE_ARGS =
"YAML directives must have exactly one argument";
const char* const YAML_VERSION = "bad YAML version: ";
const char* const YAML_MAJOR_VERSION = "YAML major version too large";
const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive";
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 CHAR_IN_TAG_HANDLE =
"illegal character found while scanning tag handle";
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_MAP = "end of map 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_FLOW = "end of sequence flow not found";
const char* const MULTIPLE_TAGS =
"cannot assign multiple tags to the same node";
const char* const MULTIPLE_ANCHORS =
"cannot assign multiple anchors to the same node";
const char* const MULTIPLE_ALIASES =
"cannot assign multiple aliases to the same node";
const char* const ALIAS_CONTENT =
"aliases can't have any content, *including* tags";
const char* const INVALID_HEX = "bad character found while scanning hex number";
const char* const INVALID_UNICODE = "invalid unicode: ";
const char* const INVALID_ESCAPE = "unknown escape character: ";
const char* const UNKNOWN_TOKEN = "unknown token";
const char* const DOC_IN_SCALAR = "illegal document indicator in scalar";
const char* const EOF_IN_SCALAR = "illegal EOF in scalar";
const char* const CHAR_IN_SCALAR = "illegal character in scalar";
const char* const TAB_IN_INDENTATION =
"illegal tab when looking for indentation";
const char* const FLOW_END = "illegal flow end";
const char* const BLOCK_ENTRY = "illegal block entry";
const char* const MAP_KEY = "illegal map key";
const char* const MAP_VALUE = "illegal map value";
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 =
"invalid node; this may result from using a map iterator as a sequence "
"iterator, or vice-versa";
const char* const INVALID_SCALAR = "invalid scalar";
const char* const KEY_NOT_FOUND = "key not found";
const char* const BAD_CONVERSION = "bad conversion";
const char* const BAD_DEREFERENCE = "bad dereference";
const char* const BAD_SUBSCRIPT = "operator[] call on a scalar";
const char* const BAD_PUSHBACK = "appending to a non-sequence";
const char* const BAD_INSERT = "inserting in a non-convertible-to-map";
const char* const UNMATCHED_GROUP_TAG = "unmatched group tag";
const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token";
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 BAD_FILE = "bad file";
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(
const T&, typename disable_if<is_numeric<T>>::type* = 0) {
return KEY_NOT_FOUND;
}
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& 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();
}
}
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_) {}
virtual ~Exception() YAML_CPP_NOEXCEPT;
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.c_str();
}
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;
virtual ~ParserException() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API RepresentationException : public Exception {
public:
RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
RepresentationException(const RepresentationException&) = default;
virtual ~RepresentationException() YAML_CPP_NOEXCEPT;
};
// representation exceptions
class YAML_CPP_API InvalidScalar : public RepresentationException {
public:
InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
InvalidScalar(const InvalidScalar&) = default;
virtual ~InvalidScalar() YAML_CPP_NOEXCEPT;
};
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;
virtual ~KeyNotFound() YAML_CPP_NOEXCEPT;
};
template <typename T>
class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {}
virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {}
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()
: RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
InvalidNode(const InvalidNode&) = default;
virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API BadConversion : public RepresentationException {
public:
explicit BadConversion(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
BadConversion(const BadConversion&) = default;
virtual ~BadConversion() YAML_CPP_NOEXCEPT;
};
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;
virtual ~BadDereference() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API BadSubscript : public RepresentationException {
public:
BadSubscript()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
BadSubscript(const BadSubscript&) = default;
virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API BadPushback : public RepresentationException {
public:
BadPushback()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
BadPushback(const BadPushback&) = default;
virtual ~BadPushback() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API BadInsert : public RepresentationException {
public:
BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
BadInsert(const BadInsert&) = default;
virtual ~BadInsert() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API EmitterException : public Exception {
public:
EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {}
EmitterException(const EmitterException&) = default;
virtual ~EmitterException() YAML_CPP_NOEXCEPT;
};
class YAML_CPP_API BadFile : public Exception {
public:
BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
BadFile(const BadFile&) = default;
virtual ~BadFile() YAML_CPP_NOEXCEPT;
};
}
#undef YAML_CPP_NOEXCEPT
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

29
include/yaml-cpp/mark.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MARK_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 {
struct YAML_CPP_API Mark {
Mark() : pos(0), line(0), column(0) {}
static const Mark null_mark() { return Mark(-1, -1, -1); }
bool is_null() const { return pos == -1 && line == -1 && column == -1; }
int pos;
int line, column;
private:
Mark(int pos_, int line_, int column_)
: pos(pos_), line(line_), column(column_) {}
};
}
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,331 @@
#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_CONVERT_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 <array>
#include <limits>
#include <list>
#include <map>
#include <sstream>
#include <vector>
#include "yaml-cpp/binary.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/null.h"
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 <std::size_t N>
struct convert<const char[N]> {
static Node encode(const char(&rhs)[N]) { return Node(rhs); }
};
template <>
struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { return Node(); }
static bool decode(const Node& node, _Null& /* rhs */) {
return node.IsNull();
}
};
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
template <> \
struct convert<type> { \
static Node encode(const type& rhs) { \
std::stringstream stream; \
stream.precision(std::numeric_limits<type>::digits10 + 1); \
stream << rhs; \
return Node(stream.str()); \
} \
\
static bool decode(const Node& node, type& rhs) { \
if (node.Type() != NodeType::Scalar) \
return false; \
const std::string& input = node.Scalar(); \
std::stringstream stream(input); \
stream.unsetf(std::ios::dec); \
if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
return true; \
if (std::numeric_limits<type>::has_infinity) { \
if (conversion::IsInfinity(input)) { \
rhs = std::numeric_limits<type>::infinity(); \
return true; \
} else if (conversion::IsNegativeInfinity(input)) { \
rhs = negative_op std::numeric_limits<type>::infinity(); \
return true; \
} \
} \
\
if (std::numeric_limits<type>::has_quiet_NaN && \
conversion::IsNaN(input)) { \
rhs = std::numeric_limits<type>::quiet_NaN(); \
return true; \
} \
\
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
// bool
template <>
struct convert<bool> {
static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
YAML_CPP_API static bool decode(const Node& node, bool& rhs);
};
// std::map
template <typename K, typename V>
struct convert<std::map<K, V>> {
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.force_insert(it->first, it->second);
return node;
}
static bool decode(const Node& node, std::map<K, V>& rhs) {
if (!node.IsMap())
return false;
rhs.clear();
for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs[it->first.template as<K>()] = it->second.template as<V>();
#else
rhs[it->first.as<K>()] = it->second.as<V>();
#endif
return true;
}
};
// std::vector
template <typename T>
struct convert<std::vector<T>> {
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)
node.push_back(*it);
return node;
}
static bool decode(const Node& node, std::vector<T>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.push_back(it->template as<T>());
#else
rhs.push_back(it->as<T>());
#endif
return true;
}
};
// std::list
template <typename T>
struct convert<std::list<T>> {
static Node encode(const std::list<T>& rhs) {
Node node(NodeType::Sequence);
for (typename std::list<T>::const_iterator it = rhs.begin();
it != rhs.end(); ++it)
node.push_back(*it);
return node;
}
static bool decode(const Node& node, std::list<T>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.push_back(it->template as<T>());
#else
rhs.push_back(it->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::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

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

View File

@@ -0,0 +1,185 @@
#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_IMPL_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/node/detail/node.h"
#include "yaml-cpp/node/detail/node_data.h"
#include <type_traits>
namespace YAML {
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;
}
};
template <typename Key>
struct get_idx<Key,
typename std::enable_if<std::is_unsigned<Key>::value &&
!std::is_same<Key, bool>::value>::type> {
static node* get(const std::vector<node*>& sequence, const Key& key,
shared_memory_holder /* pMemory */) {
return key < sequence.size() ? sequence[key] : 0;
}
static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) {
if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
return 0;
if (key == sequence.size())
sequence.push_back(&pMemory->create_node());
return sequence[key];
}
};
template <typename Key>
struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
static node* get(const std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(
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 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) {
return equals<std::string>(rhs, pMemory);
}
// 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 NULL;
case NodeType::Sequence:
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return pNode;
return NULL;
case NodeType::Scalar:
throw BadSubscript();
}
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->equals(key, pMemory)) {
return it->second;
}
}
return NULL;
}
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 (it->first->equals(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 (kv_pairs::iterator it = m_undefinedPairs.begin();
it != m_undefinedPairs.end();) {
kv_pairs::iterator jt = std::next(it);
if (it->first->equals(key, pMemory))
m_undefinedPairs.erase(it);
it = jt;
}
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->equals(key, pMemory)) {
m_map.erase(it);
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 BadInsert();
}
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

View File

@@ -0,0 +1,92 @@
#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_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"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include <cstddef>
#include <iterator>
namespace YAML {
namespace detail {
struct iterator_value;
template <typename V>
class iterator_base : public std::iterator<std::forward_iterator_tag, V,
std::ptrdiff_t, V*, V> {
private:
template <typename>
friend class iterator_base;
struct enabler {};
typedef node_iterator base_type;
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:
typedef typename iterator_base::value_type value_type;
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;
};
}
}
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,27 @@
#ifndef 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) || \
(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"
#include <list>
#include <utility>
#include <vector>
namespace YAML {
namespace detail {
struct iterator_value;
template <typename V>
class iterator_base;
}
typedef detail::iterator_base<detail::iterator_value> iterator;
typedef detail::iterator_base<const detail::iterator_value> const_iterator;
}
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,46 @@
#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_MEMORY_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 <set>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h"
namespace YAML {
namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
namespace detail {
class YAML_CPP_API memory {
public:
node& create_node();
void merge(const memory& rhs);
private:
typedef std::set<shared_node> Nodes;
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;
};
}
}
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,169 @@
#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_NODE_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/emitterstyle.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_ref.h"
#include <set>
namespace YAML {
namespace detail {
class node {
public:
node() : m_pRef(new node_ref) {}
node(const node&) = delete;
node& operator=(const node&) = delete;
bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
const node_ref* ref() const { return m_pRef.get(); }
bool is_defined() const { return m_pRef->is_defined(); }
const Mark& mark() const { return m_pRef->mark(); }
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(); }
EmitterStyle::value style() const { return m_pRef->style(); }
template <typename T>
bool equals(const T& rhs, shared_memory_holder pMemory);
bool equals(const char* rhs, shared_memory_holder pMemory);
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_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);
}
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 NULL (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 NULL (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;
typedef std::set<node*> nodes;
nodes m_dependencies;
};
}
}
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,127 @@
#ifndef 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) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
namespace YAML {
namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
namespace detail {
class YAML_CPP_API node_data {
public:
node_data();
node_data(const node_data&) = delete;
node_data& operator=(const node_data&) = delete;
void mark_defined();
void set_mark(const Mark& mark);
void set_type(NodeType::value type);
void set_tag(const std::string& tag);
void set_null();
void set_scalar(const std::string& scalar);
void set_style(EmitterStyle::value style);
bool is_defined() const { return m_isDefined; }
const Mark& mark() const { return m_mark; }
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; }
EmitterStyle::value style() const { return m_style; }
// size/iterator
std::size_t size() const;
const_node_iterator begin() const;
node_iterator begin();
const_node_iterator end() const;
node_iterator end();
// sequence
void push_back(node& node, shared_memory_holder pMemory);
void insert(node& key, node& value, shared_memory_holder pMemory);
// indexing
template <typename Key>
node* get(const Key& key, shared_memory_holder pMemory) const;
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory);
template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory);
node* get(node& key, shared_memory_holder pMemory) const;
node& get(node& key, shared_memory_holder pMemory);
bool remove(node& key, 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 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(shared_memory_holder pMemory);
void convert_sequence_to_map(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
typedef std::vector<node*> node_seq;
node_seq m_sequence;
mutable std::size_t m_seqSize;
// map
typedef std::vector<std::pair<node*, node*>> node_map;
node_map m_map;
typedef std::pair<node*, node*> kv_pair;
typedef std::list<kv_pair> kv_pairs;
mutable kv_pairs m_undefinedPairs;
};
}
}
#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,180 @@
#ifndef 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) || \
(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"
#include "yaml-cpp/node/ptr.h"
#include <cstddef>
#include <iterator>
#include <memory>
#include <map>
#include <utility>
#include <vector>
namespace YAML {
namespace detail {
struct iterator_type {
enum value { NoneType, 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::vector<std::pair<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>
class node_iterator_base
: public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
std::ptrdiff_t, node_iterator_value<V>*,
node_iterator_value<V>> {
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:
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::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;
};
typedef node_iterator_base<node> node_iterator;
typedef node_iterator_base<const node> const_node_iterator;
}
}
#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,98 @@
#ifndef 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) || \
(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"
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_data.h"
namespace YAML {
namespace detail {
class node_ref {
public:
node_ref() : m_pData(new node_data) {}
node_ref(const node_ref&) = delete;
node_ref& operator=(const node_ref&) = delete;
bool is_defined() const { return m_pData->is_defined(); }
const Mark& mark() const { return m_pData->mark(); }
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(); }
EmitterStyle::value style() const { return m_pData->style(); }
void mark_defined() { m_pData->mark_defined(); }
void set_data(const node_ref& rhs) { m_pData = rhs.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

View File

@@ -0,0 +1,32 @@
#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_EMIT_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 <iosfwd>
#include "yaml-cpp/dll.h"
namespace YAML {
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

View File

@@ -0,0 +1,448 @@
#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_IMPL_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/node/node.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/exceptions.h"
#include <string>
namespace YAML {
inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
inline Node::Node(NodeType::value type)
: m_isValid(true),
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_isValid(true),
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_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(const Node& rhs)
: m_isValid(rhs.m_isValid),
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
: m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
inline Node::~Node() {}
inline void Node::EnsureNodeExists() const {
if (!m_isValid)
throw InvalidNode();
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 InvalidNode();
}
return m_pNode ? m_pNode->mark() : Mark::null_mark();
}
inline NodeType::value Node::Type() const {
if (!m_isValid)
throw InvalidNode();
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;
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::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)
throw TypedBadConversion<T>(node.Mark());
T t;
if (convert<T>::decode(node, t))
return t;
throw TypedBadConversion<T>(node.Mark());
}
};
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::Scalar)
throw TypedBadConversion<std::string>(node.Mark());
return node.Scalar();
}
};
// access functions
template <typename T>
inline T Node::as() const {
if (!m_isValid)
throw InvalidNode();
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 InvalidNode();
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
}
inline const std::string& Node::Tag() const {
if (!m_isValid)
throw InvalidNode();
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
}
inline void Node::SetTag(const std::string& tag) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_tag(tag);
}
inline EmitterStyle::value Node::Style() const {
if (!m_isValid)
throw InvalidNode();
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
}
inline void Node::SetStyle(EmitterStyle::value style) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_style(style);
}
// assignment
inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
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) {
if (!m_isValid)
throw InvalidNode();
Assign(rhs);
return *this;
}
inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode;
}
template <typename T>
inline void Node::Assign(const T& rhs) {
if (!m_isValid)
throw InvalidNode();
AssignData(convert<T>::encode(rhs));
}
template <>
inline void Node::Assign(const std::string& rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(const char* rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(char* rhs) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline Node& Node::operator=(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::AssignData(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
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 || !rhs.m_isValid)
throw InvalidNode();
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 InvalidNode();
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 InvalidNode();
push_back(Node(rhs));
}
inline void Node::push_back(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
EnsureNodeExists();
rhs.EnsureNodeExists();
m_pNode->push_back(*rhs.m_pNode, m_pMemory);
m_pMemory->merge(*rhs.m_pMemory);
}
// helpers for indexing
namespace detail {
template <typename T>
struct to_value_t {
explicit to_value_t(const T& t_) : t(t_) {}
const T& t;
typedef const T& return_type;
const T& operator()() const { return t; }
};
template <>
struct to_value_t<const char*> {
explicit to_value_t(const char* t_) : t(t_) {}
const char* t;
typedef std::string return_type;
const std::string operator()() const { return t; }
};
template <>
struct to_value_t<char*> {
explicit to_value_t(char* t_) : t(t_) {}
const char* t;
typedef std::string return_type;
const std::string operator()() const { return t; }
};
template <std::size_t N>
struct to_value_t<char[N]> {
explicit to_value_t(const char* t_) : t(t_) {}
const char* t;
typedef std::string return_type;
const std::string operator()() const { return t; }
};
// converts C-strings to std::strings so they can be copied
template <typename T>
inline typename to_value_t<T>::return_type to_value(const T& t) {
return to_value_t<T>(t)();
}
}
// indexing
template <typename Key>
inline const Node Node::operator[](const Key& key) const {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
detail::node* value = static_cast<const detail::node&>(*m_pNode)
.get(detail::to_value(key), m_pMemory);
if (!value) {
return Node(ZombieNode);
}
return Node(*value, m_pMemory);
}
template <typename Key>
inline Node Node::operator[](const Key& key) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
return Node(value, m_pMemory);
}
template <typename Key>
inline bool Node::remove(const Key& key) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
return m_pNode->remove(detail::to_value(key), m_pMemory);
}
inline const Node Node::operator[](const Node& key) const {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
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);
}
return Node(*value, m_pMemory);
}
inline Node Node::operator[](const Node& key) {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
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) {
if (!m_isValid || !key.m_isValid)
throw InvalidNode();
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) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
m_pMemory);
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
}
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,31 @@
#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_ITERATOR_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"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/detail/iterator.h"
#include <list>
#include <utility>
#include <vector>
namespace YAML {
namespace detail {
struct iterator_value : public Node, std::pair<Node, Node> {
iterator_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

View File

@@ -0,0 +1,145 @@
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODE_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 <stdexcept>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/bool_type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
namespace YAML {
namespace detail {
class node;
class node_data;
struct iterator_value;
} // namespace detail
} // namespace YAML
namespace YAML {
class YAML_CPP_API Node {
public:
friend class NodeBuilder;
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;
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();
YAML::Mark Mark() const;
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>
T as() const;
template <typename T, typename S>
T as(const S& fallback) const;
const std::string& Scalar() const;
const std::string& Tag() const;
void SetTag(const std::string& tag);
// style
// 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(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;
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

View File

@@ -0,0 +1,78 @@
#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PARSE_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 <iosfwd>
#include <string>
#include <vector>
#include "yaml-cpp/dll.h"
namespace YAML {
class Node;
/**
* 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

View File

@@ -0,0 +1,29 @@
#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PTR_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"
#include <memory>
namespace YAML {
namespace detail {
class node;
class node_ref;
class node_data;
class memory;
class memory_holder;
typedef std::shared_ptr<node> shared_node;
typedef std::shared_ptr<node_ref> shared_node_ref;
typedef std::shared_ptr<node_data> shared_node_data;
typedef std::shared_ptr<memory_holder> shared_memory_holder;
typedef std::shared_ptr<memory> shared_memory;
}
}
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,16 @@
#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_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 {
struct NodeType {
enum value { Undefined, Null, Scalar, Sequence, Map };
};
}
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

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

26
include/yaml-cpp/null.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NULL_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"
#include <string>
namespace YAML {
class Node;
struct YAML_CPP_API _Null {};
inline bool operator==(const _Null&, const _Null&) { return true; }
inline bool operator!=(const _Null&, const _Null&) { return false; }
YAML_CPP_API bool IsNull(const Node& node); // old API only
YAML_CPP_API bool IsNullString(const std::string& str);
extern YAML_CPP_API _Null Null;
}
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,72 @@
#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();
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 0;
} 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;
}
}
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

86
include/yaml-cpp/parser.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSER_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 <ios>
#include <memory>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/noncopyable.h"
namespace YAML {
class EventHandler;
class Node;
class Scanner;
struct Directives;
struct Token;
/**
* A parser turns a stream of bytes into one stream of "events" per YAML
* document in the input stream.
*/
class YAML_CPP_API Parser : private noncopyable {
public:
/** Constructs an empty parser (with no input. */
Parser();
/**
* Constructs a parser from the given input stream. The input stream must
* live as long as the parser.
*/
explicit Parser(std::istream& in);
~Parser();
/** 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;
};
}
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,51 @@
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STLEMITTER_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 <vector>
#include <list>
#include <set>
#include <map>
namespace YAML {
template <typename Seq>
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
emitter << BeginSeq;
for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
emitter << *it;
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;
}
}
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

103
include/yaml-cpp/traits.h Normal file
View File

@@ -0,0 +1,103 @@
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TRAITS_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 {
template <typename>
struct is_numeric {
enum { value = false };
};
template <>
struct is_numeric<char> {
enum { value = true };
};
template <>
struct is_numeric<unsigned char> {
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)
template <>
struct is_numeric<__int64> {
enum { value = true };
};
template <>
struct is_numeric<unsigned __int64> {
enum { value = true };
};
#else
template <>
struct is_numeric<long long> {
enum { value = true };
};
template <>
struct is_numeric<unsigned long long> {
enum { value = true };
};
#endif
template <>
struct is_numeric<float> {
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>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
}
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

24
include/yaml-cpp/yaml.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define YAML_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/parser.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/stlemitter.h"
#include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/impl.h"
#include "yaml-cpp/node/parse.h"
#include "yaml-cpp/node/emit.h"
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,15 +0,0 @@
#pragma once
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "crt.h"
#include "parser.h"
#include "node.h"
#include "iterator.h"
#include "emitter.h"
#include "stlemitter.h"
#include "exceptions.h"
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -21,4 +21,4 @@ make install
If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary.
(Note: this is pretty tedious. It's sooo much easier to use CMake.)
(Note: this is pretty tedious. It's sooo much easier to use CMake.)

View File

@@ -1,94 +0,0 @@
#include "crt.h"
#include "aliascontent.h"
namespace YAML
{
AliasContent::AliasContent(Content* pNodeContent)
: m_pRef(pNodeContent)
{
}
Content *AliasContent::Clone() const
{
return 0; // TODO: how to clone an alias?
}
void AliasContent::Parse(Scanner * /*pScanner*/, const ParserState& /*state*/)
{
}
void AliasContent::Write(Emitter&) const
{
// no content (just an alias)
}
bool AliasContent::GetBegin(std::vector <Node *>::const_iterator& i) const
{
return m_pRef->GetBegin(i);
}
bool AliasContent::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& i) const
{
return m_pRef->GetBegin(i);
}
bool AliasContent::GetEnd(std::vector <Node *>::const_iterator& i) const
{
return m_pRef->GetEnd(i);
}
bool AliasContent::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& i) const
{
return m_pRef->GetEnd(i);
}
Node* AliasContent::GetNode(std::size_t n) const
{
return m_pRef->GetNode(n);
}
std::size_t AliasContent::GetSize() const
{
return m_pRef->GetSize();
}
bool AliasContent::IsScalar() const
{
return m_pRef->IsScalar();
}
bool AliasContent::IsMap() const
{
return m_pRef->IsMap();
}
bool AliasContent::IsSequence() const
{
return m_pRef->IsSequence();
}
bool AliasContent::GetScalar(std::string& scalar) const
{
return m_pRef->GetScalar(scalar);
}
int AliasContent::Compare(Content *pContent)
{
return m_pRef->Compare(pContent);
}
int AliasContent::Compare(Scalar *pScalar)
{
return m_pRef->Compare(pScalar);
}
int AliasContent::Compare(Sequence *pSequence)
{
return m_pRef->Compare(pSequence);
}
int AliasContent::Compare(Map *pMap)
{
return m_pRef->Compare(pMap);
}
}

View File

@@ -1,43 +0,0 @@
#pragma once
#ifndef ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "content.h"
namespace YAML
{
class AliasContent : public Content
{
public:
AliasContent(Content *pNodeContent);
virtual Content *Clone() const;
virtual void Parse(Scanner* pScanner, const ParserState& state);
virtual void Write(Emitter&) const;
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const;
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const;
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const;
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const;
virtual Node* GetNode(std::size_t) const;
virtual std::size_t GetSize() const;
virtual bool IsScalar() const;
virtual bool IsMap() const;
virtual bool IsSequence() const;
virtual bool GetScalar(std::string& s) const;
virtual int Compare(Content *);
virtual int Compare(Scalar *);
virtual int Compare(Sequence *);
virtual int Compare(Map *);
private:
Content* m_pRef;
};
}
#endif // ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

93
src/binary.cpp Normal file
View File

@@ -0,0 +1,93 @@
#include "yaml-cpp/binary.h"
namespace YAML {
static const char encoding[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string EncodeBase64(const unsigned char *data, std::size_t size) {
const char PAD = '=';
std::string ret;
ret.resize(4 * size / 3 + 3);
char *out = &ret[0];
std::size_t chunks = size / 3;
std::size_t remainder = size % 3;
for (std::size_t i = 0; i < chunks; i++, data += 3) {
*out++ = encoding[data[0] >> 2];
*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;
case 1:
*out++ = encoding[data[0] >> 2];
*out++ = encoding[((data[0] & 0x3) << 4)];
*out++ = PAD;
*out++ = PAD;
break;
case 2:
*out++ = encoding[data[0] >> 2];
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
*out++ = encoding[((data[1] & 0xf) << 2)];
*out++ = PAD;
break;
}
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) {
typedef std::vector<unsigned char> ret_type;
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; 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;
}
}

39
src/collectionstack.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define COLLECTIONSTACK_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 <stack>
#include <cassert>
namespace YAML {
struct CollectionType {
enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
};
class CollectionStack {
public:
CollectionType::value GetCurCollectionType() const {
if (collectionStack.empty())
return CollectionType::NoCollection;
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;
};
}
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,13 +0,0 @@
#include "crt.h"
#include "content.h"
namespace YAML
{
Content::Content()
{
}
Content::~Content()
{
}
}

View File

@@ -1,57 +0,0 @@
#pragma once
#ifndef CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include <vector>
#include <map>
#include "parserstate.h"
#include "exceptions.h"
#include "ltnode.h"
namespace YAML
{
class Scanner;
class Parser;
class Node;
class Scalar;
class Sequence;
class Map;
class Emitter;
class Content
{
public:
Content();
virtual ~Content();
virtual Content *Clone() const = 0;
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
virtual void Write(Emitter& out) const = 0;
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const { return false; }
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; }
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual Node *GetNode(std::size_t) const { return 0; }
virtual std::size_t GetSize() const { return 0; }
virtual bool IsScalar() const { return false; }
virtual bool IsMap() const { return false; }
virtual bool IsSequence() const { return false; }
// extraction
virtual bool GetScalar(std::string&) const { return false; }
// ordering
virtual int Compare(Content *) { return 0; }
virtual int Compare(Scalar *) { return 0; }
virtual int Compare(Sequence *) { return 0; }
virtual int Compare(Map *) { return 0; }
protected:
};
}
#endif // CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -0,0 +1,17 @@
#include "graphbuilderadapter.h"
#include "yaml-cpp/parser.h" // IWYU pragma: keep
namespace YAML {
class GraphBuilderInterface;
void* BuildGraphOfNextDocument(Parser& parser,
GraphBuilderInterface& graphBuilder) {
GraphBuilderAdapter eventHandler(graphBuilder);
if (parser.HandleNextDocument(eventHandler)) {
return eventHandler.RootNode();
} else {
return NULL;
}
}
}

View File

@@ -0,0 +1,94 @@
#include "graphbuilderadapter.h"
#include "yaml-cpp/contrib/graphbuilder.h"
namespace YAML {
struct Mark;
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) {
void *pParent = GetCurrentParent();
void *pNode = m_builder.NewNull(mark, pParent);
RegisterAnchor(anchor, 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 = 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);
}
}
}

View File

@@ -0,0 +1,79 @@
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDERADAPTER_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 <cstdlib>
#include <map>
#include <stack>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
namespace YAML {
class GraphBuilderInterface;
struct Mark;
} // namespace YAML
namespace YAML {
class GraphBuilderAdapter : public EventHandler {
public:
GraphBuilderAdapter(GraphBuilderInterface& builder)
: m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {}
virtual void OnDocumentStart(const Mark& mark) { (void)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, EmitterStyle::value style);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd();
void* RootNode() const { return m_pRootNode; }
private:
struct ContainerFrame {
ContainerFrame(void* pSequence)
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
ContainerFrame(void* pMap, void* pPrevKeyNode)
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {}
void* pContainer;
void* pPrevKeyNode;
bool isMap() const { return pPrevKeyNode != &sequenceMarker; }
private:
static int sequenceMarker;
};
typedef std::stack<ContainerFrame> ContainerStack;
typedef AnchorDict<void*> AnchorMap;
GraphBuilderInterface& m_builder;
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);
};
}
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,89 +0,0 @@
#include "conversion.h"
#include <algorithm>
////////////////////////////////////////////////////////////////
// Specializations for converting a string to specific types
namespace
{
// 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 IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str)
{
std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower);
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));
}
}
namespace YAML
{
bool Convert(const std::string& input, bool& b)
{
// 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(input))
return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
if(names[i].truename == tolower(input)) {
b = true;
return true;
}
if(names[i].falsename == tolower(input)) {
b = false;
return true;
}
}
return false;
}
bool Convert(const std::string& input, _Null& /*output*/)
{
return input.empty() || input == "~" || input == "null" || input == "Null" || input == "NULL";
}
}

75
src/convert.cpp Normal file
View File

@@ -0,0 +1,75 @@
#include <algorithm>
#include "yaml-cpp/node/convert.h"
namespace {
// 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 IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str) {
std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower);
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));
}
}
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 (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;
}
}

22
src/directives.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include "directives.h"
namespace YAML {
Directives::Directives() {
// version
version.isDefault = true;
version.major = 1;
version.minor = 2;
}
const std::string Directives::TranslateTagHandle(
const std::string& handle) const {
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;
}
}

29
src/directives.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DIRECTIVES_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 <map>
namespace YAML {
struct Version {
bool isDefault;
int major, minor;
};
struct Directives {
Directives();
const 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

25
src/emit.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "yaml-cpp/node/emit.h"
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "nodeevents.h"
namespace YAML {
Emitter& operator<<(Emitter& out, const Node& node) {
EmitFromEvents emitFromEvents(out);
NodeEvents events(node);
events.Emit(emitFromEvents);
return out;
}
std::ostream& operator<<(std::ostream& out, const Node& node) {
Emitter emitter(out);
emitter << node;
return out;
}
std::string Dump(const Node& node) {
Emitter emitter;
emitter << node;
return emitter.c_str();
}
} // namespace YAML

119
src/emitfromevents.cpp Normal file
View File

@@ -0,0 +1,119 @@
#include <cassert>
#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 {
std::string ToString(YAML::anchor_t anchor) {
std::stringstream stream;
stream << anchor;
return stream.str();
}
}
namespace YAML {
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,
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;
}
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, 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;
}
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 != "!")
m_emitter << VerbatimTag(tag);
if (anchor)
m_emitter << Anchor(ToString(anchor));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,263 +1,365 @@
#include <limits>
#include "emitterstate.h"
#include "exceptions.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
namespace YAML
{
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSeparation(false)
{
// start up
m_stateStack.push(ES_WAITING_FOR_DOC);
// set default global manipulators
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);
}
EmitterState::~EmitterState()
{
while(!m_groups.empty())
_PopGroup();
}
std::auto_ptr <EmitterState::Group> EmitterState::_PopGroup()
{
if(m_groups.empty())
return std::auto_ptr <Group> (0);
std::auto_ptr <Group> pGroup(m_groups.top());
m_groups.pop();
return pGroup;
}
// SetLocalValue
// . 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)
{
SetStringFormat(value, LOCAL);
SetBoolFormat(value, LOCAL);
SetBoolCaseFormat(value, LOCAL);
SetBoolLengthFormat(value, LOCAL);
SetIntFormat(value, LOCAL);
SetFlowType(GT_SEQ, value, LOCAL);
SetFlowType(GT_MAP, value, LOCAL);
SetMapKeyFormat(value, LOCAL);
}
void EmitterState::BeginGroup(GROUP_TYPE type)
{
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top()->indent);
m_curIndent += lastIndent;
std::auto_ptr <Group> pGroup(new Group(type));
// transfer settings (which last until this group is done)
pGroup->modifiedSettings = m_modifiedSettings;
// set up group
pGroup->flow = GetFlowType(type);
pGroup->indent = GetIndent();
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
m_groups.push(pGroup.release());
}
void EmitterState::EndGroup(GROUP_TYPE type)
{
if(m_groups.empty())
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
// get rid of the current group
{
std::auto_ptr <Group> pFinishedGroup = _PopGroup();
if(pFinishedGroup->type != type)
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
}
// 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::ClearModifiedSettings()
{
m_modifiedSettings.clear();
}
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;
}
}
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;
}
}
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case UpperCase:
case LowerCase:
case CamelCase:
_Set(m_boolCaseFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case Dec:
case Hex:
case Oct:
_Set(m_intFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
{
if(value == 0)
return false;
_Set(m_indent, value, scope);
return true;
}
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;
}
bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case Block:
case Flow:
_Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
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;
}
}
namespace YAML {
EmitterState::EmitterState()
: m_isGood(true),
m_curIndent(0),
m_hasAnchor(false),
m_hasTag(false),
m_hasNonContent(false),
m_docCount(0) {
// 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(std::numeric_limits<float>::digits10 + 1);
m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
}
EmitterState::~EmitterState() {}
// SetLocalValue
// . 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) {
SetOutputCharset(value, FmtScope::Local);
SetStringFormat(value, FmtScope::Local);
SetBoolFormat(value, FmtScope::Local);
SetBoolCaseFormat(value, FmtScope::Local);
SetBoolLengthFormat(value, FmtScope::Local);
SetIntFormat(value, FmtScope::Local);
SetFlowType(GroupType::Seq, value, FmtScope::Local);
SetFlowType(GroupType::Map, value, FmtScope::Local);
SetMapKeyFormat(value, FmtScope::Local);
}
void EmitterState::SetAnchor() { m_hasAnchor = true; }
void EmitterState::SetTag() { m_hasTag = true; }
void EmitterState::SetNonContent() { m_hasNonContent = true; }
void EmitterState::SetLongKey() {
assert(!m_groups.empty());
if (m_groups.empty()) {
return;
}
assert(m_groups.back()->type == GroupType::Map);
m_groups.back()->longKey = true;
}
void EmitterState::ForceFlow() {
assert(!m_groups.empty());
if (m_groups.empty()) {
return;
}
m_groups.back()->flowType = FlowType::Flow;
}
void EmitterState::StartedNode() {
if (m_groups.empty()) {
m_docCount++;
} else {
m_groups.back()->childCount++;
if (m_groups.back()->childCount % 2 == 0) {
m_groups.back()->longKey = false;
}
}
m_hasAnchor = false;
m_hasTag = false;
m_hasNonContent = false;
}
EmitterNodeType::value EmitterState::NextGroupType(
GroupType::value type) const {
if (type == GroupType::Seq) {
if (GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq;
else
return EmitterNodeType::FlowSeq;
} else {
if (GetFlowType(type) == Block)
return EmitterNodeType::BlockMap;
else
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);
} else {
return SetError(ErrorMsg::UNEXPECTED_END_MAP);
}
}
// 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();
}
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(); }
bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case EmitNonAscii:
case EscapeNonAscii:
_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::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>::digits10 + 1)
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>::digits10 + 1)
return false;
_Set(m_doublePrecision, value, scope);
return true;
}
}

View File

@@ -1,201 +1,203 @@
#pragma once
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_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 "setting.h"
#include "emittermanip.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h"
#include <cassert>
#include <vector>
#include <stack>
#include <memory>
#include <stack>
#include <stdexcept>
#include <vector>
namespace YAML
{
enum FMT_SCOPE {
LOCAL,
GLOBAL
};
enum GROUP_TYPE {
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();
namespace YAML {
struct FmtScope {
enum value { Local, Global };
};
struct GroupType {
enum value { NoType, Seq, Map };
};
struct FlowType {
enum value { NoType, Flow, Block };
};
bool RequiresSeparation() const { return m_requiresSeparation; }
void RequireSeparation() { m_requiresSeparation = true; }
void UnsetSeparation() { m_requiresSeparation = false; }
class EmitterState {
public:
EmitterState();
~EmitterState();
void ClearModifiedSettings();
// 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;
}
// formatters
bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
// node handling
void SetAnchor();
void SetTag();
void SetNonContent();
void SetLongKey();
void ForceFlow();
void StartedDoc();
void EndedDoc();
void StartedScalar();
void StartedGroup(GroupType::value type);
void EndedGroup(GroupType::value type);
bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
EmitterNodeType::value NextGroupType(GroupType::value type) const;
EmitterNodeType::value CurGroupNodeType() const;
bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
GroupType::value CurGroupType() const;
FlowType::value CurGroupFlowType() const;
std::size_t CurGroupIndent() const;
std::size_t CurGroupChildCount() const;
bool CurGroupLongKey() const;
bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
std::size_t LastIndent() const;
std::size_t CurIndent() const { return m_curIndent; }
bool HasAnchor() const { return m_hasAnchor; }
bool HasTag() const { return m_hasTag; }
bool HasBegunNode() const {
return m_hasAnchor || m_hasTag || m_hasNonContent;
}
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
bool SetIndent(unsigned value, FMT_SCOPE scope);
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(); }
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_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;
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;
};
std::auto_ptr <Group> _PopGroup();
std::stack <Group *> m_groups;
unsigned m_curIndent;
bool m_requiresSeparation;
};
void ClearModifiedSettings();
template <typename T>
void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
switch(scope) {
case LOCAL:
m_modifiedSettings.push(fmt.set(value));
break;
case 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);
}
}
// formatters
void SetLocalValue(EMITTER_MANIP value);
bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.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_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_), indent(0), childCount(0), longKey(false) {}
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_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);
}
}
}
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,145 +1,483 @@
#include <iomanip>
#include <sstream>
#include "emitterutils.h"
#include "exp.h"
#include "indentation.h"
#include "exceptions.h"
#include "regex_yaml.h"
#include "regeximpl.h"
#include "stringsource.h"
#include <sstream>
#include <iomanip>
#include "yaml-cpp/binary.h" // IWYU pragma: keep
#include "yaml-cpp/ostream_wrapper.h"
#include "yaml-cpp/null.h"
namespace YAML
{
namespace Utils
{
namespace {
bool IsPrintable(char ch) {
return (0x20 <= ch && ch <= 0x7E);
}
bool IsValidPlainScalar(const std::string& str, bool inFlow) {
// 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;
namespace YAML {
namespace Utils {
namespace {
enum { REPLACEMENT_CHARACTER = 0xFFFD };
// then check until something is disallowed
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow : Exp::EndScalar)
|| (Exp::BlankOrBreak + Exp::Comment)
|| (!Exp::Printable)
|| Exp::Break
|| Exp::Tab;
StringCharSource buffer(str.c_str(), str.size());
while(buffer) {
if(disallowed.Matches(buffer))
return false;
++buffer;
}
return true;
}
}
bool WriteString(ostream& out, const std::string& str, bool inFlow)
{
if(IsValidPlainScalar(str, inFlow)) {
out << str;
return true;
} else
return WriteDoubleQuotedString(out, str);
}
bool WriteSingleQuotedString(ostream& out, const std::string& str)
{
out << "'";
for(std::size_t i=0;i<str.size();i++) {
char ch = str[i];
if(!IsPrintable(ch))
return false;
if(ch == '\'')
out << "''";
else
out << ch;
}
out << "'";
return true;
}
bool WriteDoubleQuotedString(ostream& out, const std::string& str)
{
out << "\"";
for(std::size_t i=0;i<str.size();i++) {
char ch = str[i];
if(IsPrintable(ch)) {
if(ch == '\"')
out << "\\\"";
else if(ch == '\\')
out << "\\\\";
else
out << ch;
} else {
// TODO: for the common escaped characters, give their usual symbol
std::stringstream str;
str << "\\x" << std::hex << std::setfill('0') << std::setw(2) << static_cast <int>(ch);
out << str.str();
}
}
out << "\"";
return true;
}
bool IsAnchorChar(int ch) { // test for ns-anchor-char
switch (ch) {
case ',':
case '[':
case ']':
case '{':
case '}': // c-flow-indicator
case ' ':
case '\t': // s-white
case 0xFEFF: // c-byte-order-mark
case 0xA:
case 0xD: // b-char
return false;
case 0x85:
return true;
}
bool WriteLiteralString(ostream& out, const std::string& str, int indent)
{
out << "|\n";
out << IndentTo(indent);
for(std::size_t i=0;i<str.size();i++) {
if(str[i] == '\n')
out << "\n" << IndentTo(indent);
else
out << str[i];
}
return true;
}
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
{
unsigned curIndent = out.col();
out << "#" << Indentation(postCommentIndent);
for(std::size_t i=0;i<str.size();i++) {
if(str[i] == '\n')
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
else
out << str[i];
}
return true;
}
if (ch < 0x20) {
return false;
}
bool WriteAlias(ostream& out, const std::string& str)
{
out << "*";
for(std::size_t i=0;i<str.size();i++) {
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
return false;
out << str[i];
}
return true;
}
bool WriteAnchor(ostream& out, const std::string& str)
{
out << "&";
for(std::size_t i=0;i<str.size();i++) {
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
return false;
out << str[i];
}
return true;
}
}
if (ch < 0x7E) {
return true;
}
if (ch < 0xA0) {
return false;
}
if (ch >= 0xD800 && ch <= 0xDFFF) {
return false;
}
if ((ch & 0xFFFE) == 0xFFFE) {
return false;
}
if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) {
return false;
}
if (ch > 0x10FFFF) {
return 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,
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_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 std::string& str, FlowType::value flowType,
bool allowOnlyAscii) {
// check against null
if (IsNullString(str)) {
return false;
}
// check the start
const RegEx& start = (flowType == FlowType::Flow ? 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
static const RegEx& disallowed_flow =
Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) ||
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
Exp::Tab();
static const RegEx& disallowed_block =
Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) ||
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
Exp::Tab();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
StringCharSource buffer(str.c_str(), 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 std::string& str, bool escapeNonAscii) {
// TODO: check for non-printable characters?
for (std::size_t i = 0; i < str.size(); i++) {
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
return false;
}
if (str[i] == '\n') {
return false;
}
}
return true;
}
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
bool escapeNonAscii) {
if (flowType == FlowType::Flow) {
return false;
}
// TODO: check for non-printable characters?
for (std::size_t i = 0; i < str.size(); i++) {
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
return false;
}
}
return true;
}
void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
static const char hexDigits[] = "0123456789abcdef";
out << "\\";
int digits = 8;
if (codePoint < 0xFF) {
out << "x";
digits = 2;
} else if (codePoint < 0xFFFF) {
out << "u";
digits = 4;
} else {
out << "U";
digits = 8;
}
// Write digits into the escape sequence
for (; digits > 0; --digits)
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
}
bool WriteAliasName(ostream_wrapper& 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;
}
}
StringFormat::value ComputeStringFormat(const std::string& str,
EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii) {
switch (strFormat) {
case Auto:
if (IsValidPlainScalar(str, flowType, escapeNonAscii)) {
return StringFormat::Plain;
}
return StringFormat::DoubleQuoted;
case SingleQuoted:
if (IsValidSingleQuotedScalar(str, escapeNonAscii)) {
return StringFormat::SingleQuoted;
}
return StringFormat::DoubleQuoted;
case DoubleQuoted:
return StringFormat::DoubleQuoted;
case Literal:
if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) {
return StringFormat::Literal;
}
return StringFormat::DoubleQuoted;
default:
break;
}
return StringFormat::DoubleQuoted;
}
bool WriteSingleQuotedString(ostream_wrapper& 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_wrapper& out, const std::string& str,
bool escapeNonAscii) {
out << "\"";
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
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;
default:
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_wrapper& out, const std::string& str,
std::size_t 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_wrapper& out, char ch) {
if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
out << ch;
} else if (ch == '\"') {
out << "\"\\\"\"";
} else if (ch == '\t') {
out << "\"\\t\"";
} else if (ch == '\n') {
out << "\"\\n\"";
} else if (ch == '\b') {
out << "\"\\b\"";
} else if (ch == '\\') {
out << "\"\\\\\"";
} else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') {
out << "\"" << ch << "\"";
} else {
out << "\"";
WriteDoubleQuoteEscapeSequence(out, ch);
out << "\"";
}
return true;
}
bool WriteComment(ostream_wrapper& out, const std::string& str,
std::size_t postCommentIndent) {
const std::size_t curIndent = out.col();
out << "#" << Indentation(postCommentIndent);
out.set_comment();
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
if (codePoint == '\n') {
out << "\n" << IndentTo(curIndent) << "#"
<< Indentation(postCommentIndent);
out.set_comment();
} else {
WriteCodePoint(out, codePoint);
}
}
return true;
}
bool WriteAlias(ostream_wrapper& out, const std::string& str) {
out << "*";
return WriteAliasName(out, str);
}
bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
out << "&";
return WriteAliasName(out, str);
}
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) {
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
false);
return true;
}
}
}

View File

@@ -1,24 +1,50 @@
#pragma once
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERUTILS_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 "ostream.h"
#include <string>
namespace YAML
{
namespace Utils
{
bool WriteString(ostream& out, const std::string& str, bool inFlow);
bool WriteSingleQuotedString(ostream& out, const std::string& str);
bool WriteDoubleQuotedString(ostream& out, const std::string& str);
bool WriteLiteralString(ostream& out, const std::string& str, int indent);
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
bool WriteAlias(ostream& out, const std::string& str);
bool WriteAnchor(ostream& out, const std::string& str);
}
#include "emitterstate.h"
#include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/ostream_wrapper.h"
namespace YAML {
class ostream_wrapper;
} // namespace YAML
namespace YAML {
class Binary;
struct StringFormat {
enum value { Plain, SingleQuoted, DoubleQuoted, Literal };
};
namespace Utils {
StringFormat::value ComputeStringFormat(const std::string& str,
EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii);
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
bool escapeNonAscii);
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
std::size_t indent);
bool WriteChar(ostream_wrapper& out, char ch);
bool WriteComment(ostream_wrapper& out, const std::string& str,
std::size_t postCommentIndent);
bool WriteAlias(ostream_wrapper& out, const std::string& str);
bool WriteAnchor(ostream_wrapper& out, const std::string& str);
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

31
src/exceptions.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "yaml-cpp/exceptions.h"
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept
#ifdef _MSC_VER
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
namespace YAML {
// These destructors are defined out-of-line so the vtable is only emitted once.
Exception::~Exception() YAML_CPP_NOEXCEPT {}
ParserException::~ParserException() YAML_CPP_NOEXCEPT {}
RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT {}
InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT {}
KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT {}
InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT {}
BadConversion::~BadConversion() YAML_CPP_NOEXCEPT {}
BadDereference::~BadDereference() YAML_CPP_NOEXCEPT {}
BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT {}
BadPushback::~BadPushback() YAML_CPP_NOEXCEPT {}
BadInsert::~BadInsert() YAML_CPP_NOEXCEPT {}
EmitterException::~EmitterException() YAML_CPP_NOEXCEPT {}
BadFile::~BadFile() YAML_CPP_NOEXCEPT {}
}
#undef YAML_CPP_NOEXCEPT

View File

@@ -1,113 +1,136 @@
#include "crt.h"
#include "exp.h"
#include "exceptions.h"
#include <sstream>
namespace YAML
{
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);
#include "exp.h"
#include "stream.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
value = (value << 4) + digit;
}
namespace YAML {
struct Mark;
} // namespace YAML
return value;
}
namespace YAML {
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);
std::string Str(char ch)
{
return std::string("") + ch;
}
value = (value << 4) + digit;
}
// 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 "\0";
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 'N': return "\xC2\x85"; // NEL (#x85)
case '_': return "\xC2\xA0"; // #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(), ErrorMsg::INVALID_ESCAPE + ch);
}
}
return value;
}
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);
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);
}
}
}

282
src/exp.h
View File

@@ -1,80 +1,222 @@
#pragma once
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXP_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 "regex.h"
#include <string>
#include <ios>
#include <string>
#include "regex_yaml.h"
#include "stream.h"
namespace YAML
{
////////////////////////////////////////////////////////////////////////////////
// Here we store a bunch of expressions for matching different parts of the file.
namespace YAML {
////////////////////////////////////////////////////////////////////////////////
// Here we store a bunch of expressions for matching different parts of the
// file.
namespace Exp
{
// misc
const RegEx Space = RegEx(' ');
const RegEx Tab = RegEx('\t');
const RegEx Blank = Space || Tab;
const RegEx Break = RegEx('\n') || RegEx("\r\n");
const RegEx BlankOrBreak = Blank || Break;
const RegEx Digit = RegEx('0', '9');
const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z');
const RegEx AlphaNumeric = Alpha || Digit;
const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f');
const RegEx Printable = RegEx(0x20, 0x7E);
// actual tags
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx());
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx());
const RegEx DocIndicator = DocStart || DocEnd;
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx());
const RegEx Key = RegEx('?'),
KeyInFlow = RegEx('?') + BlankOrBreak;
const RegEx Value = RegEx(':') + (BlankOrBreak || RegEx()),
ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR));
const RegEx Comment = RegEx('#');
const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak;
// 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.
const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)),
PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank));
const RegEx EndScalar = RegEx(':') + (BlankOrBreak || RegEx()),
EndScalarInFlow = (RegEx(':') + (BlankOrBreak || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
const RegEx EscSingleQuote = RegEx("\'\'");
const RegEx EscBreak = RegEx('\\') + Break;
const RegEx ChompIndicator = RegEx("+-", REGEX_OR);
const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit;
// 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 = '>';
}
namespace Exp {
// misc
inline const RegEx& Empty() {
static const RegEx e;
return e;
}
inline const RegEx& Space() {
static const RegEx e = RegEx(' ');
return e;
}
inline const RegEx& Tab() {
static const RegEx e = RegEx('\t');
return e;
}
inline const RegEx& Blank() {
static const RegEx e = Space() || Tab();
return e;
}
inline const RegEx& Break() {
static const RegEx e = RegEx('\n') || RegEx("\r\n");
return e;
}
inline const RegEx& BlankOrBreak() {
static const RegEx e = Blank() || Break();
return e;
}
inline const RegEx& Digit() {
static const RegEx e = RegEx('0', '9');
return e;
}
inline const RegEx& Alpha() {
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
return e;
}
inline const RegEx& AlphaNumeric() {
static const RegEx e = Alpha() || Digit();
return e;
}
inline const RegEx& Word() {
static const RegEx e = AlphaNumeric() || RegEx('-');
return e;
}
inline const RegEx& Hex() {
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
return e;
}
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
// 5.1)
inline const RegEx& NotPrintable() {
static const RegEx e =
RegEx(0) ||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
RegEx(0x0E, 0x1F) ||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
return e;
}
inline const RegEx& Utf8_ByteOrderMark() {
static const RegEx e = RegEx("\xEF\xBB\xBF");
return e;
}
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
// actual tags
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 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& 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

View File

@@ -1,36 +1,41 @@
#pragma once
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define INDENTATION_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 "ostream.h"
#include <iostream>
#include <cstddef>
namespace YAML
{
struct Indentation {
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;
}
#include "yaml-cpp/ostream_wrapper.h"
struct IndentTo {
IndentTo(unsigned n_): n(n_) {}
unsigned n;
};
inline ostream& operator << (ostream& out, const IndentTo& indent) {
while(out.col() < indent.n)
out << ' ';
return out;
}
namespace YAML {
struct Indentation {
Indentation(std::size_t n_) : n(n_) {}
std::size_t n;
};
inline ostream_wrapper& operator<<(ostream_wrapper& out,
const Indentation& indent) {
for (std::size_t i = 0; i < indent.n; i++)
out << ' ';
return out;
}
struct IndentTo {
IndentTo(std::size_t n_) : n(n_) {}
std::size_t n;
};
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
inline ostream_wrapper& operator<<(ostream_wrapper& out,
const IndentTo& indent) {
while (out.col() < indent.n)
out << ' ';
return out;
}
}
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,108 +0,0 @@
#include "crt.h"
#include "node.h"
#include "exceptions.h"
#include "iterpriv.h"
namespace YAML
{
Iterator::Iterator(): m_pData(0)
{
m_pData = new IterPriv;
}
Iterator::Iterator(IterPriv *pData): m_pData(pData)
{
}
Iterator::Iterator(const Iterator& rhs): m_pData(0)
{
m_pData = new IterPriv(*rhs.m_pData);
}
Iterator& Iterator::operator = (const Iterator& rhs)
{
if(this == &rhs)
return *this;
delete m_pData;
m_pData = new IterPriv(*rhs.m_pData);
return *this;
}
Iterator::~Iterator()
{
delete m_pData;
}
Iterator& Iterator::operator ++ ()
{
if(m_pData->type == IterPriv::IT_SEQ)
++m_pData->seqIter;
else if(m_pData->type == IterPriv::IT_MAP)
++m_pData->mapIter;
return *this;
}
Iterator Iterator::operator ++ (int)
{
Iterator temp = *this;
if(m_pData->type == IterPriv::IT_SEQ)
++m_pData->seqIter;
else if(m_pData->type == IterPriv::IT_MAP)
++m_pData->mapIter;
return temp;
}
const Node& Iterator::operator * () const
{
if(m_pData->type == IterPriv::IT_SEQ)
return **m_pData->seqIter;
throw BadDereference();
}
const Node *Iterator::operator -> () const
{
if(m_pData->type == IterPriv::IT_SEQ)
return *m_pData->seqIter;
throw BadDereference();
}
const Node& Iterator::first() const
{
if(m_pData->type == IterPriv::IT_MAP)
return *m_pData->mapIter->first;
throw BadDereference();
}
const Node& Iterator::second() const
{
if(m_pData->type == IterPriv::IT_MAP)
return *m_pData->mapIter->second;
throw BadDereference();
}
bool operator == (const Iterator& it, const Iterator& jt)
{
if(it.m_pData->type != jt.m_pData->type)
return false;
if(it.m_pData->type == IterPriv::IT_SEQ)
return it.m_pData->seqIter == jt.m_pData->seqIter;
else if(it.m_pData->type == IterPriv::IT_MAP)
return it.m_pData->mapIter == jt.m_pData->mapIter;
return true;
}
bool operator != (const Iterator& it, const Iterator& jt)
{
return !(it == jt);
}
}

View File

@@ -1,31 +0,0 @@
#pragma once
#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "ltnode.h"
#include <vector>
#include <map>
namespace YAML
{
class Node;
// IterPriv
// . The implementation for iterators - essentially a union of sequence and map iterators.
struct IterPriv
{
IterPriv(): type(IT_NONE) {}
IterPriv(std::vector <Node *>::const_iterator it): type(IT_SEQ), seqIter(it) {}
IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): type(IT_MAP), mapIter(it) {}
enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
ITER_TYPE type;
std::vector <Node *>::const_iterator seqIter;
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
};
}
#endif // ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,16 +0,0 @@
#pragma once
#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
class Node;
struct ltnode {
bool operator()(const Node *pNode1, const Node *pNode2) const;
};
}
#endif // LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,189 +0,0 @@
#include "crt.h"
#include "map.h"
#include "node.h"
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
#include "emitter.h"
#include <memory>
namespace YAML
{
Map::Map()
{
}
Map::Map(const node_map& data)
{
for(node_map::const_iterator it=data.begin();it!=data.end();++it) {
std::auto_ptr<Node> pKey = it->first->Clone();
std::auto_ptr<Node> pValue = it->second->Clone();
m_data[pKey.release()] = pValue.release();
}
}
Map::~Map()
{
Clear();
}
void Map::Clear()
{
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
delete it->first;
delete it->second;
}
m_data.clear();
}
Content *Map::Clone() const
{
return new Map(m_data);
}
bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
{
it = m_data.begin();
return true;
}
bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const
{
it = m_data.end();
return true;
}
std::size_t Map::GetSize() const
{
return m_data.size();
}
void Map::Parse(Scanner *pScanner, const ParserState& state)
{
Clear();
// split based on start token
switch(pScanner->peek().type) {
case Token::BLOCK_MAP_START: ParseBlock(pScanner, state); break;
case Token::FLOW_MAP_START: ParseFlow(pScanner, state); break;
default: break;
}
}
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
{
// eat start token
pScanner->pop();
while(1) {
if(pScanner->empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
Token token = pScanner->peek();
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
if(token.type == Token::BLOCK_MAP_END) {
pScanner->pop();
break;
}
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
// grab key (if non-null)
if(token.type == Token::KEY) {
pScanner->pop();
pKey->Parse(pScanner, state);
}
// now grab value (optional)
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
pScanner->pop();
pValue->Parse(pScanner, state);
}
// assign the map with the actual pointers
m_data[pKey.release()] = pValue.release();
}
}
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
{
// eat start token
pScanner->pop();
while(1) {
if(pScanner->empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
Token& token = pScanner->peek();
// first check for end
if(token.type == Token::FLOW_MAP_END) {
pScanner->pop();
break;
}
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
// grab key (if non-null)
if(token.type == Token::KEY) {
pScanner->pop();
pKey->Parse(pScanner, state);
}
// now grab value (optional)
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
pScanner->pop();
pValue->Parse(pScanner, state);
}
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
Token& nextToken = pScanner->peek();
if(nextToken.type == Token::FLOW_ENTRY)
pScanner->pop();
else if(nextToken.type != Token::FLOW_MAP_END)
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
// assign the map with the actual pointers
m_data[pKey.release()] = pValue.release();
}
}
void Map::Write(Emitter& out) const
{
out << BeginMap;
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it)
out << Key << *it->first << Value << *it->second;
out << EndMap;
}
int Map::Compare(Content *pContent)
{
return -pContent->Compare(this);
}
int Map::Compare(Map *pMap)
{
node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin();
while(1) {
if(it == m_data.end()) {
if(jt == pMap->m_data.end())
return 0;
else
return -1;
}
if(jt == pMap->m_data.end())
return 1;
int cmp = it->first->Compare(*jt->first);
if(cmp != 0)
return cmp;
cmp = it->second->Compare(*jt->second);
if(cmp != 0)
return cmp;
}
return 0;
}
}

View File

@@ -1,50 +0,0 @@
#pragma once
#ifndef MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "content.h"
#include <map>
namespace YAML
{
class Node;
class Map: public Content
{
private:
typedef std::map <Node *, Node *, ltnode> node_map;
public:
Map();
Map(const node_map& data);
virtual ~Map();
void Clear();
virtual Content *Clone() const;
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
virtual std::size_t GetSize() const;
virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(Emitter& out) const;
virtual bool IsMap() const { return true; }
// ordering
virtual int Compare(Content *pContent);
virtual int Compare(Scalar *) { return 1; }
virtual int Compare(Sequence *) { return 1; }
virtual int Compare(Map *pMap);
private:
void ParseBlock(Scanner *pScanner, const ParserState& state);
void ParseFlow(Scanner *pScanner, const ParserState& state);
private:
node_map m_data;
};
}
#endif // MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

26
src/memory.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
#include "yaml-cpp/node/ptr.h"
namespace YAML {
namespace detail {
void memory_holder::merge(memory_holder& rhs) {
if (m_pMemory == rhs.m_pMemory)
return;
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());
}
}
}

View File

@@ -1,292 +1,12 @@
#include "crt.h"
#include "node.h"
#include "token.h"
#include "scanner.h"
#include "content.h"
#include "parser.h"
#include "scalar.h"
#include "sequence.h"
#include "map.h"
#include "aliascontent.h"
#include "iterpriv.h"
#include "emitter.h"
#include <stdexcept>
#include "yaml-cpp/node/node.h"
#include "nodebuilder.h"
#include "nodeevents.h"
namespace YAML
{
// the ordering!
bool ltnode::operator ()(const Node *pNode1, const Node *pNode2) const
{
return *pNode1 < *pNode2;
}
Node::Node(): m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(true)
{
}
Node::Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent)
: m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
{
if(m_pContent)
m_pContent = pContent->Clone();
}
Node::~Node()
{
Clear();
}
void Node::Clear()
{
delete m_pContent;
m_pContent = 0;
m_alias = false;
m_referenced = false;
m_anchor.clear();
m_tag.clear();
}
std::auto_ptr<Node> Node::Clone() const
{
if(m_alias)
throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases?
return std::auto_ptr<Node> (new Node(m_mark, m_anchor, m_tag, m_pContent));
}
void Node::Parse(Scanner *pScanner, const ParserState& state)
{
Clear();
// an empty node *is* a possibility
if(pScanner->empty())
return;
// save location
m_mark = pScanner->peek().mark;
ParseHeader(pScanner, state);
// is this an alias? if so, its contents are an alias to
// a previously defined anchor
if(m_alias) {
// the scanner throws an exception if it doesn't know this anchor name
const Node *pReferencedNode = pScanner->Retrieve(m_anchor);
m_pIdentity = pReferencedNode;
// mark the referenced node for the sake of the client code
pReferencedNode->m_referenced = true;
// use of an Alias object keeps the referenced content from
// being deleted twice
Content *pAliasedContent = pReferencedNode->m_pContent;
if(pAliasedContent)
m_pContent = new AliasContent(pAliasedContent);
return;
}
// now split based on what kind of node we should be
switch(pScanner->peek().type) {
case Token::SCALAR:
m_pContent = new Scalar;
break;
case Token::FLOW_SEQ_START:
case Token::BLOCK_SEQ_START:
m_pContent = new Sequence;
break;
case Token::FLOW_MAP_START:
case Token::BLOCK_MAP_START:
m_pContent = new Map;
break;
default:
// std::stringstream str;
// str << TokenNames[pScanner->peek().type];
// throw std::runtime_error(str.str());
break;
}
// Have to save anchor before parsing to allow for aliases as
// contained node (recursive structure)
if(!m_anchor.empty())
pScanner->Save(m_anchor, this);
if(m_pContent)
m_pContent->Parse(pScanner, state);
}
// ParseHeader
// . Grabs any tag, alias, or anchor tokens and deals with them.
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
{
while(1) {
if(pScanner->empty())
return;
switch(pScanner->peek().type) {
case Token::TAG: ParseTag(pScanner, state); break;
case Token::ANCHOR: ParseAnchor(pScanner, state); break;
case Token::ALIAS: ParseAlias(pScanner, state); break;
default: return;
}
}
}
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
{
Token& token = pScanner->peek();
if(m_tag != "")
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
m_tag = state.TranslateTag(token.value);
for(std::size_t i=0;i<token.params.size();i++)
m_tag += token.params[i];
pScanner->pop();
}
void Node::ParseAnchor(Scanner *pScanner, const ParserState& /*state*/)
{
Token& token = pScanner->peek();
if(m_anchor != "")
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
m_anchor = token.value;
m_alias = false;
pScanner->pop();
}
void Node::ParseAlias(Scanner *pScanner, const ParserState& /*state*/)
{
Token& token = pScanner->peek();
if(m_anchor != "")
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ALIASES);
if(m_tag != "")
throw ParserException(token.mark, ErrorMsg::ALIAS_CONTENT);
m_anchor = token.value;
m_alias = true;
pScanner->pop();
}
CONTENT_TYPE Node::GetType() const
{
if(!m_pContent)
return CT_NONE;
if(m_pContent->IsScalar())
return CT_SCALAR;
else if(m_pContent->IsSequence())
return CT_SEQUENCE;
else if(m_pContent->IsMap())
return CT_MAP;
return CT_NONE;
}
// begin
// Returns an iterator to the beginning of this (sequence or map).
Iterator Node::begin() const
{
if(!m_pContent)
return Iterator();
std::vector <Node *>::const_iterator seqIter;
if(m_pContent->GetBegin(seqIter))
return Iterator(new IterPriv(seqIter));
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
if(m_pContent->GetBegin(mapIter))
return Iterator(new IterPriv(mapIter));
return Iterator();
}
// end
// . Returns an iterator to the end of this (sequence or map).
Iterator Node::end() const
{
if(!m_pContent)
return Iterator();
std::vector <Node *>::const_iterator seqIter;
if(m_pContent->GetEnd(seqIter))
return Iterator(new IterPriv(seqIter));
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
if(m_pContent->GetEnd(mapIter))
return Iterator(new IterPriv(mapIter));
return Iterator();
}
// size
// . Returns the size of this node, if it's a sequence node.
// . Otherwise, returns zero.
std::size_t Node::size() const
{
if(!m_pContent)
return 0;
return m_pContent->GetSize();
}
const Node *Node::FindAtIndex(std::size_t i) const
{
if(!m_pContent)
return 0;
return m_pContent->GetNode(i);
}
bool Node::GetScalar(std::string& s) const
{
if(!m_pContent) {
s = "~";
return true;
}
return m_pContent->GetScalar(s);
}
Emitter& operator << (Emitter& out, const Node& node)
{
// write anchor/alias
if(node.m_anchor != "") {
if(node.m_alias)
out << Alias(node.m_anchor);
else
out << Anchor(node.m_anchor);
}
// TODO: write tag
// write content
if(node.m_pContent)
node.m_pContent->Write(out);
else if(!node.m_alias)
out << Null;
return out;
}
int Node::Compare(const Node& rhs) const
{
// Step 1: no content is the smallest
if(!m_pContent) {
if(rhs.m_pContent)
return -1;
else
return 0;
}
if(!rhs.m_pContent)
return 1;
return m_pContent->Compare(rhs.m_pContent);
}
bool operator < (const Node& n1, const Node& n2)
{
return n1.Compare(n2) < 0;
}
namespace YAML {
Node Clone(const Node& node) {
NodeEvents events(node);
NodeBuilder builder;
events.Emit(builder);
return builder.Root();
}
}

300
src/node_data.cpp Normal file
View File

@@ -0,0 +1,300 @@
#include <assert.h>
#include <iterator>
#include <sstream>
#include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
#include "yaml-cpp/node/detail/node_data.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
namespace YAML {
namespace detail {
std::string node_data::empty_scalar;
node_data::node_data()
: m_isDefined(false),
m_mark(Mark::null_mark()),
m_type(NodeType::Null),
m_style(EmitterStyle::Default),
m_seqSize(0) {}
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 {
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
kv_pairs::iterator 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 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 NULL;
}
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->is(key))
return it->second;
}
return NULL;
}
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.emplace_back(&key, &value);
if (!key.is_defined() || !value.is_defined())
m_undefinedPairs.emplace_back(&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;
}
}
}

130
src/nodebuilder.cpp Normal file
View File

@@ -0,0 +1,130 @@
#include <assert.h>
#include <cassert>
#include "nodebuilder.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/type.h"
namespace YAML {
struct Mark;
NodeBuilder::NodeBuilder()
: m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) {
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);
}
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.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);
}
}
}

70
src/nodebuilder.h Normal file
View File

@@ -0,0 +1,70 @@
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEBUILDER_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 <vector>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/node/ptr.h"
namespace YAML {
namespace detail {
class node;
} // namespace detail
struct Mark;
} // namespace YAML
namespace YAML {
class Node;
class NodeBuilder : public EventHandler {
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, EmitterStyle::value style);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd();
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;
typedef std::vector<detail::node*> Nodes;
Nodes m_stack;
Nodes m_anchors;
typedef std::pair<detail::node*, bool> PushedKey;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
}
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

101
src/nodeevents.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "nodeevents.h"
#include "yaml-cpp/eventhandler.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 {
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) {
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 (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());
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 (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, node.style());
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;
}
}

64
src/nodeevents.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEEVENTS_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 <map>
#include <vector>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/node/ptr.h"
namespace YAML {
namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
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;
};
}
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

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