Compare commits

..

194 Commits

Author SHA1 Message Date
Jesse Beder
562aefc114 Bump CMake version to 0.6.2.
It was incorrectly left at 0.6.0 when 0.6.1 was released, so this needs to be done to make it consistent between the tagged version and the CMake version.
2018-03-05 22:56:23 -06:00
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
466 changed files with 180031 additions and 26426 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/

4
.hgeol
View File

@@ -1,4 +0,0 @@
**.h = native
**.c = native
**.cpp = native
**.txt = native

View File

@@ -1 +0,0 @@
syntax: glob

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

@@ -12,6 +12,11 @@ endif()
if(POLICY CMP0015) if(POLICY CMP0015)
cmake_policy(SET CMP0015 OLD) cmake_policy(SET CMP0015 OLD)
endif() 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()
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
@@ -22,8 +27,8 @@ include(CheckCXXCompilerFlag)
project(YAML_CPP) project(YAML_CPP)
set(YAML_CPP_VERSION_MAJOR "0") set(YAML_CPP_VERSION_MAJOR "0")
set(YAML_CPP_VERSION_MINOR "5") set(YAML_CPP_VERSION_MINOR "6")
set(YAML_CPP_VERSION_PATCH "1") set(YAML_CPP_VERSION_PATCH "2")
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}") set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
enable_testing() enable_testing()
@@ -33,7 +38,8 @@ enable_testing()
### Project options ### Project options
### ###
## Project stuff ## Project stuff
option(YAML_CPP_BUILD_TOOLS "Enable testing and parse tools" ON) 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) option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
## Build options ## Build options
@@ -54,6 +60,29 @@ option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (
### ###
### Sources, headers, directories and libs ### 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/") set(header_directory "include/yaml-cpp/")
file(GLOB sources "src/[a-zA-Z]*.cpp") file(GLOB sources "src/[a-zA-Z]*.cpp")
@@ -68,6 +97,16 @@ else()
add_definitions(-DYAML_CPP_NO_CONTRIB) add_definitions(-DYAML_CPP_NO_CONTRIB)
endif() endif()
set(library_sources
${sources}
${public_headers}
${private_headers}
${contrib_sources}
${contrib_public_headers}
${contrib_private_headers}
)
add_sources(${library_sources})
if(VERBOSE) if(VERBOSE)
message(STATUS "sources: ${sources}") message(STATUS "sources: ${sources}")
message(STATUS "public_headers: ${public_headers}") message(STATUS "public_headers: ${public_headers}")
@@ -80,13 +119,14 @@ endif()
include_directories(${YAML_CPP_SOURCE_DIR}/src) include_directories(${YAML_CPP_SOURCE_DIR}/src)
include_directories(${YAML_CPP_SOURCE_DIR}/include) include_directories(${YAML_CPP_SOURCE_DIR}/include)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
### ###
### General compilation settings ### General compilation settings
### ###
set(yaml_c_flags ${CMAKE_C_FLAGS})
set(yaml_cxx_flags ${CMAKE_CXX_FLAGS})
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
set(LABEL_SUFFIX "shared") set(LABEL_SUFFIX "shared")
else() else()
@@ -113,8 +153,11 @@ if(WIN32)
endif() endif()
endif() endif()
# GCC specialities # GCC or Clang or Intel Compiler specialities
if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID MATCHES "Intel")
### General stuff ### General stuff
if(WIN32) if(WIN32)
set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix
@@ -134,14 +177,20 @@ if(CMAKE_COMPILER_IS_GNUCXX)
# #
set(GCC_EXTRA_OPTIONS "") set(GCC_EXTRA_OPTIONS "")
# #
if(BUILD_SHARED_LIBS)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
endif()
#
set(FLAG_TESTED "-Wextra") set(FLAG_TESTED "-Wextra")
check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA) check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
if(FLAG_WEXTRA) if(FLAG_WEXTRA)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}") set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
endif() endif()
# #
set(CMAKE_CXX_FLAGS "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}") 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 add_custom_target(debuggable $(MAKE) clean
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR}
COMMENT "Adjusting settings for debug compilation" COMMENT "Adjusting settings for debug compilation"
@@ -150,6 +199,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
COMMENT "Adjusting settings for release compilation" COMMENT "Adjusting settings for release compilation"
VERBATIM) VERBATIM)
endif()
endif() endif()
# Microsoft VisualC++ specialities # Microsoft VisualC++ specialities
@@ -182,6 +232,7 @@ if(MSVC)
set(var_name "${var_name}_${config_name}") set(var_name "${var_name}_${config_name}")
endif() endif()
string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}") string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}")
set(${var_name} "${${var_name}}" CACHE STRING "" FORCE)
endforeach() endforeach()
endforeach() endforeach()
endif() endif()
@@ -201,41 +252,31 @@ if(MSVC)
# /W3 = set warning level; see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx # /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 # /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 # /wd4355 = disable warning C4355 "'this' : used in base member initializer list"; http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
set(CMAKE_CXX_FLAGS "/W3 /wd4127 /wd4355 /D_SCL_SECURE_NO_WARNINGS ${CMAKE_CXX_FLAGS}") set(yaml_cxx_flags "/W3 /wd4127 /wd4355 ${yaml_cxx_flags}")
endif() endif()
### ###
### General install settings ### General install settings
### ###
if(WIN32)
set(_library_dir bin) # .dll are in PATH, like executables
else()
set(_library_dir lib)
endif()
set(INCLUDE_INSTALL_ROOT_DIR include) set(INCLUDE_INSTALL_ROOT_DIR include)
set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
set(LIB_INSTALL_DIR "${_library_dir}${LIB_SUFFIX}") set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
set(_INSTALL_DESTINATIONS set(_INSTALL_DESTINATIONS
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
LIBRARY DESTINATION ${LIB_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
) )
### ###
### Library ### Library
### ###
add_library(yaml-cpp add_library(yaml-cpp ${library_sources})
${sources} set_target_properties(yaml-cpp PROPERTIES
${public_headers} COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}"
${private_headers}
${contrib_sources}
${contrib_public_headers}
${contrib_private_headers}
) )
set_target_properties(yaml-cpp PROPERTIES set_target_properties(yaml-cpp PROPERTIES
@@ -262,13 +303,43 @@ if(MSVC)
endif() endif()
endif() endif()
install(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS}) install(TARGETS yaml-cpp EXPORT yaml-cpp-targets ${_INSTALL_DESTINATIONS})
install( install(
DIRECTORY ${header_directory} DIRECTORY ${header_directory}
DESTINATION ${INCLUDE_INSTALL_DIR} DESTINATION ${INCLUDE_INSTALL_DIR}
FILES_MATCHING PATTERN "*.h" 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) if(UNIX)
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc) set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY) configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
@@ -279,7 +350,16 @@ endif()
### ###
### Extras ### Extras
### ###
if(YAML_CPP_BUILD_TOOLS) if(YAML_CPP_BUILD_TESTS)
add_subdirectory(test) add_subdirectory(test)
endif()
if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util) add_subdirectory(util)
endif() 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,4 +1,4 @@
Copyright (c) 2008 Jesse Beder. Copyright (c) 2008-2015 Jesse Beder.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

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,16 +1,17 @@
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ typedef std::size_t anchor_t;
typedef std::size_t anchor_t; const anchor_t NullAnchor = 0;
const anchor_t NullAnchor = 0;
} }
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,33 +1,40 @@
#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/dll.h"
{
std::string EncodeBase64(const unsigned char *data, std::size_t size);
std::vector<unsigned char> DecodeBase64(const std::string& input);
class Binary { 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: public:
Binary(): m_unownedData(0), m_unownedSize(0) {} Binary() : m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_): m_unownedData(data_), m_unownedSize(size_) {} Binary(const unsigned char *data_, std::size_t size_)
: m_unownedData(data_), m_unownedSize(size_) {}
bool owned() const { return !m_unownedData; } bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
const unsigned char *data() const { return owned() ? &m_data[0] : m_unownedData; } const unsigned char *data() const {
return owned() ? &m_data[0] : m_unownedData;
}
void swap(std::vector<unsigned char>& rhs) { void swap(std::vector<unsigned char> &rhs) {
if(m_unownedData) { if (m_unownedData) {
m_data.swap(rhs); m_data.swap(rhs);
rhs.clear(); rhs.clear();
rhs.resize(m_unownedSize); rhs.resize(m_unownedSize);
std::copy(m_unownedData, m_unownedData + m_unownedSize, &rhs[0]); std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
m_unownedData = 0; m_unownedData = 0;
m_unownedSize = 0; m_unownedSize = 0;
} else { } else {
@@ -35,28 +42,26 @@ namespace YAML
} }
} }
bool operator == (const Binary& rhs) const { bool operator==(const Binary &rhs) const {
const std::size_t s = size(); const std::size_t s = size();
if(s != rhs.size()) if (s != rhs.size())
return false; return false;
const unsigned char *d1 = data(); const unsigned char *d1 = data();
const unsigned char *d2 = rhs.data(); const unsigned char *d2 = rhs.data();
for(std::size_t i=0;i<s;i++) { for (std::size_t i = 0; i < s; i++) {
if(*d1++ != *d2++) if (*d1++ != *d2++)
return false; return false;
} }
return true; return true;
} }
bool operator != (const Binary& rhs) const { bool operator!=(const Binary &rhs) const { return !(*this == rhs); }
return !(*this == rhs);
}
private: private:
std::vector<unsigned char> m_data; std::vector<unsigned char> m_data;
const unsigned char *m_unownedData; const unsigned char *m_unownedData;
std::size_t m_unownedSize; std::size_t m_unownedSize;
}; };
} }
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,7 +1,9 @@
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -9,34 +11,29 @@
#include "../anchor.h" #include "../anchor.h"
namespace YAML namespace YAML {
{ /**
/// AnchorDict * An object that stores and retrieves values correlating to {@link anchor_t}
/// . An object that stores and retrieves values correlating to anchor_t * values.
/// values. *
/// . Efficient implementation that can make assumptions about how anchor_t * <p>Efficient implementation that can make assumptions about how
/// values are assigned by the Parser class. * {@code anchor_t} values are assigned by the {@link Parser} class.
template <class T> */
class AnchorDict template <class T>
{ class AnchorDict {
public: public:
void Register(anchor_t anchor, T value) void Register(anchor_t anchor, T value) {
{ if (anchor > m_data.size()) {
if (anchor > m_data.size())
{
m_data.resize(anchor); m_data.resize(anchor);
} }
m_data[anchor - 1] = value; m_data[anchor - 1] = value;
} }
T Get(anchor_t anchor) const T Get(anchor_t anchor) const { return m_data[anchor - 1]; }
{
return m_data[anchor - 1];
}
private: private:
std::vector<T> m_data; std::vector<T> m_data;
}; };
} }
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,89 +1,103 @@
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Parser;
class Parser;
// GraphBuilderInterface // GraphBuilderInterface
// . Abstraction of node creation // . Abstraction of node creation
// . pParentNode is always NULL or the return value of one of the NewXXX() // . pParentNode is always NULL or the return value of one of the NewXXX()
// functions. // functions.
class GraphBuilderInterface class GraphBuilderInterface {
{
public: public:
virtual ~GraphBuilderInterface() = 0;
// Create and return a new node with a null value. // Create and return a new node with a null value.
virtual void *NewNull(const Mark& mark, void *pParentNode) = 0; virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
// Create and return a new node with the given tag and value. // Create and return a new node with the given tag and value.
virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0; virtual void *NewScalar(const Mark &mark, const std::string &tag,
void *pParentNode, const std::string &value) = 0;
// Create and return a new sequence node // Create and return a new sequence node
virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0; virtual void *NewSequence(const Mark &mark, const std::string &tag,
void *pParentNode) = 0;
// Add pNode to pSequence. pNode was created with one of the NewXxx() // Add pNode to pSequence. pNode was created with one of the NewXxx()
// functions and pSequence with NewSequence(). // functions and pSequence with NewSequence().
virtual void AppendToSequence(void *pSequence, void *pNode) = 0; virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
// Note that no moew entries will be added to pSequence // Note that no moew entries will be added to pSequence
virtual void SequenceComplete(void *pSequence) {(void)pSequence;} virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
// Create and return a new map node // Create and return a new map node
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0; virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) = 0;
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
// were created with one of the NewXxx() methods and pMap with NewMap(). // were created with one of the NewXxx() methods and pMap with NewMap().
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
// Note that no more assignments will be made in pMap // Note that no more assignments will be made in pMap
virtual void MapComplete(void *pMap) {(void)pMap;} virtual void MapComplete(void *pMap) { (void)pMap; }
// Return the node that should be used in place of an alias referencing // Return the node that should be used in place of an alias referencing
// pNode (pNode by default) // pNode (pNode by default)
virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;} virtual void *AnchorReference(const Mark &mark, void *pNode) {
}; (void)mark;
return pNode;
}
};
// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
// Node, Sequence, and Map types. Sequence and Map must derive from Node // Node, Sequence, and Map types. Sequence and Map must derive from Node
// (unless Node is defined as void). Impl must also implement function with // (unless Node is defined as void). Impl must also implement function with
// all of the same names as the virtual functions in GraphBuilderInterface // all of the same names as the virtual functions in GraphBuilderInterface
// -- including the ones with default implementations -- but with the // -- including the ones with default implementations -- but with the
// prototypes changed to accept an explicit Node*, Sequence*, or Map* where // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
// appropriate. // appropriate.
template <class Impl> template <class Impl>
class GraphBuilder : public GraphBuilderInterface class GraphBuilder : public GraphBuilderInterface {
{
public: public:
typedef typename Impl::Node Node; typedef typename Impl::Node Node;
typedef typename Impl::Sequence Sequence; typedef typename Impl::Sequence Sequence;
typedef typename Impl::Map Map; typedef typename Impl::Map Map;
GraphBuilder(Impl& impl) : m_impl(impl) GraphBuilder(Impl &impl) : m_impl(impl) {
{ Map *pMap = NULL;
Map* pMap = NULL; Sequence *pSeq = NULL;
Sequence* pSeq = NULL; Node *pNode = NULL;
Node* pNode = NULL;
// Type consistency checks // Type consistency checks
pNode = pMap; pNode = pMap;
pNode = pSeq; pNode = pSeq;
} }
GraphBuilderInterface& AsBuilderInterface() {return *this;} GraphBuilderInterface &AsBuilderInterface() { return *this; }
virtual void *NewNull(const Mark& mark, void* pParentNode) { virtual void *NewNull(const Mark &mark, void *pParentNode) {
return CheckType<Node>(m_impl.NewNull(mark, AsNode(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) { virtual void *NewScalar(const Mark &mark, const std::string &tag,
return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); 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) { virtual void *NewSequence(const Mark &mark, const std::string &tag,
return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode))); void *pParentNode) {
return CheckType<Sequence>(
m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
} }
virtual void AppendToSequence(void *pSequence, void *pNode) { virtual void AppendToSequence(void *pSequence, void *pNode) {
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
@@ -92,42 +106,44 @@ namespace YAML
m_impl.SequenceComplete(AsSequence(pSequence)); m_impl.SequenceComplete(AsSequence(pSequence));
} }
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) { virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) {
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode))); return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
} }
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
} }
virtual void MapComplete(void *pMap) { virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
m_impl.MapComplete(AsMap(pMap));
}
virtual void *AnchorReference(const Mark& mark, void *pNode) { virtual void *AnchorReference(const Mark &mark, void *pNode) {
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode))); return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
} }
private: private:
Impl& m_impl; Impl &m_impl;
// Static check for pointer to T // Static check for pointer to T
template <class T, class U> template <class T, class U>
static T* CheckType(U* p) {return p;} 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
));
} }
static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
static Sequence *AsSequence(void *pSeq) {
return static_cast<Sequence *>(pSeq);
}
static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
};
void *BuildGraphOfNextDocument(Parser &parser,
GraphBuilderInterface &graphBuilder);
template <class Impl>
typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
GraphBuilder<Impl> graphBuilder(impl);
return static_cast<typename Impl::Node *>(
BuildGraphOfNextDocument(parser, graphBuilder));
}
} }
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

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

View File

@@ -1,19 +1,26 @@
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/eventhandler.h"
#include <stack> #include <stack>
namespace YAML #include "yaml-cpp/anchor.h"
{ #include "yaml-cpp/emitterstyle.h"
class Emitter; #include "yaml-cpp/eventhandler.h"
class EmitFromEvents: public EventHandler namespace YAML {
{ struct Mark;
} // namespace YAML
namespace YAML {
class Emitter;
class EmitFromEvents : public EventHandler {
public: public:
EmitFromEvents(Emitter& emitter); EmitFromEvents(Emitter& emitter);
@@ -22,12 +29,15 @@ namespace YAML
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(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 OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd(); virtual void OnMapEnd();
private: private:
@@ -37,9 +47,11 @@ namespace YAML
private: private:
Emitter& m_emitter; Emitter& m_emitter;
struct State { enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; }; struct State {
std::stack<State::value> m_stateStack; enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue };
}; };
std::stack<State::value> m_stateStack;
};
} }
#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,35 +1,41 @@
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef>
#include <memory>
#include <sstream>
#include <string>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h" #include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
#include <memory>
#include <string>
#include <sstream>
namespace YAML namespace YAML {
{ class Binary;
class EmitterState; struct _Null;
} // namespace YAML
class YAML_CPP_API Emitter: private noncopyable namespace YAML {
{ class EmitterState;
class YAML_CPP_API Emitter : private noncopyable {
public: public:
Emitter(); Emitter();
explicit Emitter(std::ostream& stream); explicit Emitter(std::ostream& stream);
~Emitter(); ~Emitter();
// output // output
const char *c_str() const; const char* c_str() const;
std::size_t size() const; std::size_t size() const;
// state checking // state checking
@@ -43,11 +49,11 @@ namespace YAML
bool SetIntBase(EMITTER_MANIP value); bool SetIntBase(EMITTER_MANIP value);
bool SetSeqFormat(EMITTER_MANIP value); bool SetSeqFormat(EMITTER_MANIP value);
bool SetMapFormat(EMITTER_MANIP value); bool SetMapFormat(EMITTER_MANIP value);
bool SetIndent(unsigned n); bool SetIndent(std::size_t n);
bool SetPreCommentIndent(unsigned n); bool SetPreCommentIndent(std::size_t n);
bool SetPostCommentIndent(unsigned n); bool SetPostCommentIndent(std::size_t n);
bool SetFloatPrecision(unsigned n); bool SetFloatPrecision(std::size_t n);
bool SetDoublePrecision(unsigned n); bool SetDoublePrecision(std::size_t n);
// local setters // local setters
Emitter& SetLocalValue(EMITTER_MANIP value); Emitter& SetLocalValue(EMITTER_MANIP value);
@@ -72,9 +78,10 @@ namespace YAML
Emitter& WriteStreamable(T value); Emitter& WriteStreamable(T value);
private: private:
template<typename T> void SetStreamablePrecision(std::stringstream&) {} template <typename T>
unsigned GetFloatPrecision() const; void SetStreamablePrecision(std::stringstream&) {}
unsigned GetDoublePrecision() const; std::size_t GetFloatPrecision() const;
std::size_t GetDoublePrecision() const;
void PrepareIntegralStream(std::stringstream& stream) const; void PrepareIntegralStream(std::stringstream& stream) const;
void StartedScalar(); void StartedScalar();
@@ -109,20 +116,19 @@ namespace YAML
void BlockMapPrepareSimpleKey(EmitterNodeType::value child); void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
void SpaceOrIndentTo(bool requireSpace, unsigned indent); void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
const char *ComputeFullBoolName(bool b) const; const char* ComputeFullBoolName(bool b) const;
bool CanEmitNewline() const; bool CanEmitNewline() const;
private: private:
std::auto_ptr<EmitterState> m_pState; std::unique_ptr<EmitterState> m_pState;
ostream_wrapper m_stream; ostream_wrapper m_stream;
}; };
template <typename T> template <typename T>
inline Emitter& Emitter::WriteIntegralType(T value) inline Emitter& Emitter::WriteIntegralType(T value) {
{ if (!good())
if(!good())
return *this; return *this;
PrepareNode(EmitterNodeType::Scalar); PrepareNode(EmitterNodeType::Scalar);
@@ -135,12 +141,11 @@ namespace YAML
StartedScalar(); StartedScalar();
return *this; return *this;
} }
template <typename T> template <typename T>
inline Emitter& Emitter::WriteStreamable(T value) inline Emitter& Emitter::WriteStreamable(T value) {
{ if (!good())
if(!good())
return *this; return *this;
PrepareNode(EmitterNodeType::Scalar); PrepareNode(EmitterNodeType::Scalar);
@@ -153,57 +158,97 @@ namespace YAML
StartedScalar(); StartedScalar();
return *this; return *this;
} }
template<> template <>
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
{ stream.precision(static_cast<std::streamsize>(GetFloatPrecision()));
stream.precision(GetFloatPrecision()); }
}
template<> template <>
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
{ stream.precision(static_cast<std::streamsize>(GetDoublePrecision()));
stream.precision(GetDoublePrecision()); }
}
// overloads of insertion // overloads of insertion
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); } inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(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, bool v) {
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(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, char v) {
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(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, 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, 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, int v) {
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(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, unsigned int v) {
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(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, short v) {
inline Emitter& operator << (Emitter& emitter, unsigned long long v) { return emitter.WriteIntegralType(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, float v) {
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); } return emitter.WriteStreamable(v);
}
inline Emitter& operator<<(Emitter& emitter, double v) {
return emitter.WriteStreamable(v);
}
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) { inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
return emitter.SetLocalValue(value); return emitter.SetLocalValue(value);
} }
inline Emitter& operator << (Emitter& emitter, _Indent indent) { inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent); return emitter.SetLocalIndent(indent);
} }
inline Emitter& operator << (Emitter& emitter, _Precision precision) { inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision); return emitter.SetLocalPrecision(precision);
} }
} }
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,13 +1,16 @@
#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define 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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML namespace YAML {
{ struct EmitterNodeType {
struct EmitterNodeType { enum value { None, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; }; enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap };
};
} }
#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,16 +1,16 @@
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
namespace YAML namespace YAML {
{ enum EMITTER_MANIP {
enum EMITTER_MANIP {
// general manipulators // general manipulators
Auto, Auto,
TagByKind, TagByKind,
@@ -60,90 +60,78 @@ namespace YAML
// Block, // duplicate // Block, // duplicate
// Auto, // duplicate // Auto, // duplicate
LongKey LongKey
}; };
struct _Indent { struct _Indent {
_Indent(int value_): value(value_) {} _Indent(int value_) : value(value_) {}
int value; int value;
}; };
inline _Indent Indent(int value) { inline _Indent Indent(int value) { return _Indent(value); }
return _Indent(value);
}
struct _Alias { struct _Alias {
_Alias(const std::string& content_): content(content_) {} _Alias(const std::string& content_) : content(content_) {}
std::string content; std::string content;
}; };
inline _Alias Alias(const std::string content) { inline _Alias Alias(const std::string content) { return _Alias(content); }
return _Alias(content);
}
struct _Anchor { struct _Anchor {
_Anchor(const std::string& content_): content(content_) {} _Anchor(const std::string& content_) : content(content_) {}
std::string content; std::string content;
};
inline _Anchor Anchor(const std::string content) { return _Anchor(content); }
struct _Tag {
struct Type {
enum value { Verbatim, PrimaryHandle, NamedHandle };
}; };
inline _Anchor Anchor(const std::string content) { explicit _Tag(const std::string& prefix_, const std::string& content_,
return _Anchor(content); Type::value type_)
} : prefix(prefix_), content(content_), type(type_) {}
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 prefix;
std::string content; std::string content;
Type::value type; Type::value type;
}; };
inline _Tag VerbatimTag(const std::string content) { inline _Tag VerbatimTag(const std::string content) {
return _Tag("", content, _Tag::Type::Verbatim); return _Tag("", content, _Tag::Type::Verbatim);
} }
inline _Tag LocalTag(const std::string content) { inline _Tag LocalTag(const std::string content) {
return _Tag("", content, _Tag::Type::PrimaryHandle); return _Tag("", content, _Tag::Type::PrimaryHandle);
} }
inline _Tag LocalTag(const std::string& prefix, const std::string content) { inline _Tag LocalTag(const std::string& prefix, const std::string content) {
return _Tag(prefix, content, _Tag::Type::NamedHandle); return _Tag(prefix, content, _Tag::Type::NamedHandle);
} }
inline _Tag SecondaryTag(const std::string content) { inline _Tag SecondaryTag(const std::string content) {
return _Tag("", content, _Tag::Type::NamedHandle); return _Tag("", content, _Tag::Type::NamedHandle);
} }
struct _Comment { struct _Comment {
_Comment(const std::string& content_): content(content_) {} _Comment(const std::string& content_) : content(content_) {}
std::string content; std::string content;
}; };
inline _Comment Comment(const std::string content) { inline _Comment Comment(const std::string content) { return _Comment(content); }
return _Comment(content);
}
struct _Precision { struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_): floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} _Precision(int floatPrecision_, int doublePrecision_)
: floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
int floatPrecision; int floatPrecision;
int doublePrecision; int doublePrecision;
}; };
inline _Precision FloatPrecision(int n) { inline _Precision FloatPrecision(int n) { return _Precision(n, -1); }
return _Precision(n, -1);
}
inline _Precision DoublePrecision(int n) { inline _Precision DoublePrecision(int n) { return _Precision(-1, n); }
return _Precision(-1, n);
}
inline _Precision Precision(int n) { inline _Precision Precision(int n) { return _Precision(n, n); }
return _Precision(n, n);
}
} }
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #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

@@ -1,19 +1,21 @@
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h"
#include <string> #include <string>
namespace YAML #include "yaml-cpp/anchor.h"
{ #include "yaml-cpp/emitterstyle.h"
struct Mark;
class EventHandler namespace YAML {
{ struct Mark;
class EventHandler {
public: public:
virtual ~EventHandler() {} virtual ~EventHandler() {}
@@ -22,15 +24,17 @@ namespace YAML
virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
virtual void OnAlias(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 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) = 0; virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnSequenceEnd() = 0; virtual void OnSequenceEnd() = 0;
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0; virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnMapEnd() = 0; virtual void OnMapEnd() = 0;
}; };
} }
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,208 +1,267 @@
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/traits.h" #include "yaml-cpp/traits.h"
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <sstream>
namespace YAML // This is here for compatibility with older versions of Visual Studio
{ // which don't support noexcept
// error messages #ifdef _MSC_VER
namespace ErrorMsg #define YAML_CPP_NOEXCEPT _NOEXCEPT
{ #else
const char * const YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument"; #define YAML_CPP_NOEXCEPT noexcept
const char * const YAML_VERSION = "bad YAML version: "; #endif
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"; namespace YAML {
const char * const INVALID_SCALAR = "invalid scalar"; // error messages
const char * const KEY_NOT_FOUND = "key not found"; namespace ErrorMsg {
const char * const BAD_CONVERSION = "bad conversion"; const char* const YAML_DIRECTIVE_ARGS =
const char * const BAD_DEREFERENCE = "bad dereference"; "YAML directives must have exactly one argument";
const char * const BAD_SUBSCRIPT = "operator[] call on a scalar"; const char* const YAML_VERSION = "bad YAML version: ";
const char * const BAD_PUSHBACK = "appending to a non-sequence"; const char* const YAML_MAJOR_VERSION = "YAML major version too large";
const char * const BAD_INSERT = "inserting in a non-convertible-to-map"; 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 UNMATCHED_GROUP_TAG = "unmatched group tag"; const char* const INVALID_NODE =
const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token"; "invalid node; this may result from using a map iterator as a sequence "
const char * const UNEXPECTED_END_MAP = "unexpected end map token"; "iterator, or vice-versa";
const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string"; const char* const INVALID_SCALAR = "invalid scalar";
const char * const INVALID_ANCHOR = "invalid anchor"; const char* const KEY_NOT_FOUND = "key not found";
const char * const INVALID_ALIAS = "invalid alias"; const char* const BAD_CONVERSION = "bad conversion";
const char * const INVALID_TAG = "invalid tag"; const char* const BAD_DEREFERENCE = "bad dereference";
const char * const BAD_FILE = "bad file"; 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";
template <typename T> const char* const UNMATCHED_GROUP_TAG = "unmatched group tag";
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) { 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; return KEY_NOT_FOUND;
} }
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
std::stringstream stream; std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key; stream << KEY_NOT_FOUND << ": " << key;
return stream.str(); return stream.str();
} }
template <typename T> template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) { inline const std::string KEY_NOT_FOUND_WITH_KEY(
const T& key, typename enable_if<is_numeric<T>>::type* = 0) {
std::stringstream stream; std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key; stream << KEY_NOT_FOUND << ": " << key;
return stream.str(); return stream.str();
} }
} }
class Exception: public std::runtime_error { class YAML_CPP_API Exception : public std::runtime_error {
public: public:
Exception(const Mark& mark_, const std::string& msg_) Exception(const Mark& mark_, const std::string& msg_)
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
virtual ~Exception() throw() {} virtual ~Exception() YAML_CPP_NOEXCEPT;
Exception(const Exception&) = default;
Mark mark; Mark mark;
std::string msg; std::string msg;
private: private:
static const std::string build_what(const Mark& mark, const std::string& msg) { static const std::string build_what(const Mark& mark,
const std::string& msg) {
if (mark.is_null()) {
return msg.c_str();
}
std::stringstream output; std::stringstream output;
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg; output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
<< mark.column + 1 << ": " << msg;
return output.str(); return output.str();
} }
}; };
class ParserException: public Exception { class YAML_CPP_API ParserException : public Exception {
public: public:
ParserException(const Mark& mark_, const std::string& msg_) ParserException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {} : Exception(mark_, msg_) {}
}; ParserException(const ParserException&) = default;
virtual ~ParserException() YAML_CPP_NOEXCEPT;
};
class RepresentationException: public Exception { class YAML_CPP_API RepresentationException : public Exception {
public: public:
RepresentationException(const Mark& mark_, const std::string& msg_) RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {} : Exception(mark_, msg_) {}
}; RepresentationException(const RepresentationException&) = default;
virtual ~RepresentationException() YAML_CPP_NOEXCEPT;
};
// representation exceptions // representation exceptions
class InvalidScalar: public RepresentationException { class YAML_CPP_API InvalidScalar : public RepresentationException {
public: public:
InvalidScalar(const Mark& mark_) InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
}; InvalidScalar(const InvalidScalar&) = default;
virtual ~InvalidScalar() YAML_CPP_NOEXCEPT;
};
class KeyNotFound: public RepresentationException { class YAML_CPP_API KeyNotFound : public RepresentationException {
public: public:
template <typename T> template <typename T>
KeyNotFound(const Mark& mark_, const T& key_) KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {} : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
}; }
KeyNotFound(const KeyNotFound&) = default;
virtual ~KeyNotFound() YAML_CPP_NOEXCEPT;
};
template <typename T> template <typename T>
class TypedKeyNotFound: public KeyNotFound { class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
public: public:
TypedKeyNotFound(const Mark& mark_, const T& key_) TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {} : KeyNotFound(mark_, key_), key(key_) {}
virtual ~TypedKeyNotFound() throw() {} virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {}
T key; T key;
}; };
template <typename T> template <typename T>
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) { inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
return TypedKeyNotFound <T> (mark, key); const T& key) {
} return TypedKeyNotFound<T>(mark, key);
}
class InvalidNode: public RepresentationException { class YAML_CPP_API InvalidNode : public RepresentationException {
public: public:
InvalidNode() InvalidNode()
: RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
}; InvalidNode(const InvalidNode&) = default;
virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
};
class BadConversion: public RepresentationException { class YAML_CPP_API BadConversion : public RepresentationException {
public: public:
BadConversion() explicit BadConversion(const Mark& mark_)
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {} : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
}; BadConversion(const BadConversion&) = default;
virtual ~BadConversion() YAML_CPP_NOEXCEPT;
};
template<typename T> template <typename T>
class TypedBadConversion: public BadConversion { class TypedBadConversion : public BadConversion {
public: public:
TypedBadConversion() explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {}
: BadConversion() {} };
};
class BadDereference: public RepresentationException { class YAML_CPP_API BadDereference : public RepresentationException {
public: public:
BadDereference() BadDereference()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
}; BadDereference(const BadDereference&) = default;
virtual ~BadDereference() YAML_CPP_NOEXCEPT;
};
class BadSubscript: public RepresentationException { class YAML_CPP_API BadSubscript : public RepresentationException {
public: public:
BadSubscript() BadSubscript()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
}; BadSubscript(const BadSubscript&) = default;
virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
};
class BadPushback: public RepresentationException { class YAML_CPP_API BadPushback : public RepresentationException {
public: public:
BadPushback() BadPushback()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
}; BadPushback(const BadPushback&) = default;
virtual ~BadPushback() YAML_CPP_NOEXCEPT;
};
class BadInsert: public RepresentationException { class YAML_CPP_API BadInsert : public RepresentationException {
public: public:
BadInsert() BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
}; BadInsert(const BadInsert&) = default;
virtual ~BadInsert() YAML_CPP_NOEXCEPT;
};
class EmitterException: public Exception { class YAML_CPP_API EmitterException : public Exception {
public: public:
EmitterException(const std::string& msg_) EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {} : Exception(Mark::null_mark(), msg_) {}
}; EmitterException(const EmitterException&) = default;
virtual ~EmitterException() YAML_CPP_NOEXCEPT;
};
class BadFile: public Exception { class YAML_CPP_API BadFile : public Exception {
public: public:
BadFile(): Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {} 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 #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,26 +1,29 @@
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML namespace YAML {
{ struct YAML_CPP_API Mark {
struct YAML_CPP_API Mark { Mark() : pos(0), line(0), column(0) {}
Mark(): pos(0), line(0), column(0) {}
static const Mark null_mark() { return Mark(-1, -1, -1); } static const Mark null_mark() { return Mark(-1, -1, -1); }
bool is_null() const { return pos == -1 && line == -1 && column == -1; }
int pos; int pos;
int line, column; int line, column;
private: private:
Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {} Mark(int pos_, int line_, int column_)
}; : pos(pos_), line(line_), column(column_) {}
};
} }
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,232 +1,283 @@
#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <array>
#include "yaml-cpp/binary.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/null.h"
#include <limits> #include <limits>
#include <list> #include <list>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/binary.h"
{ #include "yaml-cpp/node/impl.h"
namespace conversion { #include "yaml-cpp/node/iterator.h"
inline bool IsInfinity(const std::string& input) { #include "yaml-cpp/node/node.h"
return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF"; #include "yaml-cpp/node/type.h"
} #include "yaml-cpp/null.h"
inline bool IsNegativeInfinity(const std::string& input) { 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"; return input == "-.inf" || input == "-.Inf" || input == "-.INF";
} }
inline bool IsNaN(const std::string& input) { inline bool IsNaN(const std::string& input) {
return input == ".nan" || input == ".NaN" || input == ".NAN"; return input == ".nan" || input == ".NaN" || input == ".NAN";
} }
} }
// std::string // Node
template<> template <>
struct convert<std::string> { struct convert<Node> {
static Node encode(const std::string& rhs) { static Node encode(const Node& rhs) { return rhs; }
return Node(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) { static bool decode(const Node& node, std::string& rhs) {
if(!node.IsScalar()) if (!node.IsScalar())
return false; return false;
rhs = node.Scalar(); rhs = node.Scalar();
return true; return true;
} }
}; };
// C-strings can only be encoded // C-strings can only be encoded
template<> template <>
struct convert<const char *> { struct convert<const char*> {
static Node encode(const char *&rhs) { static Node encode(const char*& rhs) { return Node(rhs); }
return Node(rhs); };
}
};
template<std::size_t N> template <std::size_t N>
struct convert<const char[N]> { struct convert<const char[N]> {
static Node encode(const char (&rhs)[N]) { static Node encode(const char(&rhs)[N]) { return Node(rhs); }
return Node(rhs); };
}
};
template<> template <>
struct convert<_Null> { struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { static Node encode(const _Null& /* rhs */) { return Node(); }
return Node();
}
static bool decode(const Node& node, _Null& /* rhs */) { static bool decode(const Node& node, _Null& /* rhs */) {
return node.IsNull(); return node.IsNull();
} }
}; };
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)\ #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
template<>\ template <> \
struct convert<type> {\ struct convert<type> { \
static Node encode(const type& rhs) {\ static Node encode(const type& rhs) { \
std::stringstream stream;\ std::stringstream stream; \
stream.precision(std::numeric_limits<type>::digits10 + 1);\ stream.precision(std::numeric_limits<type>::digits10 + 1); \
stream << rhs;\ stream << rhs; \
return Node(stream.str());\ return Node(stream.str()); \
}\ } \
\ \
static bool decode(const Node& node, type& rhs) {\ static bool decode(const Node& node, type& rhs) { \
if(node.Type() != NodeType::Scalar)\ if (node.Type() != NodeType::Scalar) \
return false;\ return false; \
const std::string& input = node.Scalar();\ const std::string& input = node.Scalar(); \
std::stringstream stream(input);\ std::stringstream stream(input); \
stream.unsetf(std::ios::dec);\ stream.unsetf(std::ios::dec); \
if((stream >> rhs) && (stream >> std::ws).eof())\ if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
return true;\ return true; \
if(std::numeric_limits<type>::has_infinity) {\ if (std::numeric_limits<type>::has_infinity) { \
if(conversion::IsInfinity(input)) {\ if (conversion::IsInfinity(input)) { \
rhs = std::numeric_limits<type>::infinity();\ rhs = std::numeric_limits<type>::infinity(); \
return true;\ return true; \
} else if(conversion::IsNegativeInfinity(input)) {\ } else if (conversion::IsNegativeInfinity(input)) { \
rhs = negative_op std::numeric_limits<type>::infinity();\ rhs = negative_op std::numeric_limits<type>::infinity(); \
return true;\ return true; \
}\ } \
}\ } \
\ \
if(std::numeric_limits<type>::has_quiet_NaN && conversion::IsNaN(input)) {\ if (std::numeric_limits<type>::has_quiet_NaN && \
rhs = std::numeric_limits<type>::quiet_NaN();\ conversion::IsNaN(input)) { \
return true;\ rhs = std::numeric_limits<type>::quiet_NaN(); \
}\ return true; \
} \
\ \
return false;\ return false; \
}\ } \
} }
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type)\ #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
YAML_DEFINE_CONVERT_STREAMABLE(type, -) YAML_DEFINE_CONVERT_STREAMABLE(type, -)
#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type)\ #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
YAML_DEFINE_CONVERT_STREAMABLE(type, +) YAML_DEFINE_CONVERT_STREAMABLE(type, +)
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned 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(float);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE #undef YAML_DEFINE_CONVERT_STREAMABLE
// bool // bool
template<> template <>
struct convert<bool> { struct convert<bool> {
static Node encode(bool rhs) { static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
return rhs ? Node("true") : Node("false");
}
static bool decode(const Node& node, bool& rhs); YAML_CPP_API static bool decode(const Node& node, bool& rhs);
}; };
// std::map // std::map
template<typename K, typename V> template <typename K, typename V>
struct convert<std::map<K, V> > { struct convert<std::map<K, V>> {
static Node encode(const std::map<K, V>& rhs) { static Node encode(const std::map<K, V>& rhs) {
Node node(NodeType::Map); Node node(NodeType::Map);
for(typename std::map<K, V>::const_iterator it=rhs.begin();it!=rhs.end();++it) for (typename std::map<K, V>::const_iterator it = rhs.begin();
it != rhs.end(); ++it)
node.force_insert(it->first, it->second); node.force_insert(it->first, it->second);
return node; return node;
} }
static bool decode(const Node& node, std::map<K, V>& rhs) { static bool decode(const Node& node, std::map<K, V>& rhs) {
if(!node.IsMap()) if (!node.IsMap())
return false; return false;
rhs.clear(); rhs.clear();
for(const_iterator it=node.begin();it!=node.end();++it) for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs[it->first.template as<K>()] = it->second.template as<V>(); rhs[it->first.template as<K>()] = it->second.template as<V>();
#else #else
rhs[it->first.as<K>()] = it->second.as<V>(); rhs[it->first.as<K>()] = it->second.as<V>();
#endif #endif
return true; return true;
} }
}; };
// std::vector // std::vector
template<typename T> template <typename T>
struct convert<std::vector<T> > { struct convert<std::vector<T>> {
static Node encode(const std::vector<T>& rhs) { static Node encode(const std::vector<T>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
for(typename std::vector<T>::const_iterator it=rhs.begin();it!=rhs.end();++it) for (typename std::vector<T>::const_iterator it = rhs.begin();
it != rhs.end(); ++it)
node.push_back(*it); node.push_back(*it);
return node; return node;
} }
static bool decode(const Node& node, std::vector<T>& rhs) { static bool decode(const Node& node, std::vector<T>& rhs) {
if(!node.IsSequence()) if (!node.IsSequence())
return false; return false;
rhs.clear(); rhs.clear();
for(const_iterator it=node.begin();it!=node.end();++it) for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.push_back(it->template as<T>()); rhs.push_back(it->template as<T>());
#else #else
rhs.push_back(it->as<T>()); rhs.push_back(it->as<T>());
#endif #endif
return true; return true;
} }
}; };
// std::list // std::list
template<typename T> template <typename T>
struct convert<std::list<T> > { struct convert<std::list<T>> {
static Node encode(const std::list<T>& rhs) { static Node encode(const std::list<T>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
for(typename std::list<T>::const_iterator it=rhs.begin();it!=rhs.end();++it) for (typename std::list<T>::const_iterator it = rhs.begin();
it != rhs.end(); ++it)
node.push_back(*it); node.push_back(*it);
return node; return node;
} }
static bool decode(const Node& node, std::list<T>& rhs) { static bool decode(const Node& node, std::list<T>& rhs) {
if(!node.IsSequence()) if (!node.IsSequence())
return false; return false;
rhs.clear(); rhs.clear();
for(const_iterator it=node.begin();it!=node.end();++it) for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.push_back(it->template as<T>()); rhs.push_back(it->template as<T>());
#else #else
rhs.push_back(it->as<T>()); rhs.push_back(it->as<T>());
#endif #endif
return true; return true;
} }
}; };
// std::pair // std::array
template<typename T, typename U> template <typename T, std::size_t N>
struct convert<std::pair<T, U> > { 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) { static Node encode(const std::pair<T, U>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
node.push_back(rhs.first); node.push_back(rhs.first);
@@ -235,46 +286,46 @@ namespace YAML
} }
static bool decode(const Node& node, std::pair<T, U>& rhs) { static bool decode(const Node& node, std::pair<T, U>& rhs) {
if(!node.IsSequence()) if (!node.IsSequence())
return false; return false;
if (node.size() != 2) if (node.size() != 2)
return false; return false;
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.first = node[0].template as<T>(); rhs.first = node[0].template as<T>();
#else #else
rhs.first = node[0].as<T>(); rhs.first = node[0].as<T>();
#endif #endif
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.second = node[1].template as<U>(); rhs.second = node[1].template as<U>();
#else #else
rhs.second = node[1].as<U>(); rhs.second = node[1].as<U>();
#endif #endif
return true; return true;
} }
}; };
// binary // binary
template<> template <>
struct convert<Binary> { struct convert<Binary> {
static Node encode(const Binary& rhs) { static Node encode(const Binary& rhs) {
return Node(EncodeBase64(rhs.data(), rhs.size())); return Node(EncodeBase64(rhs.data(), rhs.size()));
} }
static bool decode(const Node& node, Binary& rhs) { static bool decode(const Node& node, Binary& rhs) {
if(!node.IsScalar()) if (!node.IsScalar())
return false; return false;
std::vector<unsigned char> data = DecodeBase64(node.Scalar()); std::vector<unsigned char> data = DecodeBase64(node.Scalar());
if(data.empty() && !node.Scalar().empty()) if (data.empty() && !node.Scalar().empty())
return false; return false;
rhs.swap(data); rhs.swap(data);
return true; return true;
} }
}; };
} }
#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,26 +1,26 @@
#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define 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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct unspecified_bool {
{
struct unspecified_bool {
struct NOT_ALLOWED; struct NOT_ALLOWED;
static void true_value(NOT_ALLOWED*) {} static void true_value(NOT_ALLOWED*) {}
}; };
typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
} }
} }
#define YAML_CPP_OPERATOR_BOOL()\ #define YAML_CPP_OPERATOR_BOOL() \
operator YAML::detail::unspecified_bool_type() const\ operator YAML::detail::unspecified_bool_type() const { \
{\ return this->operator!() ? 0 \
return this->operator!() ? 0 : &YAML::detail::unspecified_bool::true_value;\ : &YAML::detail::unspecified_bool::true_value; \
} }
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,87 +1,110 @@
#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/type_traits.hpp> #include <type_traits>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail template <typename Key, typename Enable = void>
{ struct get_idx {
template<typename Key, typename Enable = void> static node* get(const std::vector<node*>& /* sequence */,
struct get_idx { const Key& /* key */, shared_memory_holder /* pMemory */) {
static node *get(const std::vector<node *>& /* sequence */, const Key& /* key */, shared_memory_holder /* pMemory */) {
return 0; return 0;
} }
}; };
template<typename Key> template <typename Key>
struct get_idx<Key, typename boost::enable_if_c<boost::is_unsigned<Key>::value && !boost::is_same<Key, bool>::value>::type> { struct get_idx<Key,
static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder /* pMemory */) { 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; return key < sequence.size() ? sequence[key] : 0;
} }
static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) { static node* get(std::vector<node*>& sequence, const Key& key,
if(key > sequence.size()) shared_memory_holder pMemory) {
if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
return 0; return 0;
if(key == sequence.size()) if (key == sequence.size())
sequence.push_back(&pMemory->create_node()); sequence.push_back(&pMemory->create_node());
return sequence[key]; return sequence[key];
} }
}; };
template<typename Key> template <typename Key>
struct get_idx<Key, typename boost::enable_if<boost::is_signed<Key> >::type> { 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) { static node* get(const std::vector<node*>& sequence, const Key& key,
return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0; 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) { static node* get(std::vector<node*>& sequence, const Key& key,
return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0; shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(
sequence, static_cast<std::size_t>(key), pMemory)
: 0;
} }
}; };
// indexing template <typename T>
template<typename Key> inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const T lhs;
{ if (convert<T>::decode(Node(*this, pMemory), lhs)) {
switch(m_type) { 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: case NodeType::Map:
break; break;
case NodeType::Undefined: case NodeType::Undefined:
case NodeType::Null: case NodeType::Null:
return pMemory->create_node(); return NULL;
case NodeType::Sequence: case NodeType::Sequence:
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return *pNode; return pNode;
return pMemory->create_node(); return NULL;
case NodeType::Scalar: case NodeType::Scalar:
throw BadSubscript(); throw BadSubscript();
} }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
if(equals(*it->first, key, pMemory)) if (it->first->equals(key, pMemory)) {
return *it->second; return it->second;
}
} }
return pMemory->create_node(); return NULL;
} }
template<typename Key> template <typename Key>
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
{ switch (m_type) {
switch(m_type) {
case NodeType::Map: case NodeType::Map:
break; break;
case NodeType::Undefined: case NodeType::Undefined:
case NodeType::Null: case NodeType::Null:
case NodeType::Sequence: case NodeType::Sequence:
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) { if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
m_type = NodeType::Sequence; m_type = NodeType::Sequence;
return *pNode; return *pNode;
} }
@@ -92,38 +115,46 @@ namespace YAML
throw BadSubscript(); throw BadSubscript();
} }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
if(equals(*it->first, key, pMemory)) if (it->first->equals(key, pMemory)) {
return *it->second; return *it->second;
} }
}
node& k = convert_to_node(key, pMemory); node& k = convert_to_node(key, pMemory);
node& v = pMemory->create_node(); node& v = pMemory->create_node();
insert_map_pair(k, v); insert_map_pair(k, v);
return v; return v;
} }
template<typename Key> template <typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
{ if (m_type != NodeType::Map)
if(m_type != NodeType::Map)
return false; return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { for (kv_pairs::iterator it = m_undefinedPairs.begin();
if(equals(*it->first, key, pMemory)) { 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); m_map.erase(it);
return true; return true;
} }
} }
return false; return false;
} }
// map // map
template<typename Key, typename Value> template <typename Key, typename Value>
inline void node_data::force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) inline void node_data::force_insert(const Key& key, const Value& value,
{ shared_memory_holder pMemory) {
switch(m_type) { switch (m_type) {
case NodeType::Map: case NodeType::Map:
break; break;
case NodeType::Undefined: case NodeType::Undefined:
@@ -138,31 +169,17 @@ namespace YAML
node& k = convert_to_node(key, pMemory); node& k = convert_to_node(key, pMemory);
node& v = convert_to_node(value, pMemory); node& v = convert_to_node(value, pMemory);
insert_map_pair(k, v); insert_map_pair(k, v);
} }
template<typename T> template <typename T>
inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory) inline node& node_data::convert_to_node(const T& rhs,
{ shared_memory_holder pMemory) {
T lhs;
if(convert<T>::decode(Node(node, pMemory), lhs))
return lhs == rhs;
return false;
}
inline bool node_data::equals(node& node, const char *rhs, shared_memory_holder pMemory)
{
return equals<std::string>(node, rhs, pMemory);
}
template<typename T>
inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory)
{
Node value = convert<T>::encode(rhs); Node value = convert<T>::encode(rhs);
value.EnsureNodeExists(); value.EnsureNodeExists();
pMemory->merge(*value.m_pMemory); pMemory->merge(*value.m_pMemory);
return *value.m_pNode; return *value.m_pNode;
} }
} }
} }
#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,64 +1,92 @@
#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_iterator.h" #include "yaml-cpp/node/detail/node_iterator.h"
#include <boost/iterator/iterator_adaptor.hpp> #include <cstddef>
#include <boost/utility.hpp> #include <iterator>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct iterator_value;
{
struct iterator_value; template <typename V>
class iterator_base : public std::iterator<std::forward_iterator_tag, V,
std::ptrdiff_t, V*, V> {
template<typename V>
class iterator_base: public boost::iterator_adaptor<
iterator_base<V>,
node_iterator,
V,
std::forward_iterator_tag,
V>
{
private: private:
template<typename> friend class iterator_base; template <typename>
friend class iterator_base;
struct enabler {}; struct enabler {};
typedef typename iterator_base::base_type base_type; 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: public:
typedef typename iterator_base::value_type value_type; typedef typename iterator_base::value_type value_type;
public: public:
iterator_base() {} iterator_base() : m_iterator(), m_pMemory() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory): iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {} explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
: m_iterator(rhs), m_pMemory(pMemory) {}
template<class W> template <class W>
iterator_base(const iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()): iterator_base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {} 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) {}
private: iterator_base<V>& operator++() {
friend class boost::iterator_core_access; ++m_iterator;
return *this;
}
void increment() { this->base_reference() = boost::next(this->base()); } iterator_base<V> operator++(int) {
iterator_base<V> iterator_pre(*this);
++(*this);
return iterator_pre;
}
value_type dereference() const { template <typename W>
const typename base_type::value_type& v = *this->base(); bool operator==(const iterator_base<W>& rhs) const {
if(v.pNode) 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)); return value_type(Node(*v, m_pMemory));
if(v.first && v.second) if (v.first && v.second)
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
return value_type(); return value_type();
} }
proxy operator->() const { return proxy(**this); }
private: private:
base_type m_iterator;
shared_memory_holder m_pMemory; shared_memory_holder m_pMemory;
}; };
} }
} }
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,27 +1,27 @@
#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <list> #include <list>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{
class node;
namespace detail { namespace detail {
struct iterator_value; struct iterator_value;
template<typename V> class iterator_base; template <typename V>
} class iterator_base;
}
typedef detail::iterator_base<detail::iterator_value> iterator; typedef detail::iterator_base<detail::iterator_value> iterator;
typedef detail::iterator_base<const detail::iterator_value> const_iterator; typedef detail::iterator_base<const detail::iterator_value> const_iterator;
} }
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,19 +1,26 @@
#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/ptr.h"
#include <set> #include <set>
#include <boost/shared_ptr.hpp>
namespace YAML #include "yaml-cpp/dll.h"
{ #include "yaml-cpp/node/ptr.h"
namespace detail
{ namespace YAML {
class memory { namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
namespace detail {
class YAML_CPP_API memory {
public: public:
node& create_node(); node& create_node();
void merge(const memory& rhs); void merge(const memory& rhs);
@@ -21,19 +28,19 @@ namespace YAML
private: private:
typedef std::set<shared_node> Nodes; typedef std::set<shared_node> Nodes;
Nodes m_nodes; Nodes m_nodes;
}; };
class memory_holder { class YAML_CPP_API memory_holder {
public: public:
memory_holder(): m_pMemory(new memory) {} memory_holder() : m_pMemory(new memory) {}
node& create_node() { return m_pMemory->create_node(); } node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs); void merge(memory_holder& rhs);
private: private:
boost::shared_ptr<memory> m_pMemory; shared_memory m_pMemory;
}; };
} }
} }
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,66 +1,75 @@
#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_ref.h" #include "yaml-cpp/node/detail/node_ref.h"
#include <set> #include <set>
#include <boost/utility.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class node {
{
class node: private boost::noncopyable
{
public: public:
node(): m_pRef(new node_ref) {} 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; } bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
const node_ref *ref() const { return m_pRef.get(); } const node_ref* ref() const { return m_pRef.get(); }
bool is_defined() const { return m_pRef->is_defined(); } 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(); } NodeType::value type() const { return m_pRef->type(); }
const std::string& scalar() const { return m_pRef->scalar(); } const std::string& scalar() const { return m_pRef->scalar(); }
const std::string& tag() const { return m_pRef->tag(); } 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() { void mark_defined() {
if(is_defined()) if (is_defined())
return; return;
m_pRef->mark_defined(); m_pRef->mark_defined();
for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it) for (nodes::iterator it = m_dependencies.begin();
it != m_dependencies.end(); ++it)
(*it)->mark_defined(); (*it)->mark_defined();
m_dependencies.clear(); m_dependencies.clear();
} }
void add_dependency(node& rhs) { void add_dependency(node& rhs) {
if(is_defined()) if (is_defined())
rhs.mark_defined(); rhs.mark_defined();
else else
m_dependencies.insert(&rhs); m_dependencies.insert(&rhs);
} }
void set_ref(const node& rhs) { void set_ref(const node& rhs) {
if(rhs.is_defined()) if (rhs.is_defined())
mark_defined(); mark_defined();
m_pRef = rhs.m_pRef; m_pRef = rhs.m_pRef;
} }
void set_data(const node& rhs) { void set_data(const node& rhs) {
if(rhs.is_defined()) if (rhs.is_defined())
mark_defined(); mark_defined();
m_pRef->set_data(*rhs.m_pRef); m_pRef->set_data(*rhs.m_pRef);
} }
void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
void set_type(NodeType::value type) { void set_type(NodeType::value type) {
if(type != NodeType::Undefined) if (type != NodeType::Undefined)
mark_defined(); mark_defined();
m_pRef->set_type(type); m_pRef->set_type(type);
} }
@@ -77,19 +86,29 @@ namespace YAML
m_pRef->set_tag(tag); m_pRef->set_tag(tag);
} }
// style
void set_style(EmitterStyle::value style) {
mark_defined();
m_pRef->set_style(style);
}
// size/iterator // size/iterator
std::size_t size() const { return m_pRef->size(); } std::size_t size() const { return m_pRef->size(); }
const_node_iterator begin() const { return static_cast<const node_ref&>(*m_pRef).begin(); } const_node_iterator begin() const {
return static_cast<const node_ref&>(*m_pRef).begin();
}
node_iterator begin() { return m_pRef->begin(); } node_iterator begin() { return m_pRef->begin(); }
const_node_iterator end() const { return static_cast<const node_ref&>(*m_pRef).end(); } const_node_iterator end() const {
return static_cast<const node_ref&>(*m_pRef).end();
}
node_iterator end() { return m_pRef->end(); } node_iterator end() { return m_pRef->end(); }
// sequence // sequence
void push_back(node& node, shared_memory_holder pMemory) { void push_back(node& input, shared_memory_holder pMemory) {
m_pRef->push_back(node, pMemory); m_pRef->push_back(input, pMemory);
node.add_dependency(*this); input.add_dependency(*this);
} }
void insert(node& key, node& value, shared_memory_holder pMemory) { void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pRef->insert(key, value, pMemory); m_pRef->insert(key, value, pMemory);
@@ -98,33 +117,53 @@ namespace YAML
} }
// indexing // indexing
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); } template <typename Key>
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { 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); node& value = m_pRef->get(key, pMemory);
value.add_dependency(*this); value.add_dependency(*this);
return value; return value;
} }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory) {
return m_pRef->remove(key, pMemory);
}
node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); } node* get(node& key, shared_memory_holder pMemory) 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& get(node& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory); node& value = m_pRef->get(key, pMemory);
key.add_dependency(*this); key.add_dependency(*this);
value.add_dependency(*this); value.add_dependency(*this);
return value; return value;
} }
bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } bool remove(node& key, shared_memory_holder pMemory) {
return m_pRef->remove(key, pMemory);
}
// map // map
template<typename Key, typename Value> 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); } void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pRef->force_insert(key, value, pMemory);
}
private: private:
shared_node_ref m_pRef; shared_node_ref m_pRef;
typedef std::set<node *> nodes; typedef std::set<node*> nodes;
nodes m_dependencies; nodes m_dependencies;
}; };
} }
} }
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,39 +1,54 @@
#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
#include <boost/utility.hpp>
#include <list> #include <list>
#include <map>
#include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/dll.h"
{ #include "yaml-cpp/node/detail/node_iterator.h"
namespace detail #include "yaml-cpp/node/iterator.h"
{ #include "yaml-cpp/node/ptr.h"
class node_data: private boost::noncopyable #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: public:
node_data(); node_data();
node_data(const node_data&) = delete;
node_data& operator=(const node_data&) = delete;
void mark_defined(); void mark_defined();
void set_mark(const Mark& mark);
void set_type(NodeType::value type); void set_type(NodeType::value type);
void set_tag(const std::string& tag); void set_tag(const std::string& tag);
void set_null(); void set_null();
void set_scalar(const std::string& scalar); void set_scalar(const std::string& scalar);
void set_style(EmitterStyle::value style);
bool is_defined() const { return m_isDefined; } bool is_defined() const { return m_isDefined; }
NodeType::value type() const { return m_isDefined ? m_type : NodeType::Undefined; } 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& scalar() const { return m_scalar; }
const std::string& tag() const { return m_tag; } const std::string& tag() const { return m_tag; }
EmitterStyle::value style() const { return m_style; }
// size/iterator // size/iterator
std::size_t size() const; std::size_t size() const;
@@ -49,17 +64,21 @@ namespace YAML
void insert(node& key, node& value, shared_memory_holder pMemory); void insert(node& key, node& value, shared_memory_holder pMemory);
// indexing // indexing
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const; template <typename Key>
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory); node* get(const Key& key, shared_memory_holder pMemory) const;
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory); 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) const;
node& get(node& key, shared_memory_holder pMemory); node& get(node& key, shared_memory_holder pMemory);
bool remove(node& key, shared_memory_holder pMemory); bool remove(node& key, shared_memory_holder pMemory);
// map // map
template<typename Key, typename Value> template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory); void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory);
public: public:
static std::string empty_scalar; static std::string empty_scalar;
@@ -75,36 +94,34 @@ namespace YAML
void convert_to_map(shared_memory_holder pMemory); void convert_to_map(shared_memory_holder pMemory);
void convert_sequence_to_map(shared_memory_holder pMemory); void convert_sequence_to_map(shared_memory_holder pMemory);
template<typename T> template <typename T>
static bool equals(node& node, const T& rhs, shared_memory_holder pMemory);
static bool equals(node& node, const char *rhs, shared_memory_holder pMemory);
template<typename T>
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
private: private:
bool m_isDefined; bool m_isDefined;
Mark m_mark;
NodeType::value m_type; NodeType::value m_type;
std::string m_tag; std::string m_tag;
EmitterStyle::value m_style;
// scalar // scalar
std::string m_scalar; std::string m_scalar;
// sequence // sequence
typedef std::vector<node *> node_seq; typedef std::vector<node*> node_seq;
node_seq m_sequence; node_seq m_sequence;
mutable std::size_t m_seqSize; mutable std::size_t m_seqSize;
// map // map
typedef std::map<node *, node *> node_map; typedef std::vector<std::pair<node*, node*>> node_map;
node_map m_map; node_map m_map;
typedef std::pair<node *, node *> kv_pair; typedef std::pair<node*, node*> kv_pair;
typedef std::list<kv_pair> kv_pairs; typedef std::list<kv_pair> kv_pairs;
mutable kv_pairs m_undefinedPairs; mutable kv_pairs m_undefinedPairs;
}; };
} }
} }
#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,100 +1,129 @@
#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <boost/iterator/iterator_facade.hpp> #include <cstddef>
#include <boost/utility/enable_if.hpp> #include <iterator>
#include <memory>
#include <map> #include <map>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct iterator_type {
{ enum value { NoneType, Sequence, Map };
struct iterator_type { enum value { None, Sequence, Map }; }; };
template<typename V> template <typename V>
struct node_iterator_value: public std::pair<V*, V*> { struct node_iterator_value : public std::pair<V*, V*> {
typedef std::pair<V*, V*> kv; typedef std::pair<V*, V*> kv;
node_iterator_value(): kv(), pNode(0) {} node_iterator_value() : kv(), pNode(0) {}
explicit node_iterator_value(V& rhs): kv(), pNode(&rhs) {} explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
explicit node_iterator_value(V& key, V& value): kv(&key, &value), pNode(0) {} explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {}
V& operator *() const { return *pNode; } V& operator*() const { return *pNode; }
V& operator ->() const { return *pNode; } V& operator->() const { return *pNode; }
V *pNode; V* pNode;
}; };
typedef std::vector<node *> node_seq; typedef std::vector<node*> node_seq;
typedef std::map<node *, node *> node_map; typedef std::vector<std::pair<node*, node*>> node_map;
template<typename V> template <typename V>
struct node_iterator_type { struct node_iterator_type {
typedef node_seq::iterator seq; typedef node_seq::iterator seq;
typedef node_map::iterator map; typedef node_map::iterator map;
}; };
template<typename V> template <typename V>
struct node_iterator_type<const V> { struct node_iterator_type<const V> {
typedef node_seq::const_iterator seq; typedef node_seq::const_iterator seq;
typedef node_map::const_iterator map; typedef node_map::const_iterator map;
}; };
template <typename V>
template<typename V> class node_iterator_base
class node_iterator_base: public boost::iterator_facade< : public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
node_iterator_base<V>, std::ptrdiff_t, node_iterator_value<V>*,
node_iterator_value<V>, node_iterator_value<V>> {
std::forward_iterator_tag,
node_iterator_value<V> >
{
private: private:
struct enabler {}; 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: public:
typedef typename node_iterator_type<V>::seq SeqIter; typedef typename node_iterator_type<V>::seq SeqIter;
typedef typename node_iterator_type<V>::map MapIter; typedef typename node_iterator_type<V>::map MapIter;
typedef node_iterator_value<V> value_type; typedef node_iterator_value<V> value_type;
node_iterator_base(): m_type(iterator_type::None) {} node_iterator_base()
explicit node_iterator_base(SeqIter seqIt): m_type(iterator_type::Sequence), m_seqIt(seqIt) {} : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
explicit node_iterator_base(MapIter mapIt, MapIter mapEnd): m_type(iterator_type::Map), m_mapIt(mapIt), m_mapEnd(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); m_mapIt = increment_until_defined(m_mapIt);
} }
template<typename W> template <typename W>
node_iterator_base(const node_iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()) node_iterator_base(const node_iterator_base<W>& rhs,
: m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt), m_mapEnd(rhs.m_mapEnd) {} 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) {}
private: template <typename>
friend class boost::iterator_core_access; friend class node_iterator_base;
template<typename> friend class node_iterator_base;
template<typename W> template <typename W>
bool equal(const node_iterator_base<W>& rhs) const { bool operator==(const node_iterator_base<W>& rhs) const {
if(m_type != rhs.m_type) if (m_type != rhs.m_type)
return false; return false;
switch(m_type) { switch (m_type) {
case iterator_type::None: return true; case iterator_type::NoneType:
case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt; return true;
case iterator_type::Map: return m_mapIt == rhs.m_mapIt; case iterator_type::Sequence:
return m_seqIt == rhs.m_seqIt;
case iterator_type::Map:
return m_mapIt == rhs.m_mapIt;
} }
return true; return true;
} }
void increment() { template <typename W>
switch(m_type) { bool operator!=(const node_iterator_base<W>& rhs) const {
case iterator_type::None: break; return !(*this == rhs);
}
node_iterator_base<V>& operator++() {
switch (m_type) {
case iterator_type::NoneType:
break;
case iterator_type::Sequence: case iterator_type::Sequence:
++m_seqIt; ++m_seqIt;
break; break;
@@ -103,19 +132,31 @@ namespace YAML
m_mapIt = increment_until_defined(m_mapIt); m_mapIt = increment_until_defined(m_mapIt);
break; break;
} }
return *this;
} }
value_type dereference() const { node_iterator_base<V> operator++(int) {
switch(m_type) { node_iterator_base<V> iterator_pre(*this);
case iterator_type::None: return value_type(); ++(*this);
case iterator_type::Sequence: return value_type(**m_seqIt); return iterator_pre;
case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second); }
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(); return value_type();
} }
proxy operator->() const { return proxy(**this); }
MapIter increment_until_defined(MapIter it) { MapIter increment_until_defined(MapIter it) {
while(it != m_mapEnd && !is_defined(it)) while (it != m_mapEnd && !is_defined(it))
++it; ++it;
return it; return it;
} }
@@ -129,11 +170,11 @@ namespace YAML
SeqIter m_seqIt; SeqIter m_seqIt;
MapIter m_mapIt, m_mapEnd; MapIter m_mapIt, m_mapEnd;
}; };
typedef node_iterator_base<node> node_iterator; typedef node_iterator_base<node> node_iterator;
typedef node_iterator_base<const node> const_node_iterator; typedef node_iterator_base<const node> const_node_iterator;
} }
} }
#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,69 +1,98 @@
#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/utility.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class node_ref {
{
class node_ref: private boost::noncopyable
{
public: public:
node_ref(): m_pData(new node_data) {} 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(); } 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(); } NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); } const std::string& scalar() const { return m_pData->scalar(); }
const std::string& tag() const { return m_pData->tag(); } 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 mark_defined() { m_pData->mark_defined(); }
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } 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_type(NodeType::value type) { m_pData->set_type(type); }
void set_tag(const std::string& tag) { m_pData->set_tag(tag); } void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); } void set_null() { m_pData->set_null(); }
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } 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 // size/iterator
std::size_t size() const { return m_pData->size(); } std::size_t size() const { return m_pData->size(); }
const_node_iterator begin() const { return static_cast<const node_data&>(*m_pData).begin(); } const_node_iterator begin() const {
node_iterator begin() {return m_pData->begin(); } 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(); } const_node_iterator end() const {
node_iterator end() {return m_pData->end(); } return static_cast<const node_data&>(*m_pData).end();
}
node_iterator end() { return m_pData->end(); }
// sequence // sequence
void push_back(node& node, shared_memory_holder pMemory) { m_pData->push_back(node, pMemory); } void push_back(node& node, shared_memory_holder pMemory) {
void insert(node& key, node& value, shared_memory_holder pMemory) { m_pData->insert(key, value, pMemory); } m_pData->push_back(node, pMemory);
}
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pData->insert(key, value, pMemory);
}
// indexing // 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>
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } node* get(const Key& key, shared_memory_holder pMemory) const {
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); } 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) const {
node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } return static_cast<const node_data&>(*m_pData).get(key, pMemory);
bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(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 // map
template<typename Key, typename Value> 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); } void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pData->force_insert(key, value, pMemory);
}
private: private:
shared_node_data m_pData; shared_node_data m_pData;
}; };
} }
} }
#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,23 +1,32 @@
#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
namespace YAML #include "yaml-cpp/dll.h"
{
class Emitter;
class Node;
Emitter& operator << (Emitter& out, const Node& node); namespace YAML {
std::ostream& operator << (std::ostream& out, const Node& node); class Emitter;
class Node;
std::string Dump(const Node& 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 #endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,11 +1,12 @@
#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
@@ -13,254 +14,255 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
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()) 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); m_pNode->set_type(type);
} }
template<typename T> template <typename T>
inline Node::Node(const T& rhs): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) inline Node::Node(const T& rhs)
{ : m_isValid(true),
m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) {
Assign(rhs); 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 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(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(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(detail::node& node, detail::shared_memory_holder pMemory)
{ : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
}
inline Node::~Node() inline Node::~Node() {}
{
}
inline void Node::EnsureNodeExists() const inline void Node::EnsureNodeExists() const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
if(!m_pNode) { if (!m_pNode) {
m_pMemory.reset(new detail::memory_holder); m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node(); m_pNode = &m_pMemory->create_node();
m_pNode->set_null(); m_pNode->set_null();
} }
} }
inline bool Node::IsDefined() const inline bool Node::IsDefined() const {
{ if (!m_isValid) {
if(!m_isValid) return false;
throw InvalidNode(); }
return m_pNode ? m_pNode->is_defined() : true; return m_pNode ? m_pNode->is_defined() : true;
} }
inline NodeType::value Node::Type() const inline Mark Node::Mark() const {
{ if (!m_isValid) {
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(); throw InvalidNode();
return m_pNode ? m_pNode->type() : NodeType::Null; return m_pNode ? m_pNode->type() : NodeType::Null;
} }
// access // access
// template helpers // template helpers
template<typename T, typename S> template <typename T, typename S>
struct as_if { struct as_if {
explicit as_if(const Node& node_): node(node_) {} explicit as_if(const Node& node_) : node(node_) {}
const Node& node; const Node& node;
const T operator()(const S& fallback) const { T operator()(const S& fallback) const {
if(!node.m_pNode) if (!node.m_pNode)
return fallback; return fallback;
T t; T t;
if(convert<T>::decode(node, t)) if (convert<T>::decode(node, t))
return t; return t;
return fallback; return fallback;
} }
}; };
template<typename S> template <typename S>
struct as_if<std::string, S> { struct as_if<std::string, S> {
explicit as_if(const Node& node_): node(node_) {} explicit as_if(const Node& node_) : node(node_) {}
const Node& node; const Node& node;
const std::string operator()(const S& fallback) const { std::string operator()(const S& fallback) const {
if(node.Type() != NodeType::Scalar) if (node.Type() != NodeType::Scalar)
return fallback; return fallback;
return node.Scalar(); return node.Scalar();
} }
}; };
template<typename T> template <typename T>
struct as_if<T, void> { struct as_if<T, void> {
explicit as_if(const Node& node_): node(node_) {} explicit as_if(const Node& node_) : node(node_) {}
const Node& node; const Node& node;
const T operator()() const { T operator()() const {
if(!node.m_pNode) if (!node.m_pNode)
throw TypedBadConversion<T>(); throw TypedBadConversion<T>(node.Mark());
T t; T t;
if(convert<T>::decode(node, t)) if (convert<T>::decode(node, t))
return t; return t;
throw TypedBadConversion<T>(); throw TypedBadConversion<T>(node.Mark());
} }
}; };
template<> template <>
struct as_if<std::string, void> { struct as_if<std::string, void> {
explicit as_if(const Node& node_): node(node_) {} explicit as_if(const Node& node_) : node(node_) {}
const Node& node; const Node& node;
const std::string operator()() const { std::string operator()() const {
if(node.Type() != NodeType::Scalar) if (node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>(); throw TypedBadConversion<std::string>(node.Mark());
return node.Scalar(); return node.Scalar();
} }
}; };
// access functions // access functions
template<typename T> template <typename T>
inline const T Node::as() const inline T Node::as() const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
return as_if<T, void>(*this)(); return as_if<T, void>(*this)();
} }
template<typename T, typename S> template <typename T, typename S>
inline const T Node::as(const S& fallback) const inline T Node::as(const S& fallback) const {
{ if (!m_isValid)
if(!m_isValid) return fallback;
throw InvalidNode();
return as_if<T, S>(*this)(fallback); return as_if<T, S>(*this)(fallback);
} }
inline const std::string& Node::Scalar() const inline const std::string& Node::Scalar() const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
} }
inline const std::string& Node::Tag() const inline const std::string& Node::Tag() const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
} }
inline void Node::SetTag(const std::string& tag) inline void Node::SetTag(const std::string& tag) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_tag(tag); m_pNode->set_tag(tag);
} }
// assignment inline EmitterStyle::value Node::Style() const {
inline bool Node::is(const Node& rhs) const if (!m_isValid)
{
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
if(!m_pNode || !rhs.m_pNode) 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 false;
return m_pNode->is(*rhs.m_pNode); return m_pNode->is(*rhs.m_pNode);
} }
template<typename T> template <typename T>
inline Node& Node::operator=(const T& rhs) inline Node& Node::operator=(const T& rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
Assign(rhs); Assign(rhs);
return *this; return *this;
} }
inline void Node::reset(const YAML::Node& rhs) inline void Node::reset(const YAML::Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
m_pMemory = rhs.m_pMemory; m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode; m_pNode = rhs.m_pNode;
} }
template<typename T> template <typename T>
inline void Node::Assign(const T& rhs) inline void Node::Assign(const T& rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
AssignData(convert<T>::encode(rhs)); AssignData(convert<T>::encode(rhs));
} }
template<> template <>
inline void Node::Assign(const std::string& rhs) inline void Node::Assign(const std::string& rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline void Node::Assign(const char *rhs) inline void Node::Assign(const char* rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline void Node::Assign(char *rhs) inline void Node::Assign(char* rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->set_scalar(rhs); m_pNode->set_scalar(rhs);
} }
inline Node& Node::operator=(const Node& rhs) inline Node& Node::operator=(const Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
if(is(rhs)) if (is(rhs))
return *this; return *this;
AssignNode(rhs); AssignNode(rhs);
return *this; return *this;
} }
inline void Node::AssignData(const Node& rhs) inline void Node::AssignData(const Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
m_pNode->set_data(*rhs.m_pNode); m_pNode->set_data(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory); m_pMemory->merge(*rhs.m_pMemory);
} }
inline void Node::AssignNode(const Node& rhs) inline void Node::AssignNode(const Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
if(!m_pNode) { if (!m_pNode) {
m_pNode = rhs.m_pNode; m_pNode = rhs.m_pNode;
m_pMemory = rhs.m_pMemory; m_pMemory = rhs.m_pMemory;
return; return;
@@ -269,183 +271,178 @@ namespace YAML
m_pNode->set_ref(*rhs.m_pNode); m_pNode->set_ref(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory); m_pMemory->merge(*rhs.m_pMemory);
m_pNode = rhs.m_pNode; m_pNode = rhs.m_pNode;
} }
// size/iterator // size/iterator
inline std::size_t Node::size() const inline std::size_t Node::size() const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
return m_pNode ? m_pNode->size() : 0; return m_pNode ? m_pNode->size() : 0;
} }
inline const_iterator Node::begin() const inline const_iterator Node::begin() const {
{ if (!m_isValid)
if(!m_isValid) return const_iterator();
throw InvalidNode(); return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) : const_iterator(); : const_iterator();
} }
inline iterator Node::begin() inline iterator Node::begin() {
{ if (!m_isValid)
if(!m_isValid) return iterator();
throw InvalidNode();
return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
} }
inline const_iterator Node::end() const inline const_iterator Node::end() const {
{ if (!m_isValid)
if(!m_isValid) return const_iterator();
throw InvalidNode();
return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
} }
inline iterator Node::end() inline iterator Node::end() {
{ if (!m_isValid)
if(!m_isValid) return iterator();
throw InvalidNode();
return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
} }
// sequence // sequence
template<typename T> template <typename T>
inline void Node::push_back(const T& rhs) inline void Node::push_back(const T& rhs) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
push_back(Node(rhs)); push_back(Node(rhs));
} }
inline void Node::push_back(const Node& rhs) inline void Node::push_back(const Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
rhs.EnsureNodeExists(); rhs.EnsureNodeExists();
m_pNode->push_back(*rhs.m_pNode, m_pMemory); m_pNode->push_back(*rhs.m_pNode, m_pMemory);
m_pMemory->merge(*rhs.m_pMemory); m_pMemory->merge(*rhs.m_pMemory);
} }
// helpers for indexing // helpers for indexing
namespace detail { namespace detail {
template<typename T> template <typename T>
struct to_value_t { struct to_value_t {
explicit to_value_t(const T& t_): t(t_) {} explicit to_value_t(const T& t_) : t(t_) {}
const T& t; const T& t;
typedef const T& return_type; typedef const T& return_type;
const T& operator()() const { return t; } const T& operator()() const { return t; }
}; };
template<> template <>
struct to_value_t<const char*> { struct to_value_t<const char*> {
explicit to_value_t(const char *t_): t(t_) {} explicit to_value_t(const char* t_) : t(t_) {}
const char *t; const char* t;
typedef std::string return_type; typedef std::string return_type;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
template<> template <>
struct to_value_t<char*> { struct to_value_t<char*> {
explicit to_value_t(char *t_): t(t_) {} explicit to_value_t(char* t_) : t(t_) {}
const char *t; const char* t;
typedef std::string return_type; typedef std::string return_type;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
template<std::size_t N> template <std::size_t N>
struct to_value_t<char [N]> { struct to_value_t<char[N]> {
explicit to_value_t(const char *t_): t(t_) {} explicit to_value_t(const char* t_) : t(t_) {}
const char *t; const char* t;
typedef std::string return_type; typedef std::string return_type;
const std::string operator()() const { return t; } const std::string operator()() const { return t; }
}; };
// converts C-strings to std::strings so they can be copied // converts C-strings to std::strings so they can be copied
template<typename T> template <typename T>
inline typename to_value_t<T>::return_type to_value(const T& t) { inline typename to_value_t<T>::return_type to_value(const T& t) {
return to_value_t<T>(t)(); return to_value_t<T>(t)();
} }
} }
// indexing // indexing
template<typename Key> template <typename Key>
inline const Node Node::operator[](const Key& key) const inline const Node Node::operator[](const Key& key) const {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(detail::to_value(key), m_pMemory); detail::node* value = static_cast<const detail::node&>(*m_pNode)
return Node(value, m_pMemory); .get(detail::to_value(key), m_pMemory);
if (!value) {
return Node(ZombieNode);
} }
return Node(*value, m_pMemory);
}
template<typename Key> template <typename Key>
inline Node Node::operator[](const Key& key) inline Node Node::operator[](const Key& key) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
return Node(value, m_pMemory); return Node(value, m_pMemory);
} }
template<typename Key> template <typename Key>
inline bool Node::remove(const Key& key) inline bool Node::remove(const Key& key) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
return m_pNode->remove(detail::to_value(key), m_pMemory); return m_pNode->remove(detail::to_value(key), m_pMemory);
} }
inline const Node Node::operator[](const Node& key) const inline const Node Node::operator[](const Node& key) const {
{ if (!m_isValid || !key.m_isValid)
if(!m_isValid || !key.m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory); m_pMemory->merge(*key.m_pMemory);
return Node(value, 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) inline Node Node::operator[](const Node& key) {
{ if (!m_isValid || !key.m_isValid)
if(!m_isValid || !key.m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory);
detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory); detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory); return Node(value, m_pMemory);
} }
inline bool Node::remove(const Node& key) inline bool Node::remove(const Node& key) {
{ if (!m_isValid || !key.m_isValid)
if(!m_isValid || !key.m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory); return m_pNode->remove(*key.m_pNode, m_pMemory);
} }
// map // map
template<typename Key, typename Value> template <typename Key, typename Value>
inline void Node::force_insert(const Key& key, const Value& value) inline void Node::force_insert(const Key& key, const Value& value) {
{ if (!m_isValid)
if(!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
m_pNode->force_insert(detail::to_value(key), detail::to_value(value), m_pMemory); m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
} m_pMemory);
}
// free functions // free functions
inline bool operator==(const Node& lhs, const Node& rhs) inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
{
return lhs.is(rhs);
}
} }
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,11 +1,12 @@
#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/detail/iterator_fwd.h" #include "yaml-cpp/node/detail/iterator_fwd.h"
@@ -14,15 +15,17 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail { struct iterator_value : public Node, std::pair<Node, Node> {
struct iterator_value: public Node, std::pair<Node, Node> {
iterator_value() {} 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& rhs)
explicit iterator_value(const Node& key, const Node& value): Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {} : Node(rhs),
}; std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
} explicit iterator_value(const Node& key, const Node& value)
: Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
};
}
} }
#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,40 +1,55 @@
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/detail/bool_type.h"
#include <stdexcept> #include <stdexcept>
namespace YAML #include "yaml-cpp/dll.h"
{ #include "yaml-cpp/emitterstyle.h"
class Node #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: public:
friend class NodeBuilder; friend class NodeBuilder;
friend class NodeEvents; friend class NodeEvents;
friend struct detail::iterator_value; friend struct detail::iterator_value;
friend class detail::node;
friend class detail::node_data; friend class detail::node_data;
template<typename> friend class detail::iterator_base; template <typename>
template<typename T, typename S> friend struct as_if; friend class detail::iterator_base;
template <typename T, typename S>
friend struct as_if;
typedef YAML::iterator iterator; typedef YAML::iterator iterator;
typedef YAML::const_iterator const_iterator; typedef YAML::const_iterator const_iterator;
Node(); Node();
explicit Node(NodeType::value type); explicit Node(NodeType::value type);
template<typename T> explicit Node(const T& rhs); template <typename T>
explicit Node(const T& rhs);
explicit Node(const detail::iterator_value& rhs); explicit Node(const detail::iterator_value& rhs);
Node(const Node& rhs); Node(const Node& rhs);
~Node(); ~Node();
YAML::Mark Mark() const;
NodeType::value Type() const; NodeType::value Type() const;
bool IsDefined() const; bool IsDefined() const;
bool IsNull() const { return Type() == NodeType::Null; } bool IsNull() const { return Type() == NodeType::Null; }
@@ -43,19 +58,28 @@ namespace YAML
bool IsMap() const { return Type() == NodeType::Map; } bool IsMap() const { return Type() == NodeType::Map; }
// bool conversions // bool conversions
YAML_CPP_OPERATOR_BOOL(); YAML_CPP_OPERATOR_BOOL()
bool operator!() const { return !IsDefined(); } bool operator!() const { return !IsDefined(); }
// access // access
template<typename T> const T as() const; template <typename T>
template<typename T, typename S> const T as(const S& fallback) const; T as() const;
template <typename T, typename S>
T as(const S& fallback) const;
const std::string& Scalar() const; const std::string& Scalar() const;
const std::string& Tag() const; const std::string& Tag() const;
void SetTag(const std::string& tag); 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 // assignment
bool is(const Node& rhs) const; bool is(const Node& rhs) const;
template<typename T> Node& operator=(const T& rhs); template <typename T>
Node& operator=(const T& rhs);
Node& operator=(const Node& rhs); Node& operator=(const Node& rhs);
void reset(const Node& rhs = Node()); void reset(const Node& rhs = Node());
@@ -69,20 +93,24 @@ namespace YAML
iterator end(); iterator end();
// sequence // sequence
template<typename T> void push_back(const T& rhs); template <typename T>
void push_back(const T& rhs);
void push_back(const Node& rhs); void push_back(const Node& rhs);
// indexing // indexing
template<typename Key> const Node operator[](const Key& key) const; template <typename Key>
template<typename Key> Node operator[](const Key& key); const Node operator[](const Key& key) const;
template<typename Key> bool remove(const Key& key); template <typename Key>
Node operator[](const Key& key);
template <typename Key>
bool remove(const Key& key);
const Node operator[](const Node& key) const; const Node operator[](const Node& key) const;
Node operator[](const Node& key); Node operator[](const Node& key);
bool remove(const Node& key); bool remove(const Node& key);
// map // map
template<typename Key, typename Value> template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value); void force_insert(const Key& key, const Value& value);
private: private:
@@ -92,9 +120,10 @@ namespace YAML
void EnsureNodeExists() const; void EnsureNodeExists() const;
template<typename T> void Assign(const T& rhs); template <typename T>
void Assign(const char *rhs); void Assign(const T& rhs);
void Assign(char *rhs); void Assign(const char* rhs);
void Assign(char* rhs);
void AssignData(const Node& rhs); void AssignData(const Node& rhs);
void AssignNode(const Node& rhs); void AssignNode(const Node& rhs);
@@ -102,15 +131,15 @@ namespace YAML
private: private:
bool m_isValid; bool m_isValid;
mutable detail::shared_memory_holder m_pMemory; mutable detail::shared_memory_holder m_pMemory;
mutable detail::node *m_pNode; mutable detail::node* m_pNode;
}; };
bool operator==(const Node& lhs, const Node& rhs); YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs);
Node Clone(const Node& node); YAML_CPP_API Node Clone(const Node& node);
template<typename T> template <typename T>
struct convert; struct convert;
} }
#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,7 +1,9 @@
#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -9,20 +11,68 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/dll.h"
{
class Node;
Node Load(const std::string& input); namespace YAML {
Node Load(const char *input); class Node;
Node Load(std::istream& input);
Node LoadFile(const std::string& filename);
std::vector<Node> LoadAll(const std::string& input); /**
std::vector<Node> LoadAll(const char *input); * Loads the input string as a single YAML document.
std::vector<Node> LoadAll(std::istream& input); *
std::vector<Node> LoadAllFromFile(const std::string& filename); * @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 #endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,29 +1,29 @@
#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <boost/shared_ptr.hpp> #include <memory>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail { class node;
class node; class node_ref;
class node_ref; class node_data;
class node_data; class memory;
class memory; class memory_holder;
class memory_holder;
typedef boost::shared_ptr<node> shared_node; typedef std::shared_ptr<node> shared_node;
typedef boost::shared_ptr<node_ref> shared_node_ref; typedef std::shared_ptr<node_ref> shared_node_ref;
typedef boost::shared_ptr<node_data> shared_node_data; typedef std::shared_ptr<node_data> shared_node_data;
typedef boost::shared_ptr<memory_holder> shared_memory_holder; typedef std::shared_ptr<memory_holder> shared_memory_holder;
typedef boost::shared_ptr<memory> shared_memory; typedef std::shared_ptr<memory> shared_memory;
} }
} }
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,14 +1,16 @@
#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML {
namespace YAML struct NodeType {
{ enum value { Undefined, Null, Scalar, Sequence, Map };
struct NodeType { enum value { Undefined, Null, Scalar, Sequence, Map }; }; };
} }
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,25 +1,25 @@
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define 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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML namespace YAML {
{ // this is basically boost::noncopyable
// this is basically boost::noncopyable class YAML_CPP_API noncopyable {
class YAML_CPP_API noncopyable
{
protected: protected:
noncopyable() {} noncopyable() {}
~noncopyable() {} ~noncopyable() {}
private: private:
noncopyable(const noncopyable&); noncopyable(const noncopyable&);
const noncopyable& operator = (const noncopyable&); const noncopyable& operator=(const noncopyable&);
}; };
} }
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,25 +1,26 @@
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <string>
namespace YAML namespace YAML {
{ class Node;
class Node;
struct YAML_CPP_API _Null {}; struct YAML_CPP_API _Null {};
inline bool operator == (const _Null&, const _Null&) { return true; } inline bool operator==(const _Null&, const _Null&) { return true; }
inline bool operator != (const _Null&, const _Null&) { return false; } inline bool operator!=(const _Null&, const _Null&) { return false; }
YAML_CPP_API bool IsNull(const Node& node); // old API only 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; extern YAML_CPP_API _Null Null;
} }
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,30 +1,31 @@
#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define 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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/dll.h"
{
class ostream_wrapper namespace YAML {
{ class YAML_CPP_API ostream_wrapper {
public: public:
ostream_wrapper(); ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream); explicit ostream_wrapper(std::ostream& stream);
~ostream_wrapper(); ~ostream_wrapper();
void write(const std::string& str); void write(const std::string& str);
void write(const char *str, std::size_t size); void write(const char* str, std::size_t size);
void set_comment() { m_comment = true; } void set_comment() { m_comment = true; }
const char *str() const { const char* str() const {
if(m_pStream) { if (m_pStream) {
return 0; return 0;
} else { } else {
m_buffer[m_pos] = '\0'; m_buffer[m_pos] = '\0';
@@ -42,28 +43,30 @@ namespace YAML
private: private:
mutable std::vector<char> m_buffer; mutable std::vector<char> m_buffer;
std::ostream *m_pStream; std::ostream* const m_pStream;
std::size_t m_pos; std::size_t m_pos;
std::size_t m_row, m_col; std::size_t m_row, m_col;
bool m_comment; bool m_comment;
}; };
template<std::size_t N> template <std::size_t N>
inline ostream_wrapper& operator << (ostream_wrapper& stream, const char (&str)[N]) { inline ostream_wrapper& operator<<(ostream_wrapper& stream,
stream.write(str, N-1); const char(&str)[N]) {
stream.write(str, N - 1);
return stream; return stream;
} }
inline ostream_wrapper& operator << (ostream_wrapper& stream, const std::string& str) { inline ostream_wrapper& operator<<(ostream_wrapper& stream,
const std::string& str) {
stream.write(str); stream.write(str);
return stream; return stream;
} }
inline ostream_wrapper& operator << (ostream_wrapper& stream, char ch) { inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
stream.write(&ch, 1); stream.write(&ch, 1);
return stream; return stream;
} }
} }
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,47 +1,86 @@
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h"
#include "yaml-cpp/noncopyable.h"
#include <ios> #include <ios>
#include <memory> #include <memory>
namespace YAML #include "yaml-cpp/dll.h"
{ #include "yaml-cpp/noncopyable.h"
struct Directives;
struct Token;
class EventHandler;
class Scanner;
class YAML_CPP_API Parser: private noncopyable 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: public:
/** Constructs an empty parser (with no input. */
Parser(); Parser();
Parser(std::istream& in);
/**
* Constructs a parser from the given input stream. The input stream must
* live as long as the parser.
*/
explicit Parser(std::istream& in);
~Parser(); ~Parser();
operator bool() const; /** 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); 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); bool HandleNextDocument(EventHandler& eventHandler);
void PrintTokens(std::ostream& out); void PrintTokens(std::ostream& out);
private: private:
/**
* Reads any directives that are next in the queue, setting the internal
* {@code m_pDirectives} state.
*/
void ParseDirectives(); void ParseDirectives();
void HandleDirective(const Token& token); 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); 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); void HandleTagDirective(const Token& token);
private: private:
std::auto_ptr<Scanner> m_pScanner; std::unique_ptr<Scanner> m_pScanner;
std::auto_ptr<Directives> m_pDirectives; std::unique_ptr<Directives> m_pDirectives;
}; };
} }
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,51 +1,51 @@
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <vector> #include <vector>
#include <list> #include <list>
#include <set> #include <set>
#include <map> #include <map>
namespace YAML namespace YAML {
{ template <typename Seq>
template<typename Seq> inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
emitter << BeginSeq; emitter << BeginSeq;
for(typename Seq::const_iterator it=seq.begin();it!=seq.end();++it) for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
emitter << *it; emitter << *it;
emitter << EndSeq; emitter << EndSeq;
return emitter; return emitter;
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::vector<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::vector<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::list<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::list<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::set<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template <typename K, typename V> template <typename K, typename V>
inline Emitter& operator << (Emitter& emitter, const std::map<K, V>& m) { inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
typedef typename std::map <K, V> map; typedef typename std::map<K, V> map;
emitter << BeginMap; emitter << BeginMap;
for(typename map::const_iterator it=m.begin();it!=m.end();++it) for (typename map::const_iterator it = m.begin(); it != m.end(); ++it)
emitter << Key << it->first << Value << it->second; emitter << Key << it->first << Value << it->second;
emitter << EndMap; emitter << EndMap;
return emitter; return emitter;
} }
} }
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,57 +1,103 @@
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML {
template <typename>
struct is_numeric {
enum { value = false };
};
namespace YAML template <>
{ struct is_numeric<char> {
template <typename> enum { value = true };
struct is_numeric { enum { value = false }; }; };
template <>
template <> struct is_numeric <char> { enum { value = true }; }; struct is_numeric<unsigned char> {
template <> struct is_numeric <unsigned char> { enum { value = true }; }; enum { value = true };
template <> struct is_numeric <int> { enum { value = true }; }; };
template <> struct is_numeric <unsigned int> { enum { value = true }; }; template <>
template <> struct is_numeric <long int> { enum { value = true }; }; struct is_numeric<int> {
template <> struct is_numeric <unsigned long int> { enum { value = true }; }; enum { value = true };
template <> struct is_numeric <short int> { enum { value = true }; }; };
template <> struct is_numeric <unsigned short int> { enum { value = true }; }; template <>
struct is_numeric<unsigned int> {
enum { value = true };
};
template <>
struct is_numeric<long int> {
enum { value = true };
};
template <>
struct is_numeric<unsigned long int> {
enum { value = true };
};
template <>
struct is_numeric<short int> {
enum { value = true };
};
template <>
struct is_numeric<unsigned short int> {
enum { value = true };
};
#if defined(_MSC_VER) && (_MSC_VER < 1310) #if defined(_MSC_VER) && (_MSC_VER < 1310)
template <> struct is_numeric <__int64> { enum { value = true }; }; template <>
template <> struct is_numeric <unsigned __int64> { enum { value = true }; }; struct is_numeric<__int64> {
enum { value = true };
};
template <>
struct is_numeric<unsigned __int64> {
enum { value = true };
};
#else #else
template <> struct is_numeric <long long> { enum { value = true }; }; template <>
template <> struct is_numeric <unsigned long long> { enum { value = true }; }; struct is_numeric<long long> {
enum { value = true };
};
template <>
struct is_numeric<unsigned long long> {
enum { value = true };
};
#endif #endif
template <> struct is_numeric <float> { enum { value = true }; }; template <>
template <> struct is_numeric <double> { enum { value = true }; }; struct is_numeric<float> {
template <> struct is_numeric <long double> { enum { value = true }; }; enum { value = true };
};
template <>
struct is_numeric<double> {
enum { value = true };
};
template <>
struct is_numeric<long double> {
enum { value = true };
};
template <bool, class T = void> template <bool, class T = void>
struct enable_if_c { struct enable_if_c {
typedef T type; typedef T type;
}; };
template <class T> template <class T>
struct enable_if_c<false, T> {}; struct enable_if_c<false, T> {};
template <class Cond, class T = void> template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {}; struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void> template <bool, class T = void>
struct disable_if_c { struct disable_if_c {
typedef T type; typedef T type;
}; };
template <class T> template <class T>
struct disable_if_c<true, T> {}; struct disable_if_c<true, T> {};
template <class Cond, class T = void> template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {}; struct disable_if : public disable_if_c<Cond::value, T> {};
} }
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,12 +1,15 @@
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/parser.h" #include "yaml-cpp/parser.h"
#include "yaml-cpp/emitter.h" #include "yaml-cpp/emitter.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/stlemitter.h" #include "yaml-cpp/stlemitter.h"
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"

View File

@@ -1,11 +1,10 @@
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
namespace YAML namespace YAML {
{ static const char encoding[] =
static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string EncodeBase64(const unsigned char *data, std::size_t size) std::string EncodeBase64(const unsigned char *data, std::size_t size) {
{
const char PAD = '='; const char PAD = '=';
std::string ret; std::string ret;
@@ -15,14 +14,14 @@ namespace YAML
std::size_t chunks = size / 3; std::size_t chunks = size / 3;
std::size_t remainder = size % 3; std::size_t remainder = size % 3;
for(std::size_t i=0;i<chunks;i++, data += 3) { for (std::size_t i = 0; i < chunks; i++, data += 3) {
*out++ = encoding[data[0] >> 2]; *out++ = encoding[data[0] >> 2];
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
*out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
*out++ = encoding[data[2] & 0x3f]; *out++ = encoding[data[2] & 0x3f];
} }
switch(remainder) { switch (remainder) {
case 0: case 0:
break; break;
case 1: case 1:
@@ -41,53 +40,54 @@ namespace YAML
ret.resize(out - &ret[0]); ret.resize(out - &ret[0]);
return ret; return ret;
} }
static const unsigned char decoding[] = { 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,255,255,255,255, 255, 255, 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, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 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, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 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) std::vector<unsigned char> DecodeBase64(const std::string &input) {
{
typedef std::vector<unsigned char> ret_type; typedef std::vector<unsigned char> ret_type;
if(input.empty()) if (input.empty())
return ret_type(); return ret_type();
ret_type ret(3 * input.size() / 4 + 1); ret_type ret(3 * input.size() / 4 + 1);
unsigned char *out = &ret[0]; unsigned char *out = &ret[0];
unsigned value = 0; unsigned value = 0;
for(std::size_t i=0;i<input.size();i++) { for (std::size_t i = 0; i < input.size(); i++) {
unsigned char d = decoding[static_cast<unsigned>(input[i])]; unsigned char d = decoding[static_cast<unsigned>(input[i])];
if(d == 255) if (d == 255)
return ret_type(); return ret_type();
value = (value << 6) | d; value = (value << 6) | d;
if(i % 4 == 3) { if (i % 4 == 3) {
*out++ = value >> 16; *out++ = value >> 16;
if(i > 0 && input[i - 1] != '=') if (i > 0 && input[i - 1] != '=')
*out++ = value >> 8; *out++ = value >> 8;
if(input[i] != '=') if (input[i] != '=')
*out++ = value; *out++ = value;
} }
} }
ret.resize(out - &ret[0]); ret.resize(out - &ret[0]);
return ret; return ret;
} }
} }

View File

@@ -1,35 +1,39 @@
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <stack> #include <stack>
#include <cassert> #include <cassert>
namespace YAML namespace YAML {
{ struct CollectionType {
struct CollectionType { enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
enum value { None, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; };
};
class CollectionStack class CollectionStack {
{
public: public:
CollectionType::value GetCurCollectionType() const { CollectionType::value GetCurCollectionType() const {
if(collectionStack.empty()) if (collectionStack.empty())
return CollectionType::None; return CollectionType::NoCollection;
return collectionStack.top(); return collectionStack.top();
} }
void PushCollectionType(CollectionType::value type) { collectionStack.push(type); } void PushCollectionType(CollectionType::value type) {
void PopCollectionType(CollectionType::value type) { assert(type == GetCurCollectionType()); collectionStack.pop(); } collectionStack.push(type);
}
void PopCollectionType(CollectionType::value type) {
assert(type == GetCurCollectionType());
collectionStack.pop();
}
private: private:
std::stack<CollectionType::value> collectionStack; std::stack<CollectionType::value> collectionStack;
}; };
} }
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

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

View File

@@ -1,81 +1,79 @@
#include "graphbuilderadapter.h" #include "graphbuilderadapter.h"
#include "yaml-cpp/contrib/graphbuilder.h"
namespace YAML namespace YAML {
{ struct Mark;
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
void GraphBuilderAdapter::OnNull(const Mark& mark, anchor_t anchor) int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
{
void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) {
void *pParent = GetCurrentParent(); void *pParent = GetCurrentParent();
void *pNode = m_builder.NewNull(mark, pParent); void *pNode = m_builder.NewNull(mark, pParent);
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
DispositionNode(pNode); DispositionNode(pNode);
} }
void GraphBuilderAdapter::OnAlias(const Mark& mark, anchor_t anchor) void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) {
{
void *pReffedNode = m_anchors.Get(anchor); void *pReffedNode = m_anchors.Get(anchor);
DispositionNode(m_builder.AnchorReference(mark, pReffedNode)); DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
} }
void GraphBuilderAdapter::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
{ anchor_t anchor, const std::string &value) {
void *pParent = GetCurrentParent(); void *pParent = GetCurrentParent();
void *pNode = m_builder.NewScalar(mark, tag, pParent, value); void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
DispositionNode(pNode); DispositionNode(pNode);
} }
void GraphBuilderAdapter::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
{ const std::string &tag,
anchor_t anchor,
EmitterStyle::value /* style */) {
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent()); void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode)); m_containers.push(ContainerFrame(pNode));
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
} }
void GraphBuilderAdapter::OnSequenceEnd() void GraphBuilderAdapter::OnSequenceEnd() {
{
void *pSequence = m_containers.top().pContainer; void *pSequence = m_containers.top().pContainer;
m_containers.pop(); m_containers.pop();
DispositionNode(pSequence); DispositionNode(pSequence);
} }
void GraphBuilderAdapter::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
{ anchor_t anchor,
EmitterStyle::value /* style */) {
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode)); m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = NULL; m_pKeyNode = NULL;
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
} }
void GraphBuilderAdapter::OnMapEnd() void GraphBuilderAdapter::OnMapEnd() {
{
void *pMap = m_containers.top().pContainer; void *pMap = m_containers.top().pContainer;
m_pKeyNode = m_containers.top().pPrevKeyNode; m_pKeyNode = m_containers.top().pPrevKeyNode;
m_containers.pop(); m_containers.pop();
DispositionNode(pMap); DispositionNode(pMap);
} }
void *GraphBuilderAdapter::GetCurrentParent() const void *GraphBuilderAdapter::GetCurrentParent() const {
{
if (m_containers.empty()) { if (m_containers.empty()) {
return NULL; return NULL;
} }
return m_containers.top().pContainer; return m_containers.top().pContainer;
} }
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) {
{
if (anchor) { if (anchor) {
m_anchors.Register(anchor, pNode); m_anchors.Register(anchor, pNode);
} }
} }
void GraphBuilderAdapter::DispositionNode(void *pNode) void GraphBuilderAdapter::DispositionNode(void *pNode) {
{
if (m_containers.empty()) { if (m_containers.empty()) {
m_pRootNode = pNode; m_pRootNode = pNode;
return; return;
@@ -92,5 +90,5 @@ namespace YAML
} else { } else {
m_builder.AppendToSequence(pContainer, pNode); m_builder.AppendToSequence(pContainer, pNode);
} }
} }
} }

View File

@@ -1,56 +1,62 @@
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstdlib> #include <cstdlib>
#include <map> #include <map>
#include <stack> #include <stack>
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h" #include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h" #include "yaml-cpp/contrib/graphbuilder.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
namespace YAML namespace YAML {
{ class GraphBuilderInterface;
class GraphBuilderAdapter : public EventHandler struct Mark;
{ } // namespace YAML
namespace YAML {
class GraphBuilderAdapter : public EventHandler {
public: public:
GraphBuilderAdapter(GraphBuilderInterface& builder) GraphBuilderAdapter(GraphBuilderInterface& builder)
: m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {}
{
}
virtual void OnDocumentStart(const Mark& mark) {(void)mark;} virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
virtual void OnDocumentEnd() {} virtual void OnDocumentEnd() {}
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(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 OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd(); virtual void OnMapEnd();
void *RootNode() const {return m_pRootNode;} void* RootNode() const { return m_pRootNode; }
private: private:
struct ContainerFrame struct ContainerFrame {
{ ContainerFrame(void* pSequence)
ContainerFrame(void *pSequence) : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) ContainerFrame(void* pMap, void* pPrevKeyNode)
{} : pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {}
ContainerFrame(void *pMap, void* pPrevKeyNode)
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode)
{}
void *pContainer; void* pContainer;
void *pPrevKeyNode; void* pPrevKeyNode;
bool isMap() const {return pPrevKeyNode != &sequenceMarker;} bool isMap() const { return pPrevKeyNode != &sequenceMarker; }
private: private:
static int sequenceMarker; static int sequenceMarker;
@@ -61,13 +67,13 @@ namespace YAML
GraphBuilderInterface& m_builder; GraphBuilderInterface& m_builder;
ContainerStack m_containers; ContainerStack m_containers;
AnchorMap m_anchors; AnchorMap m_anchors;
void *m_pRootNode; void* m_pRootNode;
void *m_pKeyNode; void* m_pKeyNode;
void *GetCurrentParent() const; void* GetCurrentParent() const;
void RegisterAnchor(anchor_t anchor, void *pNode); void RegisterAnchor(anchor_t anchor, void* pNode);
void DispositionNode(void *pNode); void DispositionNode(void* pNode);
}; };
} }
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,54 +1,49 @@
#include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/impl.h"
#include <algorithm> #include <algorithm>
namespace #include "yaml-cpp/node/convert.h"
{
// 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) 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::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower); std::transform(s.begin(), s.end(), s.begin(), ToLower);
return s; return s;
} }
template <typename T> template <typename T>
bool IsEntirely(const std::string& str, T func) bool IsEntirely(const std::string& str, T func) {
{ for (std::size_t i = 0; i < str.size(); i++)
for(std::size_t i=0;i<str.size();i++) if (!func(str[i]))
if(!func(str[i]))
return false; return false;
return true; return true;
} }
// IsFlexibleCase // IsFlexibleCase
// . Returns true if 'str' is: // . Returns true if 'str' is:
// . UPPERCASE // . UPPERCASE
// . lowercase // . lowercase
// . Capitalized // . Capitalized
bool IsFlexibleCase(const std::string& str) bool IsFlexibleCase(const std::string& str) {
{ if (str.empty())
if(str.empty())
return true; return true;
if(IsEntirely(str, IsLower)) if (IsEntirely(str, IsLower))
return true; return true;
bool firstcaps = IsUpper(str[0]); bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1); std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
} }
} }
namespace YAML namespace YAML {
{ bool convert<bool>::decode(const Node& node, bool& rhs) {
bool convert<bool>::decode(const Node& node, bool& rhs) { if (!node.IsScalar())
if(!node.IsScalar())
return false; return false;
// we can't use iostream bool extraction operators as they don't // we can't use iostream bool extraction operators as they don't
@@ -57,27 +52,24 @@ namespace YAML
static const struct { static const struct {
std::string truename, falsename; std::string truename, falsename;
} names[] = { } names[] = {
{ "y", "n" }, {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
{ "yes", "no" },
{ "true", "false" },
{ "on", "off" },
}; };
if(!IsFlexibleCase(node.Scalar())) if (!IsFlexibleCase(node.Scalar()))
return false; return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) { for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
if(names[i].truename == tolower(node.Scalar())) { if (names[i].truename == tolower(node.Scalar())) {
rhs = true; rhs = true;
return true; return true;
} }
if(names[i].falsename == tolower(node.Scalar())) { if (names[i].falsename == tolower(node.Scalar())) {
rhs = false; rhs = false;
return true; return true;
} }
} }
return false; return false;
} }
} }

View File

@@ -1,24 +1,22 @@
#include "directives.h" #include "directives.h"
namespace YAML namespace YAML {
{ Directives::Directives() {
Directives::Directives()
{
// version // version
version.isDefault = true; version.isDefault = true;
version.major = 1; version.major = 1;
version.minor = 2; version.minor = 2;
} }
const std::string Directives::TranslateTagHandle(const std::string& handle) const const std::string Directives::TranslateTagHandle(
{ const std::string& handle) const {
std::map <std::string, std::string>::const_iterator it = tags.find(handle); std::map<std::string, std::string>::const_iterator it = tags.find(handle);
if(it == tags.end()) { if (it == tags.end()) {
if(handle == "!!") if (handle == "!!")
return "tag:yaml.org,2002:"; return "tag:yaml.org,2002:";
return handle; return handle;
} }
return it->second; return it->second;
} }
} }

View File

@@ -1,29 +1,29 @@
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <map> #include <map>
namespace YAML namespace YAML {
{ struct Version {
struct Version {
bool isDefault; bool isDefault;
int major, minor; int major, minor;
}; };
struct Directives { struct Directives {
Directives(); Directives();
const std::string TranslateTagHandle(const std::string& handle) const; const std::string TranslateTagHandle(const std::string& handle) const;
Version version; Version version;
std::map<std::string, std::string> tags; std::map<std::string, std::string> tags;
}; };
} }
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

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

View File

@@ -1,87 +1,102 @@
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/null.h"
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/null.h"
namespace YAML {
struct Mark;
} // namespace YAML
namespace { namespace {
std::string ToString(YAML::anchor_t anchor) { std::string ToString(YAML::anchor_t anchor) {
std::stringstream stream; std::stringstream stream;
stream << anchor; stream << anchor;
return stream.str(); return stream.str();
} }
} }
namespace YAML namespace YAML {
{ EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {}
EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
{
}
void EmitFromEvents::OnDocumentStart(const Mark&) void EmitFromEvents::OnDocumentStart(const Mark&) {}
{
}
void EmitFromEvents::OnDocumentEnd() void EmitFromEvents::OnDocumentEnd() {}
{
}
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
{
BeginNode(); BeginNode();
EmitProps("", anchor); EmitProps("", anchor);
m_emitter << Null; m_emitter << Null;
} }
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) {
{
BeginNode(); BeginNode();
m_emitter << Alias(ToString(anchor)); m_emitter << Alias(ToString(anchor));
} }
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
{ anchor_t anchor, const std::string& value) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); EmitProps(tag, anchor);
m_emitter << value; m_emitter << value;
} }
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
{ anchor_t anchor,
EmitterStyle::value style) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); 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_emitter << BeginSeq;
m_stateStack.push(State::WaitingForSequenceEntry); m_stateStack.push(State::WaitingForSequenceEntry);
} }
void EmitFromEvents::OnSequenceEnd() void EmitFromEvents::OnSequenceEnd() {
{
m_emitter << EndSeq; m_emitter << EndSeq;
assert(m_stateStack.top() == State::WaitingForSequenceEntry); assert(m_stateStack.top() == State::WaitingForSequenceEntry);
m_stateStack.pop(); m_stateStack.pop();
} }
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
{ anchor_t anchor, EmitterStyle::value style) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); 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_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey); m_stateStack.push(State::WaitingForKey);
} }
void EmitFromEvents::OnMapEnd() void EmitFromEvents::OnMapEnd() {
{
m_emitter << EndMap; m_emitter << EndMap;
assert(m_stateStack.top() == State::WaitingForKey); assert(m_stateStack.top() == State::WaitingForKey);
m_stateStack.pop(); m_stateStack.pop();
} }
void EmitFromEvents::BeginNode() void EmitFromEvents::BeginNode() {
{ if (m_stateStack.empty())
if(m_stateStack.empty())
return; return;
switch(m_stateStack.top()) { switch (m_stateStack.top()) {
case State::WaitingForKey: case State::WaitingForKey:
m_emitter << Key; m_emitter << Key;
m_stateStack.top() = State::WaitingForValue; m_stateStack.top() = State::WaitingForValue;
@@ -93,13 +108,12 @@ namespace YAML
default: default:
break; break;
} }
} }
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
{ if (!tag.empty() && tag != "?" && tag != "!")
if(!tag.empty() && tag != "?") m_emitter << VerbatimTag(tag);
m_emitter << VerbatimTag(tag); if (anchor)
if(anchor) m_emitter << Anchor(ToString(anchor));
m_emitter << Anchor(ToString(anchor)); }
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,16 @@
#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits> #include <limits>
namespace YAML #include "emitterstate.h"
{ #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
{ 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 // set default global manipulators
m_charset.set(EmitNonAscii); m_charset.set(EmitNonAscii);
m_strFmt.set(Auto); m_strFmt.set(Auto);
@@ -21,17 +26,14 @@ namespace YAML
m_mapKeyFmt.set(Auto); m_mapKeyFmt.set(Auto);
m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1); m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1); m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
} }
EmitterState::~EmitterState() EmitterState::~EmitterState() {}
{
}
// SetLocalValue // SetLocalValue
// . We blindly tries to set all possible formatters to this value // . We blindly tries to set all possible formatters to this value
// . Only the ones that make sense will be accepted // . Only the ones that make sense will be accepted
void EmitterState::SetLocalValue(EMITTER_MANIP value) void EmitterState::SetLocalValue(EMITTER_MANIP value) {
{
SetOutputCharset(value, FmtScope::Local); SetOutputCharset(value, FmtScope::Local);
SetStringFormat(value, FmtScope::Local); SetStringFormat(value, FmtScope::Local);
SetBoolFormat(value, FmtScope::Local); SetBoolFormat(value, FmtScope::Local);
@@ -41,66 +43,57 @@ namespace YAML
SetFlowType(GroupType::Seq, value, FmtScope::Local); SetFlowType(GroupType::Seq, value, FmtScope::Local);
SetFlowType(GroupType::Map, value, FmtScope::Local); SetFlowType(GroupType::Map, value, FmtScope::Local);
SetMapKeyFormat(value, FmtScope::Local); SetMapKeyFormat(value, FmtScope::Local);
} }
void EmitterState::SetAnchor() void EmitterState::SetAnchor() { m_hasAnchor = true; }
{
m_hasAnchor = true;
}
void EmitterState::SetTag() void EmitterState::SetTag() { m_hasTag = true; }
{
m_hasTag = true;
}
void EmitterState::SetNonContent() void EmitterState::SetNonContent() { m_hasNonContent = true; }
{
m_hasNonContent = true;
}
void EmitterState::SetLongKey() void EmitterState::SetLongKey() {
{
assert(!m_groups.empty()); assert(!m_groups.empty());
if(m_groups.empty()) if (m_groups.empty()) {
return; return;
assert(m_groups.top().type == GroupType::Map);
m_groups.top().longKey = true;
} }
void EmitterState::ForceFlow() assert(m_groups.back()->type == GroupType::Map);
{ m_groups.back()->longKey = true;
}
void EmitterState::ForceFlow() {
assert(!m_groups.empty()); assert(!m_groups.empty());
if(m_groups.empty()) if (m_groups.empty()) {
return; return;
m_groups.top().flowType = FlowType::Flow;
} }
void EmitterState::StartedNode() m_groups.back()->flowType = FlowType::Flow;
{ }
if(m_groups.empty()) {
void EmitterState::StartedNode() {
if (m_groups.empty()) {
m_docCount++; m_docCount++;
} else { } else {
m_groups.top().childCount++; m_groups.back()->childCount++;
if(m_groups.top().childCount % 2 == 0) if (m_groups.back()->childCount % 2 == 0) {
m_groups.top().longKey = false; m_groups.back()->longKey = false;
}
} }
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const EmitterNodeType::value EmitterState::NextGroupType(
{ GroupType::value type) const {
if(type == GroupType::Seq) { if (type == GroupType::Seq) {
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq; return EmitterNodeType::BlockSeq;
else else
return EmitterNodeType::FlowSeq; return EmitterNodeType::FlowSeq;
} else { } else {
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block)
return EmitterNodeType::BlockMap; return EmitterNodeType::BlockMap;
else else
return EmitterNodeType::FlowMap; return EmitterNodeType::FlowMap;
@@ -108,69 +101,73 @@ namespace YAML
// can't happen // can't happen
assert(false); assert(false);
return EmitterNodeType::None; return EmitterNodeType::NoType;
} }
void EmitterState::StartedDoc() void EmitterState::StartedDoc() {
{
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
void EmitterState::EndedDoc() void EmitterState::EndedDoc() {
{
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
void EmitterState::StartedScalar() void EmitterState::StartedScalar() {
{
StartedNode(); StartedNode();
ClearModifiedSettings(); ClearModifiedSettings();
} }
void EmitterState::StartedGroup(GroupType::value type) void EmitterState::StartedGroup(GroupType::value type) {
{
StartedNode(); StartedNode();
const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent); const std::size_t lastGroupIndent =
(m_groups.empty() ? 0 : m_groups.back()->indent);
m_curIndent += lastGroupIndent; m_curIndent += lastGroupIndent;
std::auto_ptr<Group> pGroup(new Group(type)); // 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) // transfer settings (which last until this group is done)
pGroup->modifiedSettings = m_modifiedSettings; //
// NB: if pGroup->modifiedSettings == m_modifiedSettings,
// m_modifiedSettings is not changed!
pGroup->modifiedSettings = std::move(m_modifiedSettings);
// set up group // set up group
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block) {
pGroup->flowType = FlowType::Block; pGroup->flowType = FlowType::Block;
else } else {
pGroup->flowType = FlowType::Flow; pGroup->flowType = FlowType::Flow;
}
pGroup->indent = GetIndent(); pGroup->indent = GetIndent();
m_groups.push(pGroup); m_groups.push_back(std::move(pGroup));
} }
void EmitterState::EndedGroup(GroupType::value type) void EmitterState::EndedGroup(GroupType::value type) {
{ if (m_groups.empty()) {
if(m_groups.empty()) { if (type == GroupType::Seq) {
if(type == GroupType::Seq)
return SetError(ErrorMsg::UNEXPECTED_END_SEQ); return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
else } else {
return SetError(ErrorMsg::UNEXPECTED_END_MAP); return SetError(ErrorMsg::UNEXPECTED_END_MAP);
} }
}
// get rid of the current group // get rid of the current group
{ {
std::auto_ptr<Group> pFinishedGroup = m_groups.pop(); std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
if(pFinishedGroup->type != type) m_groups.pop_back();
if (pFinishedGroup->type != type) {
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG); return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
} }
}
// reset old settings // reset old settings
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent); std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
assert(m_curIndent >= lastIndent); assert(m_curIndent >= lastIndent);
m_curIndent -= lastIndent; m_curIndent -= lastIndent;
@@ -179,57 +176,49 @@ namespace YAML
m_globalModifiedSettings.restore(); m_globalModifiedSettings.restore();
ClearModifiedSettings(); ClearModifiedSettings();
}
EmitterNodeType::value EmitterState::CurGroupNodeType() const {
if (m_groups.empty()) {
return EmitterNodeType::NoType;
} }
EmitterNodeType::value EmitterState::CurGroupNodeType() const return m_groups.back()->NodeType();
{ }
if(m_groups.empty())
return EmitterNodeType::None;
return m_groups.top().NodeType(); GroupType::value EmitterState::CurGroupType() const {
} return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
}
GroupType::value EmitterState::CurGroupType() const FlowType::value EmitterState::CurGroupFlowType() const {
{ return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
return m_groups.empty() ? GroupType::None : m_groups.top().type; }
}
FlowType::value EmitterState::CurGroupFlowType() const std::size_t EmitterState::CurGroupIndent() const {
{ return m_groups.empty() ? 0 : m_groups.back()->indent;
return m_groups.empty() ? FlowType::None : m_groups.top().flowType; }
}
int EmitterState::CurGroupIndent() const std::size_t EmitterState::CurGroupChildCount() const {
{ return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
return m_groups.empty() ? 0 : m_groups.top().indent; }
}
std::size_t EmitterState::CurGroupChildCount() const bool EmitterState::CurGroupLongKey() const {
{ return m_groups.empty() ? false : m_groups.back()->longKey;
return m_groups.empty() ? m_docCount : m_groups.top().childCount; }
}
bool EmitterState::CurGroupLongKey() const std::size_t EmitterState::LastIndent() const {
{ if (m_groups.size() <= 1) {
return m_groups.empty() ? false : m_groups.top().longKey;
}
int EmitterState::LastIndent() const
{
if(m_groups.size() <= 1)
return 0; return 0;
return m_curIndent - m_groups.top(-1).indent;
} }
void EmitterState::ClearModifiedSettings() return m_curIndent - m_groups[m_groups.size() - 2]->indent;
{ }
m_modifiedSettings.clear();
}
bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope) void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
{
switch(value) { bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case EmitNonAscii: case EmitNonAscii:
case EscapeNonAscii: case EscapeNonAscii:
_Set(m_charset, value, scope); _Set(m_charset, value, scope);
@@ -237,11 +226,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Auto: case Auto:
case SingleQuoted: case SingleQuoted:
case DoubleQuoted: case DoubleQuoted:
@@ -251,11 +239,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case OnOffBool: case OnOffBool:
case TrueFalseBool: case TrueFalseBool:
case YesNoBool: case YesNoBool:
@@ -264,11 +251,11 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case LongBool: case LongBool:
case ShortBool: case ShortBool:
_Set(m_boolLengthFmt, value, scope); _Set(m_boolLengthFmt, value, scope);
@@ -276,11 +263,11 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case UpperCase: case UpperCase:
case LowerCase: case LowerCase:
case CamelCase: case CamelCase:
@@ -289,11 +276,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Dec: case Dec:
case Hex: case Hex:
case Oct: case Oct:
@@ -302,38 +288,37 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
{ if (value <= 1)
if(value <= 1)
return false; return false;
_Set(m_indent, value, scope); _Set(m_indent, value, scope);
return true; return true;
} }
bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetPreCommentIndent(std::size_t value,
{ FmtScope::value scope) {
if(value == 0) if (value == 0)
return false; return false;
_Set(m_preCommentIndent, value, scope); _Set(m_preCommentIndent, value, scope);
return true; return true;
} }
bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetPostCommentIndent(std::size_t value,
{ FmtScope::value scope) {
if(value == 0) if (value == 0)
return false; return false;
_Set(m_postCommentIndent, value, scope); _Set(m_postCommentIndent, value, scope);
return true; return true;
} }
bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case Block: case Block:
case Flow: case Flow:
_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope); _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
@@ -341,21 +326,19 @@ namespace YAML
default: default:
return false; return false;
} }
} }
EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
{
// force flow style if we're currently in a flow // force flow style if we're currently in a flow
if(CurGroupFlowType() == FlowType::Flow) if (CurGroupFlowType() == FlowType::Flow)
return Flow; return Flow;
// otherwise, go with what's asked of us // otherwise, go with what's asked of us
return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get()); return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
} }
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Auto: case Auto:
case LongKey: case LongKey:
_Set(m_mapKeyFmt, value, scope); _Set(m_mapKeyFmt, value, scope);
@@ -363,22 +346,20 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope) bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
{ if (value > std::numeric_limits<float>::digits10 + 1)
if(value < 0 || value > std::numeric_limits<float>::digits10 + 1)
return false; return false;
_Set(m_floatPrecision, value, scope); _Set(m_floatPrecision, value, scope);
return true; return true;
} }
bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope) bool EmitterState::SetDoublePrecision(std::size_t value,
{ FmtScope::value scope) {
if(value < 0 || value > std::numeric_limits<double>::digits10 + 1) if (value > std::numeric_limits<double>::digits10 + 1)
return false; return false;
_Set(m_doublePrecision, value, scope); _Set(m_doublePrecision, value, scope);
return true; return true;
}
} }
}

View File

@@ -1,29 +1,34 @@
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "ptr_stack.h"
#include "setting.h" #include "setting.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h" #include "yaml-cpp/emittermanip.h"
#include <cassert> #include <cassert>
#include <vector>
#include <stack>
#include <memory> #include <memory>
#include <stack>
#include <stdexcept> #include <stdexcept>
#include <vector>
namespace YAML namespace YAML {
{ struct FmtScope {
struct FmtScope { enum value { Local, Global }; }; enum value { Local, Global };
struct GroupType { enum value { None, Seq, Map }; }; };
struct FlowType { enum value { None, Flow, Block }; }; struct GroupType {
enum value { NoType, Seq, Map };
};
struct FlowType {
enum value { NoType, Flow, Block };
};
class EmitterState class EmitterState {
{
public: public:
EmitterState(); EmitterState();
~EmitterState(); ~EmitterState();
@@ -31,7 +36,10 @@ namespace YAML
// basic state checking // basic state checking
bool good() const { return m_isGood; } bool good() const { return m_isGood; }
const std::string GetLastError() const { return m_lastError; } const std::string GetLastError() const { return m_lastError; }
void SetError(const std::string& error) { m_isGood = false; m_lastError = error; } void SetError(const std::string& error) {
m_isGood = false;
m_lastError = error;
}
// node handling // node handling
void SetAnchor(); void SetAnchor();
@@ -50,15 +58,17 @@ namespace YAML
GroupType::value CurGroupType() const; GroupType::value CurGroupType() const;
FlowType::value CurGroupFlowType() const; FlowType::value CurGroupFlowType() const;
int CurGroupIndent() const; std::size_t CurGroupIndent() const;
std::size_t CurGroupChildCount() const; std::size_t CurGroupChildCount() const;
bool CurGroupLongKey() const; bool CurGroupLongKey() const;
int LastIndent() const; std::size_t LastIndent() const;
int CurIndent() const { return m_curIndent; } std::size_t CurIndent() const { return m_curIndent; }
bool HasAnchor() const { return m_hasAnchor; } bool HasAnchor() const { return m_hasAnchor; }
bool HasTag() const { return m_hasTag; } bool HasTag() const { return m_hasTag; }
bool HasBegunNode() const { return m_hasAnchor || m_hasTag || m_hasNonContent; } bool HasBegunNode() const {
return m_hasAnchor || m_hasTag || m_hasNonContent;
}
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; } bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
void ClearModifiedSettings(); void ClearModifiedSettings();
@@ -84,24 +94,25 @@ namespace YAML
bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope); bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); } EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
bool SetIndent(unsigned value, FmtScope::value scope); bool SetIndent(std::size_t value, FmtScope::value scope);
int GetIndent() const { return m_indent.get(); } std::size_t GetIndent() const { return m_indent.get(); }
bool SetPreCommentIndent(unsigned value, FmtScope::value scope); bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
int GetPreCommentIndent() const { return m_preCommentIndent.get(); } std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
bool SetPostCommentIndent(unsigned value, FmtScope::value scope); bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
int GetPostCommentIndent() const { return m_postCommentIndent.get(); } std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope); bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope);
EMITTER_MANIP GetFlowType(GroupType::value groupType) const; EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope); bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); } EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
bool SetFloatPrecision(int value, FmtScope::value scope); bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
unsigned GetFloatPrecision() const { return m_floatPrecision.get(); } std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
bool SetDoublePrecision(int value, FmtScope::value scope); bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
unsigned GetDoublePrecision() const { return m_doublePrecision.get(); } std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
private: private:
template <typename T> template <typename T>
@@ -121,36 +132,37 @@ namespace YAML
Setting<EMITTER_MANIP> m_boolLengthFmt; Setting<EMITTER_MANIP> m_boolLengthFmt;
Setting<EMITTER_MANIP> m_boolCaseFmt; Setting<EMITTER_MANIP> m_boolCaseFmt;
Setting<EMITTER_MANIP> m_intFmt; Setting<EMITTER_MANIP> m_intFmt;
Setting<unsigned> m_indent; Setting<std::size_t> m_indent;
Setting<unsigned> m_preCommentIndent, m_postCommentIndent; Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
Setting<EMITTER_MANIP> m_seqFmt; Setting<EMITTER_MANIP> m_seqFmt;
Setting<EMITTER_MANIP> m_mapFmt; Setting<EMITTER_MANIP> m_mapFmt;
Setting<EMITTER_MANIP> m_mapKeyFmt; Setting<EMITTER_MANIP> m_mapKeyFmt;
Setting<int> m_floatPrecision; Setting<std::size_t> m_floatPrecision;
Setting<int> m_doublePrecision; Setting<std::size_t> m_doublePrecision;
SettingChanges m_modifiedSettings; SettingChanges m_modifiedSettings;
SettingChanges m_globalModifiedSettings; SettingChanges m_globalModifiedSettings;
struct Group { struct Group {
explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0), longKey(false) {} explicit Group(GroupType::value type_)
: type(type_), indent(0), childCount(0), longKey(false) {}
GroupType::value type; GroupType::value type;
FlowType::value flowType; FlowType::value flowType;
int indent; std::size_t indent;
std::size_t childCount; std::size_t childCount;
bool longKey; bool longKey;
SettingChanges modifiedSettings; SettingChanges modifiedSettings;
EmitterNodeType::value NodeType() const { EmitterNodeType::value NodeType() const {
if(type == GroupType::Seq) { if (type == GroupType::Seq) {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow)
return EmitterNodeType::FlowSeq; return EmitterNodeType::FlowSeq;
else else
return EmitterNodeType::BlockSeq; return EmitterNodeType::BlockSeq;
} else { } else {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow)
return EmitterNodeType::FlowMap; return EmitterNodeType::FlowMap;
else else
return EmitterNodeType::BlockMap; return EmitterNodeType::BlockMap;
@@ -158,33 +170,34 @@ namespace YAML
// can't get here // can't get here
assert(false); assert(false);
return EmitterNodeType::None; return EmitterNodeType::NoType;
} }
}; };
ptr_stack<Group> m_groups; std::vector<std::unique_ptr<Group>> m_groups;
unsigned m_curIndent; std::size_t m_curIndent;
bool m_hasAnchor; bool m_hasAnchor;
bool m_hasTag; bool m_hasTag;
bool m_hasNonContent; bool m_hasNonContent;
std::size_t m_docCount; std::size_t m_docCount;
}; };
template <typename T> template <typename T>
void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) { void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
switch(scope) { switch (scope) {
case FmtScope::Local: case FmtScope::Local:
m_modifiedSettings.push(fmt.set(value)); m_modifiedSettings.push(fmt.set(value));
break; break;
case FmtScope::Global: case FmtScope::Global:
fmt.set(value); fmt.set(value);
m_globalModifiedSettings.push(fmt.set(value)); // this pushes an identity set, so when we restore, 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 // it restores to the value here, and not the previous one
break; break;
default: default:
assert(false); assert(false);
} }
} }
} }
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,56 +1,79 @@
#include <iomanip>
#include <sstream>
#include "emitterutils.h" #include "emitterutils.h"
#include "exp.h" #include "exp.h"
#include "indentation.h" #include "indentation.h"
#include "yaml-cpp/binary.h" #include "regex_yaml.h"
#include "yaml-cpp/exceptions.h" #include "regeximpl.h"
#include "stringsource.h" #include "stringsource.h"
#include <sstream> #include "yaml-cpp/binary.h" // IWYU pragma: keep
#include <iomanip> #include "yaml-cpp/ostream_wrapper.h"
#include "yaml-cpp/null.h"
namespace YAML namespace YAML {
{ namespace Utils {
namespace Utils namespace {
{ enum { REPLACEMENT_CHARACTER = 0xFFFD };
namespace {
enum {REPLACEMENT_CHARACTER = 0xFFFD};
bool IsAnchorChar(int ch) { // test for ns-anchor-char bool IsAnchorChar(int ch) { // test for ns-anchor-char
switch (ch) { switch (ch) {
case ',': case '[': case ']': case '{': case '}': // c-flow-indicator case ',':
case ' ': case '\t': // s-white case '[':
case ']':
case '{':
case '}': // c-flow-indicator
case ' ':
case '\t': // s-white
case 0xFEFF: // c-byte-order-mark case 0xFEFF: // c-byte-order-mark
case 0xA: case 0xD: // b-char case 0xA:
case 0xD: // b-char
return false; return false;
case 0x85: case 0x85:
return true; return true;
} }
if (ch < 0x20) if (ch < 0x20) {
return false;
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 false;
}
if (ch < 0x7E) {
return true; return true;
} }
int Utf8BytesIndicated(char ch) { 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); int byteVal = static_cast<unsigned char>(ch);
switch (byteVal >> 4) { switch (byteVal >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
return 1; return 1;
case 12: case 13: case 12:
case 13:
return 2; return 2;
case 14: case 14:
return 3; return 3;
@@ -59,13 +82,13 @@ namespace YAML
default: default:
return -1; return -1;
} }
} }
bool IsTrailingByte(char ch) { bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
return (ch & 0xC0) == 0x80;
}
bool GetNextCodePointAndAdvance(int& codePoint, std::string::const_iterator& first, std::string::const_iterator last) { bool GetNextCodePointAndAdvance(int& codePoint,
std::string::const_iterator& first,
std::string::const_iterator last) {
if (first == last) if (first == last)
return false; return false;
@@ -105,9 +128,9 @@ namespace YAML
else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF) else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
codePoint = REPLACEMENT_CHARACTER; codePoint = REPLACEMENT_CHARACTER;
return true; return true;
} }
void WriteCodePoint(ostream_wrapper& out, int codePoint) { void WriteCodePoint(ostream_wrapper& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) { if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER; codePoint = REPLACEMENT_CHARACTER;
} }
@@ -126,74 +149,91 @@ namespace YAML
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F)) << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 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;
} }
bool IsValidPlainScalar(const std::string& str, FlowType::value flowType, bool allowOnlyAscii) { // check the start
if(str.empty()) const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
: Exp::PlainScalar());
if (!start.Matches(str)) {
return false; return false;
}
// first check the start // and check the end for plain whitespace (which can't be faithfully kept in a
const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow() : Exp::PlainScalar()); // plain scalar)
if(!start.Matches(str)) if (!str.empty() && *str.rbegin() == ' ') {
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; return false;
}
// then check until something is disallowed // then check until something is disallowed
const RegEx& disallowed = (flowType == FlowType::Flow ? Exp::EndScalarInFlow() : Exp::EndScalar()) static const RegEx& disallowed_flow =
|| (Exp::BlankOrBreak() + Exp::Comment()) Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) ||
|| Exp::NotPrintable() Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
|| Exp::Utf8_ByteOrderMark() Exp::Tab();
|| Exp::Break() static const RegEx& disallowed_block =
|| Exp::Tab(); 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()); StringCharSource buffer(str.c_str(), str.size());
while(buffer) { while (buffer) {
if(disallowed.Matches(buffer)) if (disallowed.Matches(buffer)) {
return false; return false;
if(allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) }
if (allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) {
return false; return false;
}
++buffer; ++buffer;
} }
return true; return true;
} }
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
{
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
return false; return false;
if(str[i] == '\n') }
if (str[i] == '\n') {
return false; return false;
} }
}
return true; return true;
} }
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, bool escapeNonAscii) bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
{ bool escapeNonAscii) {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow) {
return false; return false;
}
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
return false; return false;
} }
return true;
} }
return true;
}
void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
static const char hexDigits[] = "0123456789abcdef"; static const char hexDigits[] = "0123456789abcdef";
out << "\\"; out << "\\";
int digits = 8; int digits = 8;
if(codePoint < 0xFF) { if (codePoint < 0xFF) {
out << "x"; out << "x";
digits = 2; digits = 2;
} else if(codePoint < 0xFFFF) { } else if (codePoint < 0xFFFF) {
out << "u"; out << "u";
digits = 4; digits = 4;
} else { } else {
@@ -204,196 +244,215 @@ namespace YAML
// Write digits into the escape sequence // Write digits into the escape sequence
for (; digits > 0; --digits) for (; digits > 0; --digits)
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
} }
bool WriteAliasName(ostream_wrapper& out, const std::string& str) { bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) if (!IsAnchorChar(codePoint)) {
{
if (!IsAnchorChar(codePoint))
return false; return false;
}
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
return true; return true;
} }
} }
StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii) StringFormat::value ComputeStringFormat(const std::string& str,
{ EMITTER_MANIP strFormat,
switch(strFormat) { FlowType::value flowType,
bool escapeNonAscii) {
switch (strFormat) {
case Auto: case Auto:
if(IsValidPlainScalar(str, flowType, escapeNonAscii)) if (IsValidPlainScalar(str, flowType, escapeNonAscii)) {
return StringFormat::Plain; return StringFormat::Plain;
}
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case SingleQuoted: case SingleQuoted:
if(IsValidSingleQuotedScalar(str, escapeNonAscii)) if (IsValidSingleQuotedScalar(str, escapeNonAscii)) {
return StringFormat::SingleQuoted; return StringFormat::SingleQuoted;
}
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case DoubleQuoted: case DoubleQuoted:
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case Literal: case Literal:
if(IsValidLiteralScalar(str, flowType, escapeNonAscii)) if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) {
return StringFormat::Literal; return StringFormat::Literal;
}
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
default: default:
break; break;
} }
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
} }
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
{
out << "'"; out << "'";
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) if (codePoint == '\n') {
{ return false; // We can't handle a new line and the attendant indentation
if (codePoint == '\n') // yet
return false; // We can't handle a new line and the attendant indentation yet }
if (codePoint == '\'') if (codePoint == '\'') {
out << "''"; out << "''";
else } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
}
out << "'"; out << "'";
return true; return true;
} }
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii) bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
{ bool escapeNonAscii) {
out << "\""; out << "\"";
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) switch (codePoint) {
{ case '\"':
switch(codePoint) { out << "\\\"";
case '\"': out << "\\\""; break; break;
case '\\': out << "\\\\"; break; case '\\':
case '\n': out << "\\n"; break; out << "\\\\";
case '\t': out << "\\t"; break; break;
case '\r': out << "\\r"; break; case '\n':
case '\b': out << "\\b"; break; out << "\\n";
break;
case '\t':
out << "\\t";
break;
case '\r':
out << "\\r";
break;
case '\b':
out << "\\b";
break;
default: default:
if(codePoint < 0x20 || (codePoint >= 0x80 && codePoint <= 0xA0)) // Control characters and non-breaking space if (codePoint < 0x20 ||
(codePoint >= 0x80 &&
codePoint <= 0xA0)) { // Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (codePoint == 0xFEFF) // Byte order marks (ZWNS) should be escaped (YAML 1.2, sec. 5.2) } else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (escapeNonAscii && codePoint > 0x7E) } else if (escapeNonAscii && codePoint > 0x7E) {
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
else } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
} }
}
out << "\""; out << "\"";
return true; return true;
} }
bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent) bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
{ std::size_t indent) {
out << "|\n"; out << "|\n";
out << IndentTo(indent); out << IndentTo(indent);
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) if (codePoint == '\n') {
{
if (codePoint == '\n')
out << "\n" << IndentTo(indent); out << "\n" << IndentTo(indent);
else } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
return true;
} }
return true;
}
bool WriteChar(ostream_wrapper& out, char ch) bool WriteChar(ostream_wrapper& out, char ch) {
{ if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
out << ch; out << ch;
else if((0x20 <= ch && ch <= 0x7e) || ch == ' ') } else if (ch == '\"') {
out << "\"" << ch << "\""; out << "\"\\\"\"";
else if(ch == '\t') } else if (ch == '\t') {
out << "\"\\t\""; out << "\"\\t\"";
else if(ch == '\n') } else if (ch == '\n') {
out << "\"\\n\""; out << "\"\\n\"";
else if(ch == '\b') } else if (ch == '\b') {
out << "\"\\b\""; out << "\"\\b\"";
else { } else if (ch == '\\') {
out << "\"\\\\\"";
} else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') {
out << "\"" << ch << "\"";
} else {
out << "\""; out << "\"";
WriteDoubleQuoteEscapeSequence(out, ch); WriteDoubleQuoteEscapeSequence(out, ch);
out << "\""; out << "\"";
} }
return true; return true;
} }
bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent) bool WriteComment(ostream_wrapper& out, const std::string& str,
{ std::size_t postCommentIndent) {
const unsigned curIndent = out.col(); const std::size_t curIndent = out.col();
out << "#" << Indentation(postCommentIndent); out << "#" << Indentation(postCommentIndent);
out.set_comment(); out.set_comment();
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) if (codePoint == '\n') {
{ out << "\n" << IndentTo(curIndent) << "#"
if(codePoint == '\n') { << Indentation(postCommentIndent);
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
out.set_comment(); out.set_comment();
} else { } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
} }
return true; return true;
} }
bool WriteAlias(ostream_wrapper& out, const std::string& str) bool WriteAlias(ostream_wrapper& out, const std::string& str) {
{
out << "*"; out << "*";
return WriteAliasName(out, str); return WriteAliasName(out, str);
} }
bool WriteAnchor(ostream_wrapper& out, const std::string& str) bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
{
out << "&"; out << "&";
return WriteAliasName(out, str); return WriteAliasName(out, str);
} }
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
{
out << (verbatim ? "!<" : "!"); out << (verbatim ? "!<" : "!");
StringCharSource buffer(str.c_str(), str.size()); StringCharSource buffer(str.c_str(), str.size());
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag(); const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
while(buffer) { while (buffer) {
int n = reValid.Match(buffer); int n = reValid.Match(buffer);
if(n <= 0) if (n <= 0) {
return false; return false;
}
while(--n >= 0) { while (--n >= 0) {
out << buffer[0]; out << buffer[0];
++buffer; ++buffer;
} }
} }
if (verbatim) if (verbatim) {
out << ">"; out << ">";
return true;
} }
return true;
}
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag) bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
{ const std::string& tag) {
out << "!"; out << "!";
StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
while(prefixBuffer) { while (prefixBuffer) {
int n = Exp::URI().Match(prefixBuffer); int n = Exp::URI().Match(prefixBuffer);
if(n <= 0) if (n <= 0) {
return false; return false;
}
while(--n >= 0) { while (--n >= 0) {
out << prefixBuffer[0]; out << prefixBuffer[0];
++prefixBuffer; ++prefixBuffer;
} }
@@ -401,24 +460,24 @@ namespace YAML
out << "!"; out << "!";
StringCharSource tagBuffer(tag.c_str(), tag.size()); StringCharSource tagBuffer(tag.c_str(), tag.size());
while(tagBuffer) { while (tagBuffer) {
int n = Exp::Tag().Match(tagBuffer); int n = Exp::Tag().Match(tagBuffer);
if(n <= 0) if (n <= 0) {
return false; return false;
}
while(--n >= 0) { while (--n >= 0) {
out << tagBuffer[0]; out << tagBuffer[0];
++tagBuffer; ++tagBuffer;
} }
} }
return true; return true;
}
bool WriteBinary(ostream_wrapper& out, const Binary& binary)
{
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false);
return true;
}
}
} }
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
false);
return true;
}
}
}

View File

@@ -1,36 +1,50 @@
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "emitterstate.h"
#include "yaml-cpp/ostream_wrapper.h"
#include <string> #include <string>
namespace YAML #include "emitterstate.h"
{ #include "yaml-cpp/emittermanip.h"
class Binary; #include "yaml-cpp/ostream_wrapper.h"
struct StringFormat { enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; }; namespace YAML {
class ostream_wrapper;
} // namespace YAML
namespace Utils namespace YAML {
{ class Binary;
StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii);
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); struct StringFormat {
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii); enum value { Plain, SingleQuoted, DoubleQuoted, Literal };
bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent); };
bool WriteChar(ostream_wrapper& out, char ch);
bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent); namespace Utils {
bool WriteAlias(ostream_wrapper& out, const std::string& str); StringFormat::value ComputeStringFormat(const std::string& str,
bool WriteAnchor(ostream_wrapper& out, const std::string& str); EMITTER_MANIP strFormat,
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); FlowType::value flowType,
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag); bool escapeNonAscii);
bool WriteBinary(ostream_wrapper& out, const Binary& binary);
} 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,22 +1,25 @@
#include "exp.h"
#include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
namespace YAML #include "exp.h"
{ #include "stream.h"
namespace Exp #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
{
unsigned ParseHex(const std::string& str, const Mark& mark) namespace YAML {
{ struct Mark;
} // namespace YAML
namespace YAML {
namespace Exp {
unsigned ParseHex(const std::string& str, const Mark& mark) {
unsigned value = 0; unsigned value = 0;
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
char ch = str[i]; char ch = str[i];
int digit = 0; int digit = 0;
if('a' <= ch && ch <= 'f') if ('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10; digit = ch - 'a' + 10;
else if('A' <= ch && ch <= 'F') else if ('A' <= ch && ch <= 'F')
digit = ch - 'A' + 10; digit = ch - 'A' + 10;
else if('0' <= ch && ch <= '9') else if ('0' <= ch && ch <= '9')
digit = ch - '0'; digit = ch - '0';
else else
throw ParserException(mark, ErrorMsg::INVALID_HEX); throw ParserException(mark, ErrorMsg::INVALID_HEX);
@@ -25,51 +28,49 @@ namespace YAML
} }
return value; return value;
} }
std::string Str(unsigned ch) std::string Str(unsigned ch) { return std::string(1, static_cast<char>(ch)); }
{
return std::string(1, static_cast<char>(ch));
}
// Escape // Escape
// . Translates the next 'codeLength' characters into a hex number and returns the result. // . Translates the next 'codeLength' characters into a hex number and returns
// . Throws if it's not actually hex. // the result.
std::string Escape(Stream& in, int codeLength) // . Throws if it's not actually hex.
{ std::string Escape(Stream& in, int codeLength) {
// grab string // grab string
std::string str; std::string str;
for(int i=0;i<codeLength;i++) for (int i = 0; i < codeLength; i++)
str += in.get(); str += in.get();
// get the value // get the value
unsigned value = ParseHex(str, in.mark()); unsigned value = ParseHex(str, in.mark());
// legal unicode? // legal unicode?
if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
std::stringstream msg; std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value; msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.mark(), msg.str()); throw ParserException(in.mark(), msg.str());
} }
// now break it up into chars // now break it up into chars
if(value <= 0x7F) if (value <= 0x7F)
return Str(value); return Str(value);
else if(value <= 0x7FF) else if (value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
else if(value <= 0xFFFF) else if (value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
Str(0x80 + (value & 0x3F));
else else
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
} }
// Escape // Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote) // . Escapes the sequence starting 'in' (it must begin with a '\' or single
// and returns the result. // quote)
// . Throws if it's an unknown escape character. // and returns the result.
std::string Escape(Stream& in) // . Throws if it's an unknown escape character.
{ std::string Escape(Stream& in) {
// eat slash // eat slash
char escape = in.get(); char escape = in.get();
@@ -77,37 +78,59 @@ namespace YAML
char ch = in.get(); char ch = in.get();
// first do single quote, since it's easier // first do single quote, since it's easier
if(escape == '\'' && ch == '\'') if (escape == '\'' && ch == '\'')
return "\'"; return "\'";
// now do the slash (we're not gonna check if it's a slash - you better pass one!) // now do the slash (we're not gonna check if it's a slash - you better pass
switch(ch) { // one!)
case '0': return std::string(1, '\x00'); switch (ch) {
case 'a': return "\x07"; case '0':
case 'b': return "\x08"; return std::string(1, '\x00');
case 'a':
return "\x07";
case 'b':
return "\x08";
case 't': case 't':
case '\t': return "\x09"; case '\t':
case 'n': return "\x0A"; return "\x09";
case 'v': return "\x0B"; case 'n':
case 'f': return "\x0C"; return "\x0A";
case 'r': return "\x0D"; case 'v':
case 'e': return "\x1B"; return "\x0B";
case ' ': return "\x20"; case 'f':
case '\"': return "\""; return "\x0C";
case '\'': return "\'"; case 'r':
case '\\': return "\\"; return "\x0D";
case '/': return "/"; case 'e':
case 'N': return "\x85"; return "\x1B";
case '_': return "\xA0"; case ' ':
case 'L': return "\xE2\x80\xA8"; // LS (#x2028) return "\x20";
case 'P': return "\xE2\x80\xA9"; // PS (#x2029) case '\"':
case 'x': return Escape(in, 2); return "\"";
case 'u': return Escape(in, 4); case '\'':
case 'U': return Escape(in, 8); 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; std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
} }
} }
} }

340
src/exp.h
View File

@@ -1,196 +1,222 @@
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "regex.h"
#include <string>
#include <ios> #include <ios>
#include <string>
#include "regex_yaml.h"
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// // Here we store a bunch of expressions for matching different parts of the
// Here we store a bunch of expressions for matching different parts of the file. // file.
namespace Exp namespace Exp {
{ // misc
// misc inline const RegEx& Empty() {
inline const RegEx& Space() { static const RegEx e;
return e;
}
inline const RegEx& Space() {
static const RegEx e = RegEx(' '); static const RegEx e = RegEx(' ');
return e; return e;
} }
inline const RegEx& Tab() { inline const RegEx& Tab() {
static const RegEx e = RegEx('\t'); static const RegEx e = RegEx('\t');
return e; return e;
} }
inline const RegEx& Blank() { inline const RegEx& Blank() {
static const RegEx e = Space() || Tab(); static const RegEx e = Space() || Tab();
return e; return e;
} }
inline const RegEx& Break() { inline const RegEx& Break() {
static const RegEx e = RegEx('\n') || RegEx("\r\n"); static const RegEx e = RegEx('\n') || RegEx("\r\n");
return e; return e;
} }
inline const RegEx& BlankOrBreak() { inline const RegEx& BlankOrBreak() {
static const RegEx e = Blank() || Break(); static const RegEx e = Blank() || Break();
return e; return e;
} }
inline const RegEx& Digit() { inline const RegEx& Digit() {
static const RegEx e = RegEx('0', '9'); static const RegEx e = RegEx('0', '9');
return e; return e;
} }
inline const RegEx& Alpha() { inline const RegEx& Alpha() {
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z'); static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
return e; return e;
} }
inline const RegEx& AlphaNumeric() { inline const RegEx& AlphaNumeric() {
static const RegEx e = Alpha() || Digit(); static const RegEx e = Alpha() || Digit();
return e; return e;
} }
inline const RegEx& Word() { inline const RegEx& Word() {
static const RegEx e = AlphaNumeric() || RegEx('-'); static const RegEx e = AlphaNumeric() || RegEx('-');
return e; return e;
} }
inline const RegEx& Hex() { inline const RegEx& Hex() {
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f'); static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
return e; return e;
} }
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1) // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
inline const RegEx& NotPrintable() { // 5.1)
static const RegEx e = RegEx(0) || 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("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
RegEx(0x0E, 0x1F) || RegEx(0x0E, 0x1F) ||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F'))); (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
return e; return e;
} }
inline const RegEx& Utf8_ByteOrderMark() { inline const RegEx& Utf8_ByteOrderMark() {
static const RegEx e = RegEx("\xEF\xBB\xBF"); static const RegEx e = RegEx("\xEF\xBB\xBF");
return e; return e;
}
// 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& EscSingleQuote() {
static const RegEx e = RegEx("\'\'");
return e;
}
inline const RegEx& EscBreak() {
static const RegEx e = RegEx('\\') + Break();
return e;
}
inline const RegEx& ChompIndicator() {
static const RegEx e = RegEx("+-", REGEX_OR);
return e;
}
inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit();
return e;
}
// and some functions
std::string Escape(Stream& in);
}
namespace Keys
{
const char Directive = '%';
const char FlowSeqStart = '[';
const char FlowSeqEnd = ']';
const char FlowMapStart = '{';
const char FlowMapEnd = '}';
const char FlowEntry = ',';
const char Alias = '*';
const char Anchor = '&';
const char Tag = '!';
const char LiteralScalar = '|';
const char FoldedScalar = '>';
const char VerbatimTagStart = '<';
const char VerbatimTagEnd = '>';
}
} }
// actual tags
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 #endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,38 +1,41 @@
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <iostream>
#include <cstddef>
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
#include <iostream>
namespace YAML namespace YAML {
{ struct Indentation {
struct Indentation { Indentation(std::size_t n_) : n(n_) {}
Indentation(unsigned n_): n(n_) {} std::size_t n;
unsigned n; };
};
inline ostream_wrapper& operator << (ostream_wrapper& out, const Indentation& indent) { inline ostream_wrapper& operator<<(ostream_wrapper& out,
for(unsigned i=0;i<indent.n;i++) const Indentation& indent) {
for (std::size_t i = 0; i < indent.n; i++)
out << ' '; out << ' ';
return out; return out;
}
struct IndentTo {
IndentTo(unsigned n_): n(n_) {}
unsigned n;
};
inline ostream_wrapper& operator << (ostream_wrapper& out, const IndentTo& indent) {
while(out.col() < indent.n)
out << ' ';
return out;
}
} }
struct IndentTo {
IndentTo(std::size_t n_) : n(n_) {}
std::size_t n;
};
inline ostream_wrapper& operator<<(ostream_wrapper& out,
const IndentTo& indent) {
while (out.col() < indent.n)
out << ' ';
return out;
}
}
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,29 +1,26 @@
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
#include "yaml-cpp/node/ptr.h"
namespace YAML namespace YAML {
{ namespace detail {
namespace detail
{ void memory_holder::merge(memory_holder& rhs) {
void memory_holder::merge(memory_holder& rhs) if (m_pMemory == rhs.m_pMemory)
{
if(m_pMemory == rhs.m_pMemory)
return; return;
m_pMemory->merge(*rhs.m_pMemory); m_pMemory->merge(*rhs.m_pMemory);
rhs.m_pMemory = m_pMemory; rhs.m_pMemory = m_pMemory;
} }
node& memory::create_node() node& memory::create_node() {
{
shared_node pNode(new node); shared_node pNode(new node);
m_nodes.insert(pNode); m_nodes.insert(pNode);
return *pNode; return *pNode;
} }
void memory::merge(const memory& rhs) void memory::merge(const memory& rhs) {
{ m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); }
} }
}
} }

View File

@@ -2,13 +2,11 @@
#include "nodebuilder.h" #include "nodebuilder.h"
#include "nodeevents.h" #include "nodeevents.h"
namespace YAML namespace YAML {
{ Node Clone(const Node& node) {
Node Clone(const Node& node)
{
NodeEvents events(node); NodeEvents events(node);
NodeBuilder builder; NodeBuilder builder;
events.Emit(builder); events.Emit(builder);
return builder.Root(); return builder.Root();
} }
} }

View File

@@ -1,42 +1,49 @@
#include "yaml-cpp/node/detail/node_data.h" #include <assert.h>
#include "yaml-cpp/node/detail/memory.h" #include <iterator>
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
namespace YAML #include "yaml-cpp/exceptions.h"
{ #include "yaml-cpp/node/detail/memory.h"
namespace detail #include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
{ #include "yaml-cpp/node/detail/node_data.h"
std::string node_data::empty_scalar; #include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
node_data::node_data(): m_isDefined(false), m_type(NodeType::Null), m_seqSize(0) namespace YAML {
{ namespace detail {
}
void node_data::mark_defined() std::string node_data::empty_scalar;
{
if(m_type == NodeType::Undefined) 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_type = NodeType::Null;
m_isDefined = true; m_isDefined = true;
} }
void node_data::set_type(NodeType::value type) void node_data::set_mark(const Mark& mark) { m_mark = mark; }
{
if(type == NodeType::Undefined) { void node_data::set_type(NodeType::value type) {
if (type == NodeType::Undefined) {
m_type = type; m_type = type;
m_isDefined = false; m_isDefined = false;
return; return;
} }
m_isDefined = true; m_isDefined = true;
if(type == m_type) if (type == m_type)
return; return;
m_type = type; m_type = type;
switch(m_type) { switch (m_type) {
case NodeType::Null: case NodeType::Null:
break; break;
case NodeType::Scalar: case NodeType::Scalar:
@@ -52,123 +59,127 @@ namespace YAML
assert(false); assert(false);
break; break;
} }
} }
void node_data::set_tag(const std::string& tag) void node_data::set_tag(const std::string& tag) { m_tag = tag; }
{
m_tag = tag;
}
void node_data::set_null() void node_data::set_style(EmitterStyle::value style) { m_style = style; }
{
void node_data::set_null() {
m_isDefined = true; m_isDefined = true;
m_type = NodeType::Null; m_type = NodeType::Null;
} }
void node_data::set_scalar(const std::string& scalar) void node_data::set_scalar(const std::string& scalar) {
{
m_isDefined = true; m_isDefined = true;
m_type = NodeType::Scalar; m_type = NodeType::Scalar;
m_scalar = scalar; m_scalar = scalar;
} }
// size/iterator // size/iterator
std::size_t node_data::size() const std::size_t node_data::size() const {
{ if (!m_isDefined)
if(!m_isDefined)
return 0; return 0;
switch(m_type) { switch (m_type) {
case NodeType::Sequence: compute_seq_size(); return m_seqSize; case NodeType::Sequence:
case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size(); compute_seq_size();
return m_seqSize;
case NodeType::Map:
compute_map_size();
return m_map.size() - m_undefinedPairs.size();
default: default:
return 0; return 0;
} }
return 0; return 0;
} }
void node_data::compute_seq_size() const void node_data::compute_seq_size() const {
{ while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
m_seqSize++; m_seqSize++;
} }
void node_data::compute_map_size() const void node_data::compute_map_size() const {
{
kv_pairs::iterator it = m_undefinedPairs.begin(); kv_pairs::iterator it = m_undefinedPairs.begin();
while(it != m_undefinedPairs.end()) { while (it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = boost::next(it); kv_pairs::iterator jt = std::next(it);
if(it->first->is_defined() && it->second->is_defined()) if (it->first->is_defined() && it->second->is_defined())
m_undefinedPairs.erase(it); m_undefinedPairs.erase(it);
it = jt; it = jt;
} }
} }
const_node_iterator node_data::begin() const const_node_iterator node_data::begin() const {
{ if (!m_isDefined)
if(!m_isDefined)
return const_node_iterator(); return const_node_iterator();
switch(m_type) { switch (m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.begin()); case NodeType::Sequence:
case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end()); return const_node_iterator(m_sequence.begin());
default: return const_node_iterator(); case NodeType::Map:
} return const_node_iterator(m_map.begin(), m_map.end());
default:
return const_node_iterator();
} }
}
node_iterator node_data::begin() node_iterator node_data::begin() {
{ if (!m_isDefined)
if(!m_isDefined)
return node_iterator(); return node_iterator();
switch(m_type) { switch (m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.begin()); case NodeType::Sequence:
case NodeType::Map: return node_iterator(m_map.begin(), m_map.end()); return node_iterator(m_sequence.begin());
default: return node_iterator(); case NodeType::Map:
} return node_iterator(m_map.begin(), m_map.end());
default:
return node_iterator();
} }
}
const_node_iterator node_data::end() const const_node_iterator node_data::end() const {
{ if (!m_isDefined)
if(!m_isDefined)
return const_node_iterator(); return const_node_iterator();
switch(m_type) { switch (m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.end()); case NodeType::Sequence:
case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end()); return const_node_iterator(m_sequence.end());
default: return const_node_iterator(); case NodeType::Map:
} return const_node_iterator(m_map.end(), m_map.end());
default:
return const_node_iterator();
} }
}
node_iterator node_data::end() node_iterator node_data::end() {
{ if (!m_isDefined)
if(!m_isDefined)
return node_iterator(); return node_iterator();
switch(m_type) { switch (m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.end()); case NodeType::Sequence:
case NodeType::Map: return node_iterator(m_map.end(), m_map.end()); return node_iterator(m_sequence.end());
default: return node_iterator(); case NodeType::Map:
} return node_iterator(m_map.end(), m_map.end());
default:
return node_iterator();
} }
}
// sequence // sequence
void node_data::push_back(node& node, shared_memory_holder /* pMemory */) void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
{ if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
m_type = NodeType::Sequence; m_type = NodeType::Sequence;
reset_sequence(); reset_sequence();
} }
if(m_type != NodeType::Sequence) if (m_type != NodeType::Sequence)
throw BadPushback(); throw BadPushback();
m_sequence.push_back(&node); m_sequence.push_back(&node);
} }
void node_data::insert(node& key, node& value, shared_memory_holder pMemory) void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
{ switch (m_type) {
switch(m_type) {
case NodeType::Map: case NodeType::Map:
break; break;
case NodeType::Undefined: case NodeType::Undefined:
@@ -181,25 +192,24 @@ namespace YAML
} }
insert_map_pair(key, value); insert_map_pair(key, value);
}
// indexing
node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
if (m_type != NodeType::Map) {
return NULL;
} }
// indexing for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
node& node_data::get(node& key, shared_memory_holder pMemory) const if (it->first->is(key))
{ return it->second;
if(m_type != NodeType::Map)
return pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key))
return *it->second;
} }
return pMemory->create_node(); return NULL;
} }
node& node_data::get(node& key, shared_memory_holder pMemory) node& node_data::get(node& key, shared_memory_holder pMemory) {
{ switch (m_type) {
switch(m_type) {
case NodeType::Map: case NodeType::Map:
break; break;
case NodeType::Undefined: case NodeType::Undefined:
@@ -211,53 +221,49 @@ namespace YAML
throw BadSubscript(); throw BadSubscript();
} }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
if(it->first->is(key)) if (it->first->is(key))
return *it->second; return *it->second;
} }
node& value = pMemory->create_node(); node& value = pMemory->create_node();
insert_map_pair(key, value); insert_map_pair(key, value);
return value; return value;
} }
bool node_data::remove(node& key, shared_memory_holder /* pMemory */) bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
{ if (m_type != NodeType::Map)
if(m_type != NodeType::Map)
return false; return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if(it->first->is(key)) { if (it->first->is(key)) {
m_map.erase(it); m_map.erase(it);
return true; return true;
} }
} }
return false; return false;
} }
void node_data::reset_sequence() void node_data::reset_sequence() {
{
m_sequence.clear(); m_sequence.clear();
m_seqSize = 0; m_seqSize = 0;
} }
void node_data::reset_map() void node_data::reset_map() {
{
m_map.clear(); m_map.clear();
m_undefinedPairs.clear(); m_undefinedPairs.clear();
} }
void node_data::insert_map_pair(node& key, node& value) void node_data::insert_map_pair(node& key, node& value) {
{ m_map.emplace_back(&key, &value);
m_map[&key] = &value;
if(!key.is_defined() || !value.is_defined())
m_undefinedPairs.push_back(kv_pair(&key, &value));
}
void node_data::convert_to_map(shared_memory_holder pMemory) if (!key.is_defined() || !value.is_defined())
{ m_undefinedPairs.emplace_back(&key, &value);
switch(m_type) { }
void node_data::convert_to_map(shared_memory_holder pMemory) {
switch (m_type) {
case NodeType::Undefined: case NodeType::Undefined:
case NodeType::Null: case NodeType::Null:
reset_map(); reset_map();
@@ -272,14 +278,13 @@ namespace YAML
assert(false); assert(false);
break; break;
} }
} }
void node_data::convert_sequence_to_map(shared_memory_holder pMemory) void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
{
assert(m_type == NodeType::Sequence); assert(m_type == NodeType::Sequence);
reset_map(); reset_map();
for(std::size_t i=0;i<m_sequence.size();i++) { for (std::size_t i = 0; i < m_sequence.size(); i++) {
std::stringstream stream; std::stringstream stream;
stream << i; stream << i;
@@ -290,6 +295,6 @@ namespace YAML
reset_sequence(); reset_sequence();
m_type = NodeType::Map; m_type = NodeType::Map;
} }
} }
} }

View File

@@ -1,106 +1,99 @@
#include "nodebuilder.h" #include <assert.h>
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include <cassert> #include <cassert>
namespace YAML #include "nodebuilder.h"
{ #include "yaml-cpp/node/detail/node.h"
NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) #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 m_anchors.push_back(0); // since the anchors start at 1
} }
NodeBuilder::~NodeBuilder() NodeBuilder::~NodeBuilder() {}
{
}
Node NodeBuilder::Root() Node NodeBuilder::Root() {
{ if (!m_pRoot)
if(!m_pRoot)
return Node(); return Node();
return Node(*m_pRoot, m_pMemory); return Node(*m_pRoot, m_pMemory);
} }
void NodeBuilder::OnDocumentStart(const Mark&) void NodeBuilder::OnDocumentStart(const Mark&) {}
{
}
void NodeBuilder::OnDocumentEnd() void NodeBuilder::OnDocumentEnd() {}
{
}
void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
{ detail::node& node = Push(mark, anchor);
detail::node& node = Push(anchor);
node.set_null(); node.set_null();
Pop(); Pop();
} }
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
{
detail::node& node = *m_anchors[anchor]; detail::node& node = *m_anchors[anchor];
Push(node); Push(node);
Pop(); Pop();
} }
void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value) void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
{ anchor_t anchor, const std::string& value) {
detail::node& node = Push(anchor); detail::node& node = Push(mark, anchor);
node.set_scalar(value); node.set_scalar(value);
node.set_tag(tag); node.set_tag(tag);
Pop(); Pop();
} }
void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor) void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag,
{ anchor_t anchor, EmitterStyle::value style) {
detail::node& node = Push(anchor); detail::node& node = Push(mark, anchor);
node.set_tag(tag); node.set_tag(tag);
node.set_type(NodeType::Sequence); node.set_type(NodeType::Sequence);
} node.set_style(style);
}
void NodeBuilder::OnSequenceEnd() void NodeBuilder::OnSequenceEnd() { Pop(); }
{
Pop();
}
void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor) void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
{ anchor_t anchor, EmitterStyle::value style) {
detail::node& node = Push(anchor); detail::node& node = Push(mark, anchor);
node.set_type(NodeType::Map); node.set_type(NodeType::Map);
node.set_tag(tag); node.set_tag(tag);
node.set_style(style);
m_mapDepth++; m_mapDepth++;
} }
void NodeBuilder::OnMapEnd() void NodeBuilder::OnMapEnd() {
{
assert(m_mapDepth > 0); assert(m_mapDepth > 0);
m_mapDepth--; m_mapDepth--;
Pop(); Pop();
} }
detail::node& NodeBuilder::Push(anchor_t anchor) detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
{
detail::node& node = m_pMemory->create_node(); detail::node& node = m_pMemory->create_node();
node.set_mark(mark);
RegisterAnchor(anchor, node); RegisterAnchor(anchor, node);
Push(node); Push(node);
return node; return node;
} }
void NodeBuilder::Push(detail::node& node) void NodeBuilder::Push(detail::node& node) {
{ const bool needsKey =
const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth); (!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
m_keys.size() < m_mapDepth);
m_stack.push_back(&node); m_stack.push_back(&node);
if(needsKey) if (needsKey)
m_keys.push_back(PushedKey(&node, false)); m_keys.push_back(PushedKey(&node, false));
} }
void NodeBuilder::Pop() void NodeBuilder::Pop() {
{
assert(!m_stack.empty()); assert(!m_stack.empty());
if(m_stack.size() == 1) { if (m_stack.size() == 1) {
m_pRoot = m_stack[0]; m_pRoot = m_stack[0];
m_stack.pop_back(); m_stack.pop_back();
return; return;
@@ -111,12 +104,12 @@ namespace YAML
detail::node& collection = *m_stack.back(); detail::node& collection = *m_stack.back();
if(collection.type() == NodeType::Sequence) { if (collection.type() == NodeType::Sequence) {
collection.push_back(node, m_pMemory); collection.push_back(node, m_pMemory);
} else if(collection.type() == NodeType::Map) { } else if (collection.type() == NodeType::Map) {
assert(!m_keys.empty()); assert(!m_keys.empty());
PushedKey& key = m_keys.back(); PushedKey& key = m_keys.back();
if(key.second) { if (key.second) {
collection.insert(*key.first, node, m_pMemory); collection.insert(*key.first, node, m_pMemory);
m_keys.pop_back(); m_keys.pop_back();
} else { } else {
@@ -126,13 +119,12 @@ namespace YAML
assert(false); assert(false);
m_stack.clear(); m_stack.clear();
} }
} }
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
{ if (anchor) {
if(anchor) {
assert(anchor == m_anchors.size()); assert(anchor == m_anchors.size());
m_anchors.push_back(&node); m_anchors.push_back(&node);
} }
} }
} }

View File

@@ -1,20 +1,30 @@
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/node/ptr.h"
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/anchor.h"
{ #include "yaml-cpp/emitterstyle.h"
class Node; #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/node/ptr.h"
class NodeBuilder: public EventHandler namespace YAML {
{ namespace detail {
class node;
} // namespace detail
struct Mark;
} // namespace YAML
namespace YAML {
class Node;
class NodeBuilder : public EventHandler {
public: public:
NodeBuilder(); NodeBuilder();
virtual ~NodeBuilder(); virtual ~NodeBuilder();
@@ -26,33 +36,35 @@ namespace YAML
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(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 OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd(); virtual void OnMapEnd();
private: private:
detail::node& Push(anchor_t anchor); detail::node& Push(const Mark& mark, anchor_t anchor);
void Push(detail::node& node); void Push(detail::node& node);
void Pop(); void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node); void RegisterAnchor(anchor_t anchor, detail::node& node);
private: private:
detail::shared_memory_holder m_pMemory; detail::shared_memory_holder m_pMemory;
detail::node *m_pRoot; detail::node* m_pRoot;
typedef std::vector<detail::node *> Nodes; typedef std::vector<detail::node*> Nodes;
Nodes m_stack; Nodes m_stack;
Nodes m_anchors; Nodes m_anchors;
typedef std::pair<detail::node *, bool> PushedKey; typedef std::pair<detail::node*, bool> PushedKey;
std::vector<PushedKey> m_keys; std::vector<PushedKey> m_keys;
std::size_t m_mapDepth; std::size_t m_mapDepth;
}; };
} }
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,62 +1,63 @@
#include "nodeevents.h" #include "nodeevents.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/type.h"
namespace YAML namespace YAML {
{ void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
void NodeEvents::AliasManager::RegisterReference(const detail::node& node)
{
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
} }
anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const anchor_t NodeEvents::AliasManager::LookupAnchor(
{ const detail::node& node) const {
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
if(it == m_anchorByIdentity.end()) if (it == m_anchorByIdentity.end())
return 0; return 0;
return it->second; return it->second;
} }
NodeEvents::NodeEvents(const Node& node): m_pMemory(node.m_pMemory), m_root(*node.m_pNode) NodeEvents::NodeEvents(const Node& node)
{ : m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
Setup(m_root); if (m_root)
} Setup(*m_root);
}
void NodeEvents::Setup(const detail::node& node) void NodeEvents::Setup(const detail::node& node) {
{
int& refCount = m_refCount[node.ref()]; int& refCount = m_refCount[node.ref()];
refCount++; refCount++;
if(refCount > 1) if (refCount > 1)
return; return;
if(node.type() == NodeType::Sequence) { if (node.type() == NodeType::Sequence) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
Setup(**it); Setup(**it);
} else if(node.type() == NodeType::Map) { } else if (node.type() == NodeType::Map) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) { for (detail::const_node_iterator it = node.begin(); it != node.end();
++it) {
Setup(*it->first); Setup(*it->first);
Setup(*it->second); Setup(*it->second);
} }
} }
} }
void NodeEvents::Emit(EventHandler& handler) void NodeEvents::Emit(EventHandler& handler) {
{
AliasManager am; AliasManager am;
handler.OnDocumentStart(Mark()); handler.OnDocumentStart(Mark());
Emit(m_root, handler, am); if (m_root)
Emit(*m_root, handler, am);
handler.OnDocumentEnd(); handler.OnDocumentEnd();
} }
void NodeEvents::Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
{ AliasManager& am) const {
anchor_t anchor = NullAnchor; anchor_t anchor = NullAnchor;
if(IsAliased(node)) { if (IsAliased(node)) {
anchor = am.LookupAnchor(node); anchor = am.LookupAnchor(node);
if(anchor) { if (anchor) {
handler.OnAlias(Mark(), anchor); handler.OnAlias(Mark(), anchor);
return; return;
} }
@@ -65,7 +66,7 @@ namespace YAML
anchor = am.LookupAnchor(node); anchor = am.LookupAnchor(node);
} }
switch(node.type()) { switch (node.type()) {
case NodeType::Undefined: case NodeType::Undefined:
break; break;
case NodeType::Null: case NodeType::Null:
@@ -75,25 +76,26 @@ namespace YAML
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
break; break;
case NodeType::Sequence: case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor); handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) for (detail::const_node_iterator it = node.begin(); it != node.end();
++it)
Emit(**it, handler, am); Emit(**it, handler, am);
handler.OnSequenceEnd(); handler.OnSequenceEnd();
break; break;
case NodeType::Map: case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor); handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) { for (detail::const_node_iterator it = node.begin(); it != node.end();
++it) {
Emit(*it->first, handler, am); Emit(*it->first, handler, am);
Emit(*it->second, handler, am); Emit(*it->second, handler, am);
} }
handler.OnMapEnd(); handler.OnMapEnd();
break; break;
} }
} }
bool NodeEvents::IsAliased(const detail::node& node) const bool NodeEvents::IsAliased(const detail::node& node) const {
{
RefCount::const_iterator it = m_refCount.find(node.ref()); RefCount::const_iterator it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1; return it != m_refCount.end() && it->second > 1;
} }
} }

View File

@@ -1,22 +1,29 @@
#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/node/ptr.h"
#include <map> #include <map>
#include <vector> #include <vector>
namespace YAML #include "yaml-cpp/anchor.h"
{ #include "yaml-cpp/node/ptr.h"
class EventHandler;
class Node;
class NodeEvents namespace YAML {
{ namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
class EventHandler;
class Node;
class NodeEvents {
public: public:
explicit NodeEvents(const Node& node); explicit NodeEvents(const Node& node);
@@ -25,7 +32,7 @@ namespace YAML
private: private:
class AliasManager { class AliasManager {
public: public:
AliasManager(): m_curAnchor(0) {} AliasManager() : m_curAnchor(0) {}
void RegisterReference(const detail::node& node); void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const; anchor_t LookupAnchor(const detail::node& node) const;
@@ -41,17 +48,17 @@ namespace YAML
}; };
void Setup(const detail::node& node); void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const; void Emit(const detail::node& node, EventHandler& handler,
AliasManager& am) const;
bool IsAliased(const detail::node& node) const; bool IsAliased(const detail::node& node) const;
private: private:
detail::shared_memory_holder m_pMemory; detail::shared_memory_holder m_pMemory;
detail::node& m_root; detail::node* m_root;
typedef std::map<const detail::node_ref *, int> RefCount; typedef std::map<const detail::node_ref*, int> RefCount;
RefCount m_refCount; RefCount m_refCount;
}; };
} }
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,6 +1,10 @@
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
namespace YAML namespace YAML {
{ _Null Null;
_Null Null;
bool IsNullString(const std::string& str) {
return str.empty() || str == "~" || str == "null" || str == "Null" ||
str == "NULL";
}
} }

View File

@@ -1,56 +1,57 @@
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
#include <algorithm>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
namespace YAML namespace YAML {
{ ostream_wrapper::ostream_wrapper()
ostream_wrapper::ostream_wrapper(): m_pStream(0), m_pos(0), m_row(0), m_col(0), m_comment(false) : m_buffer(1, '\0'),
{ m_pStream(0),
} m_pos(0),
m_row(0),
m_col(0),
m_comment(false) {}
ostream_wrapper::ostream_wrapper(std::ostream& stream): m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) ostream_wrapper::ostream_wrapper(std::ostream& stream)
{ : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
}
ostream_wrapper::~ostream_wrapper() ostream_wrapper::~ostream_wrapper() {}
{
}
void ostream_wrapper::write(const std::string& str) void ostream_wrapper::write(const std::string& str) {
{ if (m_pStream) {
if(m_pStream) {
m_pStream->write(str.c_str(), str.size()); m_pStream->write(str.c_str(), str.size());
} else { } else {
m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1));
std::copy(str.begin(), str.end(), &m_buffer[m_pos]); std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos);
} }
for(std::size_t i=0;i<str.size();i++) for (std::size_t i = 0; i < str.size(); i++) {
update_pos(str[i]); update_pos(str[i]);
} }
}
void ostream_wrapper::write(const char *str, std::size_t size) void ostream_wrapper::write(const char* str, std::size_t size) {
{ if (m_pStream) {
if(m_pStream) {
m_pStream->write(str, size); m_pStream->write(str, size);
} else { } else {
m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1));
std::copy(str, str + size, &m_buffer[m_pos]); std::copy(str, str + size, m_buffer.begin() + m_pos);
} }
for(std::size_t i=0;i<size;i++) for (std::size_t i = 0; i < size; i++) {
update_pos(str[i]); update_pos(str[i]);
} }
}
void ostream_wrapper::update_pos(char ch) void ostream_wrapper::update_pos(char ch) {
{
m_pos++; m_pos++;
m_col++; m_col++;
if(ch == '\n') { if (ch == '\n') {
m_row++; m_row++;
m_col = 0; m_col = 0;
m_comment = false; m_comment = false;
} }
} }
} }

View File

@@ -1,68 +1,72 @@
#include "yaml-cpp/node/parse.h" #include "yaml-cpp/node/parse.h"
#include <fstream>
#include <sstream>
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/impl.h"
#include "yaml-cpp/parser.h" #include "yaml-cpp/parser.h"
#include "nodebuilder.h" #include "nodebuilder.h"
#include <fstream> namespace YAML {
#include <sstream> Node Load(const std::string& input) {
namespace YAML
{
Node Load(const std::string& input) {
std::stringstream stream(input); std::stringstream stream(input);
return Load(stream); return Load(stream);
} }
Node Load(const char *input) { Node Load(const char* input) {
std::stringstream stream(input); std::stringstream stream(input);
return Load(stream); return Load(stream);
} }
Node Load(std::istream& input) { Node Load(std::istream& input) {
Parser parser(input); Parser parser(input);
NodeBuilder builder; NodeBuilder builder;
if(!parser.HandleNextDocument(builder)) if (!parser.HandleNextDocument(builder)) {
return Node(); return Node();
}
return builder.Root(); return builder.Root();
} }
Node LoadFile(const std::string& filename) { Node LoadFile(const std::string& filename) {
std::ifstream fin(filename.c_str()); std::ifstream fin(filename.c_str());
if(!fin) if (!fin) {
throw BadFile(); throw BadFile();
}
return Load(fin); return Load(fin);
} }
std::vector<Node> LoadAll(const std::string& input) { std::vector<Node> LoadAll(const std::string& input) {
std::stringstream stream(input); std::stringstream stream(input);
return LoadAll(stream); return LoadAll(stream);
} }
std::vector<Node> LoadAll(const char *input) { std::vector<Node> LoadAll(const char* input) {
std::stringstream stream(input); std::stringstream stream(input);
return LoadAll(stream); return LoadAll(stream);
} }
std::vector<Node> LoadAll(std::istream& input) { std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> docs; std::vector<Node> docs;
Parser parser(input); Parser parser(input);
while(1) { while (1) {
NodeBuilder builder; NodeBuilder builder;
if(!parser.HandleNextDocument(builder)) if (!parser.HandleNextDocument(builder)) {
break; break;
}
docs.push_back(builder.Root()); docs.push_back(builder.Root());
} }
return docs; return docs;
}
std::vector<Node> LoadAllFromFile(const std::string& filename) {
std::ifstream fin(filename.c_str());
if(!fin)
throw BadFile();
return LoadAll(fin);
}
} }
std::vector<Node> LoadAllFromFile(const std::string& filename) {
std::ifstream fin(filename.c_str());
if (!fin) {
throw BadFile();
}
return LoadAll(fin);
}
} // namespace YAML

View File

@@ -1,141 +1,129 @@
#include "yaml-cpp/parser.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/exceptions.h"
#include "directives.h"
#include "scanner.h"
#include "singledocparser.h"
#include "tag.h"
#include "token.h"
#include <sstream>
#include <cstdio> #include <cstdio>
#include <sstream>
namespace YAML #include "directives.h" // IWYU pragma: keep
{ #include "scanner.h" // IWYU pragma: keep
Parser::Parser() #include "singledocparser.h"
{ #include "token.h"
} #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
#include "yaml-cpp/parser.h"
Parser::Parser(std::istream& in) namespace YAML {
{ class EventHandler;
Load(in);
}
Parser::~Parser() Parser::Parser() {}
{
}
Parser::operator bool() const Parser::Parser(std::istream& in) { Load(in); }
{
Parser::~Parser() {}
Parser::operator bool() const {
return m_pScanner.get() && !m_pScanner->empty(); return m_pScanner.get() && !m_pScanner->empty();
} }
void Parser::Load(std::istream& in) void Parser::Load(std::istream& in) {
{
m_pScanner.reset(new Scanner(in)); m_pScanner.reset(new Scanner(in));
m_pDirectives.reset(new Directives); m_pDirectives.reset(new Directives);
} }
// HandleNextDocument bool Parser::HandleNextDocument(EventHandler& eventHandler) {
// . Handles the next document if (!m_pScanner.get())
// . Throws a ParserException on error.
// . Returns false if there are no more documents
bool Parser::HandleNextDocument(EventHandler& eventHandler)
{
if(!m_pScanner.get())
return false; return false;
ParseDirectives(); ParseDirectives();
if(m_pScanner->empty()) if (m_pScanner->empty()) {
return false; return false;
}
SingleDocParser sdp(*m_pScanner, *m_pDirectives); SingleDocParser sdp(*m_pScanner, *m_pDirectives);
sdp.HandleDocument(eventHandler); sdp.HandleDocument(eventHandler);
return true; return true;
} }
// ParseDirectives void Parser::ParseDirectives() {
// . Reads any directives that are next in the queue.
void Parser::ParseDirectives()
{
bool readDirective = false; bool readDirective = false;
while(1) { while (1) {
if(m_pScanner->empty()) if (m_pScanner->empty()) {
break; break;
}
Token& token = m_pScanner->peek(); Token& token = m_pScanner->peek();
if(token.type != Token::DIRECTIVE) if (token.type != Token::DIRECTIVE) {
break; break;
}
// we keep the directives from the last document if none are specified; // we keep the directives from the last document if none are specified;
// but if any directives are specific, then we reset them // but if any directives are specific, then we reset them
if(!readDirective) if (!readDirective) {
m_pDirectives.reset(new Directives); m_pDirectives.reset(new Directives);
}
readDirective = true; readDirective = true;
HandleDirective(token); HandleDirective(token);
m_pScanner->pop(); m_pScanner->pop();
} }
} }
void Parser::HandleDirective(const Token& token) void Parser::HandleDirective(const Token& token) {
{ if (token.value == "YAML") {
if(token.value == "YAML")
HandleYamlDirective(token); HandleYamlDirective(token);
else if(token.value == "TAG") } else if (token.value == "TAG") {
HandleTagDirective(token); HandleTagDirective(token);
} }
}
// HandleYamlDirective void Parser::HandleYamlDirective(const Token& token) {
// . Should be of the form 'major.minor' (like a version number) if (token.params.size() != 1) {
void Parser::HandleYamlDirective(const Token& token)
{
if(token.params.size() != 1)
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS); throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
}
if(!m_pDirectives->version.isDefault) if (!m_pDirectives->version.isDefault) {
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE); throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
}
std::stringstream str(token.params[0]); std::stringstream str(token.params[0]);
str >> m_pDirectives->version.major; str >> m_pDirectives->version.major;
str.get(); str.get();
str >> m_pDirectives->version.minor; str >> m_pDirectives->version.minor;
if(!str || str.peek() != EOF) if (!str || str.peek() != EOF) {
throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]); throw ParserException(
token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
}
if(m_pDirectives->version.major > 1) if (m_pDirectives->version.major > 1) {
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION); throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
}
m_pDirectives->version.isDefault = false; m_pDirectives->version.isDefault = false;
// TODO: warning on major == 1, minor > 2? // TODO: warning on major == 1, minor > 2?
} }
// HandleTagDirective void Parser::HandleTagDirective(const Token& token) {
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file. if (token.params.size() != 2)
void Parser::HandleTagDirective(const Token& token)
{
if(token.params.size() != 2)
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS); throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
const std::string& handle = token.params[0]; const std::string& handle = token.params[0];
const std::string& prefix = token.params[1]; const std::string& prefix = token.params[1];
if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) {
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE); throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
m_pDirectives->tags[handle] = prefix;
} }
void Parser::PrintTokens(std::ostream& out) m_pDirectives->tags[handle] = prefix;
{ }
if(!m_pScanner.get())
return;
while(1) { void Parser::PrintTokens(std::ostream& out) {
if(m_pScanner->empty()) if (!m_pScanner.get()) {
return;
}
while (1) {
if (m_pScanner->empty()) {
break; break;
}
out << m_pScanner->peek() << "\n"; out << m_pScanner->peek() << "\n";
m_pScanner->pop(); m_pScanner->pop();
} }
} }
} }

View File

@@ -1,49 +0,0 @@
#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_STACK_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/noncopyable.h"
#include <cstddef>
#include <cstdlib>
#include <memory>
#include <vector>
template <typename T>
class ptr_stack: private YAML::noncopyable
{
public:
ptr_stack() {}
~ptr_stack() { clear(); }
void clear() {
for(unsigned i=0;i<m_data.size();i++)
delete m_data[i];
m_data.clear();
}
std::size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); }
void push(std::auto_ptr<T> t) {
m_data.push_back(NULL);
m_data.back() = t.release();
}
std::auto_ptr<T> pop() {
std::auto_ptr<T> t(m_data.back());
m_data.pop_back();
return t;
}
T& top() { return *m_data.back(); }
const T& top() const { return *m_data.back(); }
T& top(std::ptrdiff_t diff) { return **(m_data.end() - 1 + diff); }
const T& top(std::ptrdiff_t diff) const { return **(m_data.end() - 1 + diff); }
private:
std::vector<T*> m_data;
};
#endif // PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,47 +1,43 @@
#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PTR_VECTOR_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h"
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "yaml-cpp/noncopyable.h"
namespace YAML { namespace YAML {
template <typename T> // TODO: This class is no longer needed
class ptr_vector: private YAML::noncopyable template <typename T>
{ class ptr_vector : private YAML::noncopyable {
public: public:
ptr_vector() {} ptr_vector() {}
~ptr_vector() { clear(); }
void clear() { void clear() { m_data.clear(); }
for(unsigned i=0;i<m_data.size();i++)
delete m_data[i];
m_data.clear();
}
std::size_t size() const { return m_data.size(); } std::size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); } bool empty() const { return m_data.empty(); }
void push_back(std::auto_ptr<T> t) { void push_back(std::unique_ptr<T>&& t) { m_data.push_back(std::move(t)); }
m_data.push_back(NULL);
m_data.back() = t.release();
}
T& operator[](std::size_t i) { return *m_data[i]; } T& operator[](std::size_t i) { return *m_data[i]; }
const T& operator[](std::size_t i) const { return *m_data[i]; } const T& operator[](std::size_t i) const { return *m_data[i]; }
T& back() { return *m_data.back(); } T& back() { return *(m_data.back().get()); }
const T& back() const { return *m_data.back(); }
const T& back() const { return *(m_data.back().get()); }
private: private:
std::vector<T*> m_data; std::vector<std::unique_ptr<T>> m_data;
}; };
} }
#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,60 +0,0 @@
#include "regex.h"
namespace YAML
{
// constructors
RegEx::RegEx(): m_op(REGEX_EMPTY)
{
}
RegEx::RegEx(REGEX_OP op): m_op(op)
{
}
RegEx::RegEx(char ch): m_op(REGEX_MATCH), m_a(ch)
{
}
RegEx::RegEx(char a, char z): m_op(REGEX_RANGE), m_a(a), m_z(z)
{
}
RegEx::RegEx(const std::string& str, REGEX_OP op): m_op(op)
{
for(std::size_t i=0;i<str.size();i++)
m_params.push_back(RegEx(str[i]));
}
// combination constructors
RegEx operator ! (const RegEx& ex)
{
RegEx ret(REGEX_NOT);
ret.m_params.push_back(ex);
return ret;
}
RegEx operator || (const RegEx& ex1, const RegEx& ex2)
{
RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
RegEx operator && (const RegEx& ex1, const RegEx& ex2)
{
RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
RegEx operator + (const RegEx& ex1, const RegEx& ex2)
{
RegEx ret(REGEX_SEQ);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
}

View File

@@ -1,67 +0,0 @@
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEX_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 <string>
namespace YAML
{
class Stream;
enum REGEX_OP { REGEX_EMPTY, REGEX_MATCH, REGEX_RANGE, REGEX_OR, REGEX_AND, REGEX_NOT, REGEX_SEQ };
// simplified regular expressions
// . Only straightforward matches (no repeated characters)
// . Only matches from start of string
class RegEx
{
public:
RegEx();
RegEx(char ch);
RegEx(char a, char z);
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
~RegEx() {}
friend RegEx operator ! (const RegEx& ex);
friend RegEx operator || (const RegEx& ex1, const RegEx& ex2);
friend RegEx operator && (const RegEx& ex1, const RegEx& ex2);
friend RegEx operator + (const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const;
bool Matches(const std::string& str) const;
bool Matches(const Stream& in) const;
template <typename Source> bool Matches(const Source& source) const;
int Match(const std::string& str) const;
int Match(const Stream& in) const;
template <typename Source> int Match(const Source& source) const;
private:
RegEx(REGEX_OP op);
template <typename Source> bool IsValidSource(const Source& source) const;
template <typename Source> int MatchUnchecked(const Source& source) const;
template <typename Source> int MatchOpEmpty(const Source& source) const;
template <typename Source> int MatchOpMatch(const Source& source) const;
template <typename Source> int MatchOpRange(const Source& source) const;
template <typename Source> int MatchOpOr(const Source& source) const;
template <typename Source> int MatchOpAnd(const Source& source) const;
template <typename Source> int MatchOpNot(const Source& source) const;
template <typename Source> int MatchOpSeq(const Source& source) const;
private:
REGEX_OP m_op;
char m_a, m_z;
std::vector <RegEx> m_params;
};
}
#include "regeximpl.h"
#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66

45
src/regex_yaml.cpp Normal file
View File

@@ -0,0 +1,45 @@
#include "regex_yaml.h"
namespace YAML {
// constructors
RegEx::RegEx() : m_op(REGEX_EMPTY) {}
RegEx::RegEx(REGEX_OP op) : m_op(op) {}
RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {}
RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {}
RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
for (std::size_t i = 0; i < str.size(); i++)
m_params.push_back(RegEx(str[i]));
}
// combination constructors
RegEx operator!(const RegEx& ex) {
RegEx ret(REGEX_NOT);
ret.m_params.push_back(ex);
return ret;
}
RegEx operator||(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
RegEx operator&&(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
RegEx operator+(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_SEQ);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
}

87
src/regex_yaml.h Normal file
View File

@@ -0,0 +1,87 @@
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEX_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 Stream;
enum REGEX_OP {
REGEX_EMPTY,
REGEX_MATCH,
REGEX_RANGE,
REGEX_OR,
REGEX_AND,
REGEX_NOT,
REGEX_SEQ
};
// simplified regular expressions
// . Only straightforward matches (no repeated characters)
// . Only matches from start of string
class YAML_CPP_API RegEx {
public:
RegEx();
RegEx(char ch);
RegEx(char a, char z);
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
~RegEx() {}
friend YAML_CPP_API RegEx operator!(const RegEx& ex);
friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const;
bool Matches(const std::string& str) const;
bool Matches(const Stream& in) const;
template <typename Source>
bool Matches(const Source& source) const;
int Match(const std::string& str) const;
int Match(const Stream& in) const;
template <typename Source>
int Match(const Source& source) const;
private:
RegEx(REGEX_OP op);
template <typename Source>
bool IsValidSource(const Source& source) const;
template <typename Source>
int MatchUnchecked(const Source& source) const;
template <typename Source>
int MatchOpEmpty(const Source& source) const;
template <typename Source>
int MatchOpMatch(const Source& source) const;
template <typename Source>
int MatchOpRange(const Source& source) const;
template <typename Source>
int MatchOpOr(const Source& source) const;
template <typename Source>
int MatchOpAnd(const Source& source) const;
template <typename Source>
int MatchOpNot(const Source& source) const;
template <typename Source>
int MatchOpSeq(const Source& source) const;
private:
REGEX_OP m_op;
char m_a, m_z;
std::vector<RegEx> m_params;
};
}
#include "regeximpl.h"
#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,84 +1,77 @@
#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define REGEXIMPL_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "stream.h" #include "stream.h"
#include "stringsource.h" #include "stringsource.h"
#include "streamcharsource.h" #include "streamcharsource.h"
namespace YAML namespace YAML {
{ // query matches
// query matches inline bool RegEx::Matches(char ch) const {
inline bool RegEx::Matches(char ch) const {
std::string str; std::string str;
str += ch; str += ch;
return Matches(str); return Matches(str);
} }
inline bool RegEx::Matches(const std::string& str) const { inline bool RegEx::Matches(const std::string& str) const {
return Match(str) >= 0; return Match(str) >= 0;
} }
inline bool RegEx::Matches(const Stream& in) const { inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; }
return Match(in) >= 0;
}
template <typename Source> template <typename Source>
inline bool RegEx::Matches(const Source& source) const { inline bool RegEx::Matches(const Source& source) const {
return Match(source) >= 0; return Match(source) >= 0;
} }
// Match // Match
// . Matches the given string against this regular expression. // . Matches the given string against this regular expression.
// . Returns the number of characters matched. // . Returns the number of characters matched.
// . Returns -1 if no characters were matched (the reason for // . Returns -1 if no characters were matched (the reason for
// not returning zero is that we may have an empty regex // not returning zero is that we may have an empty regex
// which is ALWAYS successful at matching zero characters). // which is ALWAYS successful at matching zero characters).
// . REMEMBER that we only match from the start of the buffer! // . REMEMBER that we only match from the start of the buffer!
inline int RegEx::Match(const std::string& str) const inline int RegEx::Match(const std::string& str) const {
{
StringCharSource source(str.c_str(), str.size()); StringCharSource source(str.c_str(), str.size());
return Match(source); return Match(source);
} }
inline int RegEx::Match(const Stream& in) const inline int RegEx::Match(const Stream& in) const {
{
StreamCharSource source(in); StreamCharSource source(in);
return Match(source); return Match(source);
} }
template <typename Source> template <typename Source>
inline bool RegEx::IsValidSource(const Source& source) const inline bool RegEx::IsValidSource(const Source& source) const {
{
return source; return source;
} }
template<> template <>
inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const inline bool RegEx::IsValidSource<StringCharSource>(
{ const StringCharSource& source) const {
switch(m_op) { switch (m_op) {
case REGEX_MATCH: case REGEX_MATCH:
case REGEX_RANGE: case REGEX_RANGE:
return source; return source;
default: default:
return true; return true;
} }
} }
template <typename Source> template <typename Source>
inline int RegEx::Match(const Source& source) const inline int RegEx::Match(const Source& source) const {
{
return IsValidSource(source) ? MatchUnchecked(source) : -1; return IsValidSource(source) ? MatchUnchecked(source) : -1;
} }
template <typename Source> template <typename Source>
inline int RegEx::MatchUnchecked(const Source& source) const inline int RegEx::MatchUnchecked(const Source& source) const {
{ switch (m_op) {
switch(m_op) {
case REGEX_EMPTY: case REGEX_EMPTY:
return MatchOpEmpty(source); return MatchOpEmpty(source);
case REGEX_MATCH: case REGEX_MATCH:
@@ -96,91 +89,98 @@ namespace YAML
} }
return -1; return -1;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Operators // Operators
// Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source). // Note: the convention MatchOp*<Source> is that we can assume
// So we do all our checks *before* we call these functions // IsSourceValid(source).
// So we do all our checks *before* we call these functions
// EmptyOperator // EmptyOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpEmpty(const Source& source) const { inline int RegEx::MatchOpEmpty(const Source& source) const {
return source[0] == Stream::eof() ? 0 : -1; return source[0] == Stream::eof() ? 0 : -1;
} }
template <> template <>
inline int RegEx::MatchOpEmpty<StringCharSource>(const StringCharSource& source) const { inline int RegEx::MatchOpEmpty<StringCharSource>(
return !source ? 0 : -1; // the empty regex only is successful on the empty string const StringCharSource& source) const {
} return !source
? 0
: -1; // the empty regex only is successful on the empty string
}
// MatchOperator // MatchOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpMatch(const Source& source) const { inline int RegEx::MatchOpMatch(const Source& source) const {
if(source[0] != m_a) if (source[0] != m_a)
return -1; return -1;
return 1; return 1;
} }
// RangeOperator // RangeOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpRange(const Source& source) const { inline int RegEx::MatchOpRange(const Source& source) const {
if(m_a > source[0] || m_z < source[0]) if (m_a > source[0] || m_z < source[0])
return -1; return -1;
return 1; return 1;
} }
// OrOperator // OrOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpOr(const Source& source) const { inline int RegEx::MatchOpOr(const Source& source) const {
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n >= 0) if (n >= 0)
return n; return n;
} }
return -1; return -1;
} }
// AndOperator // AndOperator
// Note: 'AND' is a little funny, since we may be required to match things // Note: 'AND' is a little funny, since we may be required to match things
// of different lengths. If we find a match, we return the length of // of different lengths. If we find a match, we return the length of
// the FIRST entry on the list. // the FIRST entry on the list.
template <typename Source> template <typename Source>
inline int RegEx::MatchOpAnd(const Source& source) const { inline int RegEx::MatchOpAnd(const Source& source) const {
int first = -1; int first = -1;
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n == -1) if (n == -1)
return -1; return -1;
if(i == 0) if (i == 0)
first = n; first = n;
} }
return first; return first;
} }
// NotOperator // NotOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpNot(const Source& source) const { inline int RegEx::MatchOpNot(const Source& source) const {
if(m_params.empty()) if (m_params.empty())
return -1; return -1;
if(m_params[0].MatchUnchecked(source) >= 0) if (m_params[0].MatchUnchecked(source) >= 0)
return -1; return -1;
return 1; return 1;
} }
// SeqOperator // SeqOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpSeq(const Source& source) const { inline int RegEx::MatchOpSeq(const Source& source) const {
int offset = 0; int offset = 0;
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset int n = m_params[i].Match(source + offset); // note Match, not
if(n == -1) // MatchUnchecked because we
// need to check validity after
// the offset
if (n == -1)
return -1; return -1;
offset += n; offset += n;
} }
return offset; return offset;
} }
} }
#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,44 +1,36 @@
#include "scanner.h"
#include "token.h"
#include "yaml-cpp/exceptions.h"
#include "exp.h"
#include <cassert> #include <cassert>
#include <memory> #include <memory>
namespace YAML #include "exp.h"
{ #include "scanner.h"
Scanner::Scanner(std::istream& in) #include "token.h"
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false) #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
{
}
Scanner::~Scanner() namespace YAML {
{ Scanner::Scanner(std::istream& in)
} : INPUT(in),
m_startedStream(false),
m_endedStream(false),
m_simpleKeyAllowed(false),
m_canBeJSONFlow(false) {}
// empty Scanner::~Scanner() {}
// . Returns true if there are no more tokens to be read
bool Scanner::empty() bool Scanner::empty() {
{
EnsureTokensInQueue(); EnsureTokensInQueue();
return m_tokens.empty(); return m_tokens.empty();
} }
// pop void Scanner::pop() {
// . Simply removes the next token on the queue.
void Scanner::pop()
{
EnsureTokensInQueue(); EnsureTokensInQueue();
if(!m_tokens.empty()) if (!m_tokens.empty())
m_tokens.pop(); m_tokens.pop();
} }
// peek Token& Scanner::peek() {
// . Returns (but does not remove) the next token on the queue.
Token& Scanner::peek()
{
EnsureTokensInQueue(); EnsureTokensInQueue();
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking assert(!m_tokens.empty()); // should we be asserting here? I mean, we really
// just be checking
// if it's empty before peeking. // if it's empty before peeking.
#if 0 #if 0
@@ -49,30 +41,22 @@ namespace YAML
#endif #endif
return m_tokens.front(); return m_tokens.front();
} }
// mark Mark Scanner::mark() const { return INPUT.mark(); }
// . Returns the current mark in the stream
Mark Scanner::mark() const
{
return INPUT.mark();
}
// EnsureTokensInQueue void Scanner::EnsureTokensInQueue() {
// . Scan until there's a valid token at the front of the queue, while (1) {
// or we're sure the queue is empty. if (!m_tokens.empty()) {
void Scanner::EnsureTokensInQueue()
{
while(1) {
if(!m_tokens.empty()) {
Token& token = m_tokens.front(); Token& token = m_tokens.front();
// if this guy's valid, then we're done // if this guy's valid, then we're done
if(token.status == Token::VALID) if (token.status == Token::VALID) {
return; return;
}
// here's where we clean up the impossible tokens // here's where we clean up the impossible tokens
if(token.status == Token::INVALID) { if (token.status == Token::INVALID) {
m_tokens.pop(); m_tokens.pop();
continue; continue;
} }
@@ -81,24 +65,23 @@ namespace YAML
} }
// no token? maybe we've actually finished // no token? maybe we've actually finished
if(m_endedStream) if (m_endedStream) {
return; return;
}
// no? then scan... // no? then scan...
ScanNextToken(); ScanNextToken();
} }
}
void Scanner::ScanNextToken() {
if (m_endedStream) {
return;
} }
// ScanNextToken if (!m_startedStream) {
// . The main scanning function; here we branch out and
// scan whatever the next token should be.
void Scanner::ScanNextToken()
{
if(m_endedStream)
return;
if(!m_startedStream)
return StartStream(); return StartStream();
}
// get rid of whitespace, etc. (in between tokens it should be irrelevent) // get rid of whitespace, etc. (in between tokens it should be irrelevent)
ScanToNextToken(); ScanToNextToken();
@@ -111,84 +94,102 @@ namespace YAML
// ***** // *****
// end of stream // end of stream
if(!INPUT) if (!INPUT) {
return EndStream(); return EndStream();
}
if(INPUT.column() == 0 && INPUT.peek() == Keys::Directive) if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive) {
return ScanDirective(); return ScanDirective();
}
// document token // document token
if(INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) {
return ScanDocStart(); return ScanDocStart();
}
if(INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) {
return ScanDocEnd(); return ScanDocEnd();
}
// flow start/end/entry // flow start/end/entry
if(INPUT.peek() == Keys::FlowSeqStart || INPUT.peek() == Keys::FlowMapStart) if (INPUT.peek() == Keys::FlowSeqStart ||
INPUT.peek() == Keys::FlowMapStart) {
return ScanFlowStart(); return ScanFlowStart();
}
if(INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) {
return ScanFlowEnd(); return ScanFlowEnd();
}
if(INPUT.peek() == Keys::FlowEntry) if (INPUT.peek() == Keys::FlowEntry) {
return ScanFlowEntry(); return ScanFlowEntry();
}
// block/map stuff // block/map stuff
if(Exp::BlockEntry().Matches(INPUT)) if (Exp::BlockEntry().Matches(INPUT)) {
return ScanBlockEntry(); return ScanBlockEntry();
}
if((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) {
return ScanKey(); return ScanKey();
}
if(GetValueRegex().Matches(INPUT)) if (GetValueRegex().Matches(INPUT)) {
return ScanValue(); return ScanValue();
}
// alias/anchor // alias/anchor
if(INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) {
return ScanAnchorOrAlias(); return ScanAnchorOrAlias();
}
// tag // tag
if(INPUT.peek() == Keys::Tag) if (INPUT.peek() == Keys::Tag) {
return ScanTag(); return ScanTag();
}
// special scalars // special scalars
if(InBlockContext() && (INPUT.peek() == Keys::LiteralScalar || INPUT.peek() == Keys::FoldedScalar)) if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar ||
INPUT.peek() == Keys::FoldedScalar)) {
return ScanBlockScalar(); return ScanBlockScalar();
}
if(INPUT.peek() == '\'' || INPUT.peek() == '\"') if (INPUT.peek() == '\'' || INPUT.peek() == '\"') {
return ScanQuotedScalar(); return ScanQuotedScalar();
}
// plain scalars // plain scalars
if((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()).Matches(INPUT)) if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow())
.Matches(INPUT)) {
return ScanPlainScalar(); return ScanPlainScalar();
}
// don't know what it is! // don't know what it is!
throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN); throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
} }
// ScanToNextToken void Scanner::ScanToNextToken() {
// . Eats input until we reach the next token-like thing. while (1) {
void Scanner::ScanToNextToken()
{
while(1) {
// first eat whitespace // first eat whitespace
while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
if(InBlockContext() && Exp::Tab().Matches(INPUT)) if (InBlockContext() && Exp::Tab().Matches(INPUT)) {
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
}
INPUT.eat(1); INPUT.eat(1);
} }
// then eat a comment // then eat a comment
if(Exp::Comment().Matches(INPUT)) { if (Exp::Comment().Matches(INPUT)) {
// eat until line break // eat until line break
while(INPUT && !Exp::Break().Matches(INPUT)) while (INPUT && !Exp::Break().Matches(INPUT)) {
INPUT.eat(1); INPUT.eat(1);
} }
}
// if it's NOT a line break, then we're done! // if it's NOT a line break, then we're done!
if(!Exp::Break().Matches(INPUT)) if (!Exp::Break().Matches(INPUT)) {
break; break;
}
// otherwise, let's eat the line break and keep going // otherwise, let's eat the line break and keep going
int n = Exp::Break().Match(INPUT); int n = Exp::Break().Match(INPUT);
@@ -198,197 +199,188 @@ namespace YAML
InvalidateSimpleKey(); InvalidateSimpleKey();
// new line - we may be able to accept a simple key now // new line - we may be able to accept a simple key now
if(InBlockContext()) if (InBlockContext()) {
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
} }
} }
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Misc. helpers // Misc. helpers
// IsWhitespaceToBeEaten // IsWhitespaceToBeEaten
// . We can eat whitespace if it's a space or tab // . We can eat whitespace if it's a space or tab
// . Note: originally tabs in block context couldn't be eaten // . Note: originally tabs in block context couldn't be eaten
// "where a simple key could be allowed // "where a simple key could be allowed
// (i.e., not at the beginning of a line, or following '-', '?', or ':')" // (i.e., not at the beginning of a line, or following '-', '?', or
// I think this is wrong, since tabs can be non-content whitespace; it's just // ':')"
// that they can't contribute to indentation, so once you've seen a tab in a // I think this is wrong, since tabs can be non-content whitespace; it's just
// line, you can't start a simple key // that they can't contribute to indentation, so once you've seen a tab in a
bool Scanner::IsWhitespaceToBeEaten(char ch) // line, you can't start a simple key
{ bool Scanner::IsWhitespaceToBeEaten(char ch) {
if(ch == ' ') if (ch == ' ') {
return true; return true;
}
if(ch == '\t') if (ch == '\t') {
return true; return true;
}
return false; return false;
} }
// GetValueRegex const RegEx& Scanner::GetValueRegex() const {
// . Get the appropriate regex to check if it's a value token if (InBlockContext()) {
const RegEx& Scanner::GetValueRegex() const
{
if(InBlockContext())
return Exp::Value(); return Exp::Value();
}
return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow(); return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
} }
// StartStream void Scanner::StartStream() {
// . Set the initial conditions for starting a stream.
void Scanner::StartStream()
{
m_startedStream = true; m_startedStream = true;
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE)); std::unique_ptr<IndentMarker> pIndent(
m_indentRefs.push_back(pIndent); new IndentMarker(-1, IndentMarker::NONE));
m_indentRefs.push_back(std::move(pIndent));
m_indents.push(&m_indentRefs.back()); m_indents.push(&m_indentRefs.back());
} }
// EndStream void Scanner::EndStream() {
// . Close out the stream, finish up, etc.
void Scanner::EndStream()
{
// force newline // force newline
if(INPUT.column() > 0) if (INPUT.column() > 0) {
INPUT.ResetColumn(); INPUT.ResetColumn();
}
PopAllIndents(); PopAllIndents();
PopAllSimpleKeys(); PopAllSimpleKeys();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
m_endedStream = true; m_endedStream = true;
} }
Token *Scanner::PushToken(Token::TYPE type) Token* Scanner::PushToken(Token::TYPE type) {
{
m_tokens.push(Token(type, INPUT.mark())); m_tokens.push(Token(type, INPUT.mark()));
return &m_tokens.back(); return &m_tokens.back();
} }
Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const {
{ switch (type) {
switch(type) { case IndentMarker::SEQ:
case IndentMarker::SEQ: return Token::BLOCK_SEQ_START; return Token::BLOCK_SEQ_START;
case IndentMarker::MAP: return Token::BLOCK_MAP_START; case IndentMarker::MAP:
case IndentMarker::NONE: assert(false); break; return Token::BLOCK_MAP_START;
case IndentMarker::NONE:
assert(false);
break;
} }
assert(false); assert(false);
throw std::runtime_error("yaml-cpp: internal error, invalid indent type"); throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
}
Scanner::IndentMarker* Scanner::PushIndentTo(int column,
IndentMarker::INDENT_TYPE type) {
// are we in flow?
if (InFlowContext()) {
return 0;
} }
// PushIndentTo std::unique_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
// . Pushes an indentation onto the stack, and enqueues the
// proper token (sequence start or mapping start).
// . Returns the indent marker it generates (if any).
Scanner::IndentMarker *Scanner::PushIndentTo(int column, IndentMarker::INDENT_TYPE type)
{
// are we in flow?
if(InFlowContext())
return 0;
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
IndentMarker& indent = *pIndent; IndentMarker& indent = *pIndent;
const IndentMarker& lastIndent = *m_indents.top(); const IndentMarker& lastIndent = *m_indents.top();
// is this actually an indentation? // is this actually an indentation?
if(indent.column < lastIndent.column) if (indent.column < lastIndent.column) {
return 0; return 0;
if(indent.column == lastIndent.column && !(indent.type == IndentMarker::SEQ && lastIndent.type == IndentMarker::MAP)) }
if (indent.column == lastIndent.column &&
!(indent.type == IndentMarker::SEQ &&
lastIndent.type == IndentMarker::MAP)) {
return 0; return 0;
}
// push a start token // push a start token
indent.pStartToken = PushToken(GetStartTokenFor(type)); indent.pStartToken = PushToken(GetStartTokenFor(type));
// and then the indent // and then the indent
m_indents.push(&indent); m_indents.push(&indent);
m_indentRefs.push_back(pIndent); m_indentRefs.push_back(std::move(pIndent));
return &m_indentRefs.back(); return &m_indentRefs.back();
} }
// PopIndentToHere void Scanner::PopIndentToHere() {
// . Pops indentations off the stack until we reach the current indentation level,
// and enqueues the proper token each time.
// . Then pops all invalid indentations off.
void Scanner::PopIndentToHere()
{
// are we in flow? // are we in flow?
if(InFlowContext()) if (InFlowContext()) {
return; return;
}
// now pop away // now pop away
while(!m_indents.empty()) { while (!m_indents.empty()) {
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
if(indent.column < INPUT.column()) if (indent.column < INPUT.column()) {
break; break;
if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry().Matches(INPUT))) }
if (indent.column == INPUT.column() &&
!(indent.type == IndentMarker::SEQ &&
!Exp::BlockEntry().Matches(INPUT))) {
break; break;
}
PopIndent(); PopIndent();
} }
while(!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID) while (!m_indents.empty() &&
m_indents.top()->status == IndentMarker::INVALID) {
PopIndent(); PopIndent();
} }
}
// PopAllIndents void Scanner::PopAllIndents() {
// . Pops all indentations (except for the base empty one) off the stack,
// and enqueues the proper token each time.
void Scanner::PopAllIndents()
{
// are we in flow? // are we in flow?
if(InFlowContext()) if (InFlowContext()) {
return; return;
}
// now pop away // now pop away
while(!m_indents.empty()) { while (!m_indents.empty()) {
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
if(indent.type == IndentMarker::NONE) if (indent.type == IndentMarker::NONE) {
break; break;
}
PopIndent(); PopIndent();
} }
} }
// PopIndent void Scanner::PopIndent() {
// . Pops a single indent, pushing the proper token
void Scanner::PopIndent()
{
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
m_indents.pop(); m_indents.pop();
if(indent.status != IndentMarker::VALID) { if (indent.status != IndentMarker::VALID) {
InvalidateSimpleKey(); InvalidateSimpleKey();
return; return;
} }
if(indent.type == IndentMarker::SEQ) if (indent.type == IndentMarker::SEQ) {
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark())); m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
else if(indent.type == IndentMarker::MAP) } else if (indent.type == IndentMarker::MAP) {
m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark())); m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
} }
}
// GetTopIndent int Scanner::GetTopIndent() const {
int Scanner::GetTopIndent() const if (m_indents.empty()) {
{
if(m_indents.empty())
return 0; return 0;
return m_indents.top()->column;
} }
return m_indents.top()->column;
}
// ThrowParserException void Scanner::ThrowParserException(const std::string& msg) const {
// . Throws a ParserException with the current token location
// (if available).
// . Does not parse any more tokens.
void Scanner::ThrowParserException(const std::string& msg) const
{
Mark mark = Mark::null_mark(); Mark mark = Mark::null_mark();
if(!m_tokens.empty()) { if (!m_tokens.empty()) {
const Token& token = m_tokens.front(); const Token& token = m_tokens.front();
mark = token.mark; mark = token.mark;
} }
throw ParserException(mark, msg); throw ParserException(mark, msg);
}
} }
} // namespace YAML

View File

@@ -1,43 +1,55 @@
#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANNER_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef>
#include <ios> #include <ios>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map> #include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include "ptr_vector.h" #include "ptr_vector.h"
#include "stream.h" #include "stream.h"
#include "token.h" #include "token.h"
#include "yaml-cpp/mark.h"
namespace YAML namespace YAML {
{ class Node;
class Node; class RegEx;
class RegEx;
class Scanner /**
{ * A scanner transforms a stream of characters into a stream of tokens.
*/
class Scanner {
public: public:
Scanner(std::istream& in); explicit Scanner(std::istream &in);
~Scanner(); ~Scanner();
// token queue management (hopefully this looks kinda stl-ish) /** Returns true if there are no more tokens to be read. */
bool empty(); bool empty();
/** Removes the next token in the queue. */
void pop(); void pop();
Token& peek();
/** Returns, but does not remove, the next token in the queue. */
Token &peek();
/** Returns the current mark in the input stream. */
Mark mark() const; Mark mark() const;
private: private:
struct IndentMarker { struct IndentMarker {
enum INDENT_TYPE { MAP, SEQ, NONE }; enum INDENT_TYPE { MAP, SEQ, NONE };
enum STATUS { VALID, INVALID, UNKNOWN }; enum STATUS { VALID, INVALID, UNKNOWN };
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {} IndentMarker(int column_, INDENT_TYPE type_)
: column(column_), type(type_), status(VALID), pStartToken(0) {}
int column; int column;
INDENT_TYPE type; INDENT_TYPE type;
@@ -49,21 +61,59 @@ namespace YAML
private: private:
// scanning // scanning
/**
* Scans until there's a valid token at the front of the queue, or the queue
* is empty. The state can be checked by {@link #empty}, and the next token
* retrieved by {@link #peek}.
*/
void EnsureTokensInQueue(); void EnsureTokensInQueue();
/**
* The main scanning function; this method branches out to scan whatever the
* next token should be.
*/
void ScanNextToken(); void ScanNextToken();
/** Eats the input stream until it reaches the next token-like thing. */
void ScanToNextToken(); void ScanToNextToken();
/** Sets the initial conditions for starting a stream. */
void StartStream(); void StartStream();
/** Closes out the stream, finish up, etc. */
void EndStream(); void EndStream();
Token *PushToken(Token::TYPE type); Token *PushToken(Token::TYPE type);
bool InFlowContext() const { return !m_flows.empty(); } bool InFlowContext() const { return !m_flows.empty(); }
bool InBlockContext() const { return m_flows.empty(); } bool InBlockContext() const { return m_flows.empty(); }
int GetFlowLevel() const { return m_flows.size(); } std::size_t GetFlowLevel() const { return m_flows.size(); }
Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const; Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
/**
* Pushes an indentation onto the stack, and enqueues the proper token
* (sequence start or mapping start).
*
* @return the indent marker it generates (if any).
*/
IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type); IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
/**
* Pops indentations off the stack until it reaches the current indentation
* level, and enqueues the proper token each time. Then pops all invalid
* indentations off.
*/
void PopIndentToHere(); void PopIndentToHere();
/**
* Pops all indentations (except for the base empty one) off the stack, and
* enqueues the proper token each time.
*/
void PopAllIndents(); void PopAllIndents();
/** Pops a single indent, pushing the proper token. */
void PopIndent(); void PopIndent();
int GetTopIndent() const; int GetTopIndent() const;
@@ -75,19 +125,27 @@ namespace YAML
bool VerifySimpleKey(); bool VerifySimpleKey();
void PopAllSimpleKeys(); void PopAllSimpleKeys();
void ThrowParserException(const std::string& msg) const; /**
* Throws a ParserException with the current token location (if available),
* and does not parse any more tokens.
*/
void ThrowParserException(const std::string &msg) const;
bool IsWhitespaceToBeEaten(char ch); bool IsWhitespaceToBeEaten(char ch);
const RegEx& GetValueRegex() const;
/**
* Returns the appropriate regex to check if the next token is a value token.
*/
const RegEx &GetValueRegex() const;
struct SimpleKey { struct SimpleKey {
SimpleKey(const Mark& mark_, int flowLevel_); SimpleKey(const Mark &mark_, std::size_t flowLevel_);
void Validate(); void Validate();
void Invalidate(); void Invalidate();
Mark mark; Mark mark;
int flowLevel; std::size_t flowLevel;
IndentMarker *pIndent; IndentMarker *pIndent;
Token *pMapStart, *pKey; Token *pMapStart, *pKey;
}; };
@@ -126,8 +184,7 @@ namespace YAML
std::stack<IndentMarker *> m_indents; std::stack<IndentMarker *> m_indents;
ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection" ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
std::stack<FLOW_MARKER> m_flows; std::stack<FLOW_MARKER> m_flows;
}; };
} }
#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,23 +1,24 @@
#include "scanscalar.h" #include "scanscalar.h"
#include "scanner.h"
#include "exp.h"
#include "yaml-cpp/exceptions.h"
#include "token.h"
namespace YAML #include <algorithm>
{
// ScanScalar #include "exp.h"
// . This is where the scalar magic happens. #include "regeximpl.h"
// #include "stream.h"
// . We do the scanning in three phases: #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
// 1. Scan until newline
// 2. Eat newline namespace YAML {
// 3. Scan leading blanks. // ScanScalar
// // . This is where the scalar magic happens.
// . Depending on the parameters given, we store or stop //
// and different places in the above flow. // . We do the scanning in three phases:
std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) // 1. Scan until newline
{ // 2. Eat newline
// 3. Scan leading blanks.
//
// . Depending on the parameters given, we store or stop
// and different places in the above flow.
std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
bool foundNonEmptyLine = false; bool foundNonEmptyLine = false;
bool pastOpeningBreak = (params.fold == FOLD_FLOW); bool pastOpeningBreak = (params.fold == FOLD_FLOW);
bool emptyLine = false, moreIndented = false; bool emptyLine = false, moreIndented = false;
@@ -27,29 +28,35 @@ namespace YAML
std::string scalar; std::string scalar;
params.leadingSpaces = false; params.leadingSpaces = false;
while(INPUT) { if (!params.end) {
params.end = &Exp::Empty();
}
while (INPUT) {
// ******************************** // ********************************
// Phase #1: scan until line ending // Phase #1: scan until line ending
std::size_t lastNonWhitespaceChar = scalar.size(); std::size_t lastNonWhitespaceChar = scalar.size();
bool escapedNewline = false; bool escapedNewline = false;
while(!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) { while (!params.end->Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
if(!INPUT) if (!INPUT) {
break; break;
}
// document indicator? // document indicator?
if(INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) { if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
if(params.onDocIndicator == BREAK) if (params.onDocIndicator == BREAK) {
break; break;
else if(params.onDocIndicator == THROW) } else if (params.onDocIndicator == THROW) {
throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
} }
}
foundNonEmptyLine = true; foundNonEmptyLine = true;
pastOpeningBreak = true; pastOpeningBreak = true;
// escaped newline? (only if we're escaping on slash) // escaped newline? (only if we're escaping on slash)
if(params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) { if (params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
// eat escape character and get out (but preserve trailing whitespace!) // eat escape character and get out (but preserve trailing whitespace!)
INPUT.get(); INPUT.get();
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
@@ -59,7 +66,7 @@ namespace YAML
} }
// escape this? // escape this?
if(INPUT.peek() == params.escape) { if (INPUT.peek() == params.escape) {
scalar += Exp::Escape(INPUT); scalar += Exp::Escape(INPUT);
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
lastEscapedChar = scalar.size(); lastEscapedChar = scalar.size();
@@ -69,31 +76,36 @@ namespace YAML
// otherwise, just add the damn character // otherwise, just add the damn character
char ch = INPUT.get(); char ch = INPUT.get();
scalar += ch; scalar += ch;
if(ch != ' ' && ch != '\t') if (ch != ' ' && ch != '\t') {
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
} }
}
// eof? if we're looking to eat something, then we throw // eof? if we're looking to eat something, then we throw
if(!INPUT) { if (!INPUT) {
if(params.eatEnd) if (params.eatEnd) {
throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR); throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
}
break; break;
} }
// doc indicator? // doc indicator?
if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) if (params.onDocIndicator == BREAK && INPUT.column() == 0 &&
Exp::DocIndicator().Matches(INPUT)) {
break; break;
}
// are we done via character match? // are we done via character match?
int n = params.end.Match(INPUT); int n = params.end->Match(INPUT);
if(n >= 0) { if (n >= 0) {
if(params.eatEnd) if (params.eatEnd) {
INPUT.eat(n); INPUT.eat(n);
}
break; break;
} }
// do we remove trailing whitespace? // do we remove trailing whitespace?
if(params.fold == FOLD_FLOW) if (params.fold == FOLD_FLOW)
scalar.erase(lastNonWhitespaceChar); scalar.erase(lastNonWhitespaceChar);
// ******************************** // ********************************
@@ -105,21 +117,33 @@ namespace YAML
// Phase #3: scan initial spaces // Phase #3: scan initial spaces
// first the required indentation // first the required indentation
while(INPUT.peek() == ' ' && (INPUT.column() < params.indent || (params.detectIndent && !foundNonEmptyLine))) while (INPUT.peek() == ' ' &&
(INPUT.column() < params.indent ||
(params.detectIndent && !foundNonEmptyLine)) &&
!params.end->Matches(INPUT)) {
INPUT.eat(1); INPUT.eat(1);
}
// update indent if we're auto-detecting // update indent if we're auto-detecting
if(params.detectIndent && !foundNonEmptyLine) if (params.detectIndent && !foundNonEmptyLine) {
params.indent = std::max(params.indent, INPUT.column()); params.indent = std::max(params.indent, INPUT.column());
}
// and then the rest of the whitespace // and then the rest of the whitespace
while(Exp::Blank().Matches(INPUT)) { while (Exp::Blank().Matches(INPUT)) {
// we check for tabs that masquerade as indentation // we check for tabs that masquerade as indentation
if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW) if (INPUT.peek() == '\t' && INPUT.column() < params.indent &&
params.onTabInIndentation == THROW) {
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION); throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
}
if(!params.eatLeadingWhitespace) if (!params.eatLeadingWhitespace) {
break; break;
}
if (params.end->Matches(INPUT)) {
break;
}
INPUT.eat(1); INPUT.eat(1);
} }
@@ -127,35 +151,41 @@ namespace YAML
// was this an empty line? // was this an empty line?
bool nextEmptyLine = Exp::Break().Matches(INPUT); bool nextEmptyLine = Exp::Break().Matches(INPUT);
bool nextMoreIndented = Exp::Blank().Matches(INPUT); bool nextMoreIndented = Exp::Blank().Matches(INPUT);
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine) if (params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
foldedNewlineStartedMoreIndented = moreIndented; foldedNewlineStartedMoreIndented = moreIndented;
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep) // for block scalars, we always start with a newline, so we should ignore it
if(pastOpeningBreak) { // (not fold or keep)
switch(params.fold) { if (pastOpeningBreak) {
switch (params.fold) {
case DONT_FOLD: case DONT_FOLD:
scalar += "\n"; scalar += "\n";
break; break;
case FOLD_BLOCK: case FOLD_BLOCK:
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent) if (!emptyLine && !nextEmptyLine && !moreIndented &&
!nextMoreIndented && INPUT.column() >= params.indent) {
scalar += " "; scalar += " ";
else if(nextEmptyLine) } else if (nextEmptyLine) {
foldedNewlineCount++; foldedNewlineCount++;
else } else {
scalar += "\n"; scalar += "\n";
}
if(!nextEmptyLine && foldedNewlineCount > 0) { if (!nextEmptyLine && foldedNewlineCount > 0) {
scalar += std::string(foldedNewlineCount - 1, '\n'); scalar += std::string(foldedNewlineCount - 1, '\n');
if(foldedNewlineStartedMoreIndented || nextMoreIndented | !foundNonEmptyLine) if (foldedNewlineStartedMoreIndented ||
nextMoreIndented | !foundNonEmptyLine) {
scalar += "\n"; scalar += "\n";
}
foldedNewlineCount = 0; foldedNewlineCount = 0;
} }
break; break;
case FOLD_FLOW: case FOLD_FLOW:
if(nextEmptyLine) if (nextEmptyLine) {
scalar += "\n"; scalar += "\n";
else if(!emptyLine && !nextEmptyLine && !escapedNewline) } else if (!emptyLine && !nextEmptyLine && !escapedNewline) {
scalar += " "; scalar += " ";
}
break; break;
} }
} }
@@ -165,50 +195,56 @@ namespace YAML
pastOpeningBreak = true; pastOpeningBreak = true;
// are we done via indentation? // are we done via indentation?
if(!emptyLine && INPUT.column() < params.indent) { if (!emptyLine && INPUT.column() < params.indent) {
params.leadingSpaces = true; params.leadingSpaces = true;
break; break;
} }
} }
// post-processing // post-processing
if(params.trimTrailingSpaces) { if (params.trimTrailingSpaces) {
std::size_t pos = scalar.find_last_not_of(' '); std::size_t pos = scalar.find_last_not_of(' ');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos) {
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos < scalar.size()) }
if (pos < scalar.size()) {
scalar.erase(pos + 1); scalar.erase(pos + 1);
} }
}
switch(params.chomp) { switch (params.chomp) {
case CLIP: { case CLIP: {
std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos) {
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos == std::string::npos) }
if (pos == std::string::npos) {
scalar.erase(); scalar.erase();
else if(pos + 1 < scalar.size()) } else if (pos + 1 < scalar.size()) {
scalar.erase(pos + 2); scalar.erase(pos + 2);
}
} break; } break;
case STRIP: { case STRIP: {
std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos) {
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos == std::string::npos) }
if (pos == std::string::npos) {
scalar.erase(); scalar.erase();
else if(pos < scalar.size()) } else if (pos < scalar.size()) {
scalar.erase(pos + 1); scalar.erase(pos + 1);
}
} break; } break;
default: default:
break; break;
} }
return scalar; return scalar;
} }
} }

View File

@@ -1,45 +1,63 @@
#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANSCALAR_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include "regex.h"
#include "regex_yaml.h"
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ enum CHOMP { STRIP = -1, CLIP, KEEP };
enum CHOMP { STRIP = -1, CLIP, KEEP }; enum ACTION { NONE, BREAK, THROW };
enum ACTION { NONE, BREAK, THROW }; enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
struct ScanScalarParams { struct ScanScalarParams {
ScanScalarParams(): eatEnd(false), indent(0), detectIndent(false), eatLeadingWhitespace(0), escape(0), fold(DONT_FOLD), ScanScalarParams()
trimTrailingSpaces(0), chomp(CLIP), onDocIndicator(NONE), onTabInIndentation(NONE), leadingSpaces(false) {} : end(nullptr),
eatEnd(false),
indent(0),
detectIndent(false),
eatLeadingWhitespace(0),
escape(0),
fold(DONT_FOLD),
trimTrailingSpaces(0),
chomp(CLIP),
onDocIndicator(NONE),
onTabInIndentation(NONE),
leadingSpaces(false) {}
// input: // input:
RegEx end; // what condition ends this scalar? const RegEx* end; // what condition ends this scalar?
// unowned.
bool eatEnd; // should we eat that condition when we see it? bool eatEnd; // should we eat that condition when we see it?
int indent; // what level of indentation should be eaten and ignored? int indent; // what level of indentation should be eaten and ignored?
bool detectIndent; // should we try to autodetect the indent? bool detectIndent; // should we try to autodetect the indent?
bool eatLeadingWhitespace; // should we continue eating this delicious indentation after 'indent' spaces? bool eatLeadingWhitespace; // should we continue eating this delicious
char escape; // what character do we escape on (i.e., slash or single quote) (0 for none) // indentation after 'indent' spaces?
char escape; // what character do we escape on (i.e., slash or single quote)
// (0 for none)
FOLD fold; // how do we fold line ends? FOLD fold; // how do we fold line ends?
bool trimTrailingSpaces; // do we remove all trailing spaces (at the very end) bool trimTrailingSpaces; // do we remove all trailing spaces (at the very
CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very end) // end)
// Note: strip means kill all, clip means keep at most one, keep means keep all CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very
// end)
// Note: strip means kill all, clip means keep at most one, keep means keep
// all
ACTION onDocIndicator; // what do we do if we see a document indicator? ACTION onDocIndicator; // what do we do if we see a document indicator?
ACTION onTabInIndentation; // what do we do if we see a tab where we should be seeing indentation spaces ACTION onTabInIndentation; // what do we do if we see a tab where we should
// be seeing indentation spaces
// output: // output:
bool leadingSpaces; bool leadingSpaces;
}; };
std::string ScanScalar(Stream& INPUT, ScanScalarParams& info); std::string ScanScalar(Stream& INPUT, ScanScalarParams& info);
} }
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,84 +1,81 @@
#include "scanner.h"
#include "regex.h"
#include "exp.h" #include "exp.h"
#include "yaml-cpp/exceptions.h" #include "regex_yaml.h"
#include "regeximpl.h"
#include "stream.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
#include "yaml-cpp/mark.h"
namespace YAML namespace YAML {
{ const std::string ScanVerbatimTag(Stream& INPUT) {
const std::string ScanVerbatimTag(Stream& INPUT)
{
std::string tag; std::string tag;
// eat the start character // eat the start character
INPUT.get(); INPUT.get();
while(INPUT) { while (INPUT) {
if(INPUT.peek() == Keys::VerbatimTagEnd) { if (INPUT.peek() == Keys::VerbatimTagEnd) {
// eat the end character // eat the end character
INPUT.get(); INPUT.get();
return tag; return tag;
} }
int n = Exp::URI().Match(INPUT); int n = Exp::URI().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG); throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
} }
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) {
{
std::string tag; std::string tag;
canBeHandle = true; canBeHandle = true;
Mark firstNonWordChar; Mark firstNonWordChar;
while(INPUT) { while (INPUT) {
if(INPUT.peek() == Keys::Tag) { if (INPUT.peek() == Keys::Tag) {
if(!canBeHandle) if (!canBeHandle)
throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE); throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
break; break;
} }
int n = 0; int n = 0;
if(canBeHandle) { if (canBeHandle) {
n = Exp::Word().Match(INPUT); n = Exp::Word().Match(INPUT);
if(n <= 0) { if (n <= 0) {
canBeHandle = false; canBeHandle = false;
firstNonWordChar = INPUT.mark(); firstNonWordChar = INPUT.mark();
} }
} }
if(!canBeHandle) if (!canBeHandle)
n = Exp::Tag().Match(INPUT); n = Exp::Tag().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
return tag; return tag;
} }
const std::string ScanTagSuffix(Stream& INPUT) const std::string ScanTagSuffix(Stream& INPUT) {
{
std::string tag; std::string tag;
while(INPUT) { while (INPUT) {
int n = Exp::Tag().Match(INPUT); int n = Exp::Tag().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
if(tag.empty()) if (tag.empty())
throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX); throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
return tag; return tag;
}
} }
}

View File

@@ -1,20 +1,19 @@
#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANTAG_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ const std::string ScanVerbatimTag(Stream& INPUT);
const std::string ScanVerbatimTag(Stream& INPUT); const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle); const std::string ScanTagSuffix(Stream& INPUT);
const std::string ScanTagSuffix(Stream& INPUT);
} }
#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,23 +1,25 @@
#include "scanner.h"
#include "token.h"
#include "yaml-cpp/exceptions.h"
#include "exp.h"
#include "scanscalar.h"
#include "scantag.h"
#include "tag.h"
#include <sstream> #include <sstream>
namespace YAML #include "exp.h"
{ #include "regex_yaml.h"
/////////////////////////////////////////////////////////////////////// #include "regeximpl.h"
// Specialization for scanning specific tokens #include "scanner.h"
#include "scanscalar.h"
#include "scantag.h" // IWYU pragma: keep
#include "tag.h" // IWYU pragma: keep
#include "token.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
#include "yaml-cpp/mark.h"
// Directive namespace YAML {
// . Note: no semantic checking is done here (that's for the parser to do) ///////////////////////////////////////////////////////////////////////
void Scanner::ScanDirective() // Specialization for scanning specific tokens
{
// Directive
// . Note: no semantic checking is done here (that's for the parser to do)
void Scanner::ScanDirective() {
std::string name; std::string name;
std::vector <std::string> params; std::vector<std::string> params;
// pop indents and simple keys // pop indents and simple keys
PopAllIndents(); PopAllIndents();
@@ -31,33 +33,32 @@ namespace YAML
INPUT.eat(1); INPUT.eat(1);
// read name // read name
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT)) while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
token.value += INPUT.get(); token.value += INPUT.get();
// read parameters // read parameters
while(1) { while (1) {
// first get rid of whitespace // first get rid of whitespace
while(Exp::Blank().Matches(INPUT)) while (Exp::Blank().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// break on newline or comment // break on newline or comment
if(!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT)) if (!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT))
break; break;
// now read parameter // now read parameter
std::string param; std::string param;
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT)) while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
param += INPUT.get(); param += INPUT.get();
token.params.push_back(param); token.params.push_back(param);
} }
m_tokens.push(token); m_tokens.push(token);
} }
// DocStart // DocStart
void Scanner::ScanDocStart() void Scanner::ScanDocStart() {
{
PopAllIndents(); PopAllIndents();
PopAllSimpleKeys(); PopAllSimpleKeys();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -67,11 +68,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(Token(Token::DOC_START, mark)); m_tokens.push(Token(Token::DOC_START, mark));
} }
// DocEnd // DocEnd
void Scanner::ScanDocEnd() void Scanner::ScanDocEnd() {
{
PopAllIndents(); PopAllIndents();
PopAllSimpleKeys(); PopAllSimpleKeys();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -81,11 +81,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(Token(Token::DOC_END, mark)); m_tokens.push(Token(Token::DOC_END, mark));
} }
// FlowStart // FlowStart
void Scanner::ScanFlowStart() void Scanner::ScanFlowStart() {
{
// flows can be simple keys // flows can be simple keys
InsertPotentialSimpleKey(); InsertPotentialSimpleKey();
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
@@ -96,21 +95,21 @@ namespace YAML
char ch = INPUT.get(); char ch = INPUT.get();
FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP); FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP);
m_flows.push(flowType); m_flows.push(flowType);
Token::TYPE type = (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START); Token::TYPE type =
(flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START);
m_tokens.push(Token(type, mark)); m_tokens.push(Token(type, mark));
} }
// FlowEnd // FlowEnd
void Scanner::ScanFlowEnd() void Scanner::ScanFlowEnd() {
{ if (InBlockContext())
if(InBlockContext())
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
// we might have a solo entry in the flow context // we might have a solo entry in the flow context
if(InFlowContext()) { if (InFlowContext()) {
if(m_flows.top() == FLOW_MAP && VerifySimpleKey()) if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
m_tokens.push(Token(Token::VALUE, INPUT.mark())); m_tokens.push(Token(Token::VALUE, INPUT.mark()));
else if(m_flows.top() == FLOW_SEQ) else if (m_flows.top() == FLOW_SEQ)
InvalidateSimpleKey(); InvalidateSimpleKey();
} }
@@ -123,22 +122,21 @@ namespace YAML
// check that it matches the start // check that it matches the start
FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP); FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP);
if(m_flows.top() != flowType) if (m_flows.top() != flowType)
throw ParserException(mark, ErrorMsg::FLOW_END); throw ParserException(mark, ErrorMsg::FLOW_END);
m_flows.pop(); m_flows.pop();
Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END); Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END);
m_tokens.push(Token(type, mark)); m_tokens.push(Token(type, mark));
} }
// FlowEntry // FlowEntry
void Scanner::ScanFlowEntry() void Scanner::ScanFlowEntry() {
{
// we might have a solo entry in the flow context // we might have a solo entry in the flow context
if(InFlowContext()) { if (InFlowContext()) {
if(m_flows.top() == FLOW_MAP && VerifySimpleKey()) if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
m_tokens.push(Token(Token::VALUE, INPUT.mark())); m_tokens.push(Token(Token::VALUE, INPUT.mark()));
else if(m_flows.top() == FLOW_SEQ) else if (m_flows.top() == FLOW_SEQ)
InvalidateSimpleKey(); InvalidateSimpleKey();
} }
@@ -149,17 +147,16 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::FLOW_ENTRY, mark)); m_tokens.push(Token(Token::FLOW_ENTRY, mark));
} }
// BlockEntry // BlockEntry
void Scanner::ScanBlockEntry() void Scanner::ScanBlockEntry() {
{
// we better be in the block context! // we better be in the block context!
if(InFlowContext()) if (InFlowContext())
throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
// can we put it here? // can we put it here?
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
PushIndentTo(INPUT.column(), IndentMarker::SEQ); PushIndentTo(INPUT.column(), IndentMarker::SEQ);
@@ -170,14 +167,13 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::BLOCK_ENTRY, mark)); m_tokens.push(Token(Token::BLOCK_ENTRY, mark));
} }
// Key // Key
void Scanner::ScanKey() void Scanner::ScanKey() {
{
// handle keys diffently in the block context (and manage indents) // handle keys diffently in the block context (and manage indents)
if(InBlockContext()) { if (InBlockContext()) {
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY);
PushIndentTo(INPUT.column(), IndentMarker::MAP); PushIndentTo(INPUT.column(), IndentMarker::MAP);
@@ -190,22 +186,22 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::KEY, mark)); m_tokens.push(Token(Token::KEY, mark));
} }
// Value // Value
void Scanner::ScanValue() void Scanner::ScanValue() {
{
// and check that simple key // and check that simple key
bool isSimpleKey = VerifySimpleKey(); bool isSimpleKey = VerifySimpleKey();
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
if(isSimpleKey) { if (isSimpleKey) {
// can't follow a simple key with another simple key (dunno why, though - it seems fine) // can't follow a simple key with another simple key (dunno why, though - it
// seems fine)
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
} else { } else {
// handle values diffently in the block context (and manage indents) // handle values diffently in the block context (and manage indents)
if(InBlockContext()) { if (InBlockContext()) {
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
PushIndentTo(INPUT.column(), IndentMarker::MAP); PushIndentTo(INPUT.column(), IndentMarker::MAP);
@@ -219,11 +215,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::VALUE, mark)); m_tokens.push(Token(Token::VALUE, mark));
} }
// AnchorOrAlias // AnchorOrAlias
void Scanner::ScanAnchorOrAlias() void Scanner::ScanAnchorOrAlias() {
{
bool alias; bool alias;
std::string name; std::string name;
@@ -238,26 +233,27 @@ namespace YAML
alias = (indicator == Keys::Alias); alias = (indicator == Keys::Alias);
// now eat the content // now eat the content
while(INPUT && Exp::Anchor().Matches(INPUT)) while (INPUT && Exp::Anchor().Matches(INPUT))
name += INPUT.get(); name += INPUT.get();
// we need to have read SOMETHING! // we need to have read SOMETHING!
if(name.empty()) if (name.empty())
throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND); throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND
: ErrorMsg::ANCHOR_NOT_FOUND);
// and needs to end correctly // and needs to end correctly
if(INPUT && !Exp::AnchorEnd().Matches(INPUT)) if (INPUT && !Exp::AnchorEnd().Matches(INPUT))
throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR); throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS
: ErrorMsg::CHAR_IN_ANCHOR);
// and we're done // and we're done
Token token(alias ? Token::ALIAS : Token::ANCHOR, mark); Token token(alias ? Token::ALIAS : Token::ANCHOR, mark);
token.value = name; token.value = name;
m_tokens.push(token); m_tokens.push(token);
} }
// Tag // Tag
void Scanner::ScanTag() void Scanner::ScanTag() {
{
// insert a potential simple key // insert a potential simple key
InsertPotentialSimpleKey(); InsertPotentialSimpleKey();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -268,7 +264,7 @@ namespace YAML
// eat the indicator // eat the indicator
INPUT.get(); INPUT.get();
if(INPUT && INPUT.peek() == Keys::VerbatimTagStart){ if (INPUT && INPUT.peek() == Keys::VerbatimTagStart) {
std::string tag = ScanVerbatimTag(INPUT); std::string tag = ScanVerbatimTag(INPUT);
token.value = tag; token.value = tag;
@@ -276,15 +272,15 @@ namespace YAML
} else { } else {
bool canBeHandle; bool canBeHandle;
token.value = ScanTagHandle(INPUT, canBeHandle); token.value = ScanTagHandle(INPUT, canBeHandle);
if(!canBeHandle && token.value.empty()) if (!canBeHandle && token.value.empty())
token.data = Tag::NON_SPECIFIC; token.data = Tag::NON_SPECIFIC;
else if(token.value.empty()) else if (token.value.empty())
token.data = Tag::SECONDARY_HANDLE; token.data = Tag::SECONDARY_HANDLE;
else else
token.data = Tag::PRIMARY_HANDLE; token.data = Tag::PRIMARY_HANDLE;
// is there a suffix? // is there a suffix?
if(canBeHandle && INPUT.peek() == Keys::Tag) { if (canBeHandle && INPUT.peek() == Keys::Tag) {
// eat the indicator // eat the indicator
INPUT.get(); INPUT.get();
token.params.push_back(ScanTagSuffix(INPUT)); token.params.push_back(ScanTagSuffix(INPUT));
@@ -293,16 +289,16 @@ namespace YAML
} }
m_tokens.push(token); m_tokens.push(token);
} }
// PlainScalar // PlainScalar
void Scanner::ScanPlainScalar() void Scanner::ScanPlainScalar() {
{
std::string scalar; std::string scalar;
// set up the scanning parameters // set up the scanning parameters
ScanScalarParams params; ScanScalarParams params;
params.end = (InFlowContext() ? Exp::EndScalarInFlow() : Exp::EndScalar()) || (Exp::BlankOrBreak() + Exp::Comment()); params.end =
(InFlowContext() ? &Exp::ScanScalarEndInFlow() : &Exp::ScanScalarEnd());
params.eatEnd = false; params.eatEnd = false;
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
params.fold = FOLD_FLOW; params.fold = FOLD_FLOW;
@@ -323,26 +319,27 @@ namespace YAML
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
// finally, check and see if we ended on an illegal character // finally, check and see if we ended on an illegal character
//if(Exp::IllegalCharInScalar.Matches(INPUT)) // if(Exp::IllegalCharInScalar.Matches(INPUT))
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
Token token(Token::PLAIN_SCALAR, mark); Token token(Token::PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
// QuotedScalar // QuotedScalar
void Scanner::ScanQuotedScalar() void Scanner::ScanQuotedScalar() {
{
std::string scalar; std::string scalar;
// peek at single or double quote (don't eat because we need to preserve (for the time being) the input position) // peek at single or double quote (don't eat because we need to preserve (for
// the time being) the input position)
char quote = INPUT.peek(); char quote = INPUT.peek();
bool single = (quote == '\''); bool single = (quote == '\'');
// setup the scanning parameters // setup the scanning parameters
ScanScalarParams params; ScanScalarParams params;
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote)); RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
params.end = &end;
params.eatEnd = true; params.eatEnd = true;
params.escape = (single ? '\'' : '\\'); params.escape = (single ? '\'' : '\\');
params.indent = 0; params.indent = 0;
@@ -368,14 +365,14 @@ namespace YAML
Token token(Token::NON_PLAIN_SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
// BlockScalarToken // BlockScalarToken
// . These need a little extra processing beforehand. // . These need a little extra processing beforehand.
// . We need to scan the line where the indicator is (this doesn't count as part of the scalar), // . We need to scan the line where the indicator is (this doesn't count as part
// and then we need to figure out what level of indentation we'll be using. // of the scalar),
void Scanner::ScanBlockScalar() // and then we need to figure out what level of indentation we'll be using.
{ void Scanner::ScanBlockScalar() {
std::string scalar; std::string scalar;
ScanScalarParams params; ScanScalarParams params;
@@ -390,14 +387,14 @@ namespace YAML
// eat chomping/indentation indicators // eat chomping/indentation indicators
params.chomp = CLIP; params.chomp = CLIP;
int n = Exp::Chomp().Match(INPUT); int n = Exp::Chomp().Match(INPUT);
for(int i=0;i<n;i++) { for (int i = 0; i < n; i++) {
char ch = INPUT.get(); char ch = INPUT.get();
if(ch == '+') if (ch == '+')
params.chomp = KEEP; params.chomp = KEEP;
else if(ch == '-') else if (ch == '-')
params.chomp = STRIP; params.chomp = STRIP;
else if(Exp::Digit().Matches(ch)) { else if (Exp::Digit().Matches(ch)) {
if(ch == '0') if (ch == '0')
throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
params.indent = ch - '0'; params.indent = ch - '0';
@@ -406,20 +403,20 @@ namespace YAML
} }
// now eat whitespace // now eat whitespace
while(Exp::Blank().Matches(INPUT)) while (Exp::Blank().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// and comments to the end of the line // and comments to the end of the line
if(Exp::Comment().Matches(INPUT)) if (Exp::Comment().Matches(INPUT))
while(INPUT && !Exp::Break().Matches(INPUT)) while (INPUT && !Exp::Break().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// if it's not a line break, then we ran into a bad character inline // if it's not a line break, then we ran into a bad character inline
if(INPUT && !Exp::Break().Matches(INPUT)) if (INPUT && !Exp::Break().Matches(INPUT))
throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK); throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
// set the initial indentation // set the initial indentation
if(GetTopIndent() >= 0) if (GetTopIndent() >= 0)
params.indent += GetTopIndent(); params.indent += GetTopIndent();
params.eatLeadingWhitespace = false; params.eatLeadingWhitespace = false;
@@ -428,12 +425,13 @@ namespace YAML
scalar = ScanScalar(INPUT, params); scalar = ScanScalar(INPUT, params);
// simple keys always ok after block scalars (since we're gonna start a new line anyways) // simple keys always ok after block scalars (since we're gonna start a new
// line anyways)
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
Token token(Token::NON_PLAIN_SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
} }

View File

@@ -1,105 +1,95 @@
#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SETTING_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
namespace YAML namespace YAML {
{ class SettingChangeBase;
class SettingChangeBase;
template <typename T> template <typename T>
class Setting class Setting {
{
public: public:
Setting(): m_value() {} Setting() : m_value() {}
const T get() const { return m_value; } const T get() const { return m_value; }
std::auto_ptr <SettingChangeBase> set(const T& value); std::unique_ptr<SettingChangeBase> set(const T& value);
void restore(const Setting<T>& oldSetting) { void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); }
m_value = oldSetting.get();
}
private: private:
T m_value; T m_value;
}; };
class SettingChangeBase class SettingChangeBase {
{
public: public:
virtual ~SettingChangeBase() {} virtual ~SettingChangeBase() {}
virtual void pop() = 0; virtual void pop() = 0;
}; };
template <typename T> template <typename T>
class SettingChange: public SettingChangeBase class SettingChange : public SettingChangeBase {
{
public: public:
SettingChange(Setting<T> *pSetting): m_pCurSetting(pSetting) { SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
// copy old setting to save its state // copy old setting to save its state
m_oldSetting = *pSetting; m_oldSetting = *pSetting;
} }
virtual void pop() { virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
m_pCurSetting->restore(m_oldSetting);
}
private: private:
Setting<T> *m_pCurSetting; Setting<T>* m_pCurSetting;
Setting<T> m_oldSetting; Setting<T> m_oldSetting;
}; };
template <typename T> template <typename T>
inline std::auto_ptr <SettingChangeBase> Setting<T>::set(const T& value) { inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
std::auto_ptr <SettingChangeBase> pChange(new SettingChange<T> (this)); std::unique_ptr<SettingChangeBase> pChange(new SettingChange<T>(this));
m_value = value; m_value = value;
return pChange; return pChange;
} }
class SettingChanges: private noncopyable class SettingChanges : private noncopyable {
{
public: public:
SettingChanges() {} SettingChanges() {}
~SettingChanges() { clear(); } ~SettingChanges() { clear(); }
void clear() { void clear() {
restore(); restore();
for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it)
delete *it;
m_settingChanges.clear(); m_settingChanges.clear();
} }
void restore() { void restore() {
for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it) for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it)
(*it)->pop(); (*it)->pop();
} }
void push(std::auto_ptr <SettingChangeBase> pSettingChange) { void push(std::unique_ptr<SettingChangeBase> pSettingChange) {
m_settingChanges.push_back(pSettingChange.release()); m_settingChanges.push_back(std::move(pSettingChange));
} }
// like std::auto_ptr - assignment is transfer of ownership // like std::unique_ptr - assignment is transfer of ownership
SettingChanges& operator = (SettingChanges& rhs) { SettingChanges& operator=(SettingChanges&& rhs) {
if(this == &rhs) if (this == &rhs)
return *this; return *this;
clear(); clear();
m_settingChanges = rhs.m_settingChanges; std::swap(m_settingChanges, rhs.m_settingChanges);
rhs.m_settingChanges.clear();
return *this; return *this;
} }
private: private:
typedef std::vector <SettingChangeBase *> setting_changes; typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes;
setting_changes m_settingChanges; setting_changes m_settingChanges;
}; };
} }
#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,73 +1,66 @@
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "yaml-cpp/exceptions.h"
#include "exp.h"
namespace YAML namespace YAML {
{ struct Mark;
Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
: mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0)
{
}
void Scanner::SimpleKey::Validate() Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_)
{ : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {}
void Scanner::SimpleKey::Validate() {
// Note: pIndent will *not* be garbage here; // Note: pIndent will *not* be garbage here;
// we "garbage collect" them so we can // we "garbage collect" them so we can
// always refer to them // always refer to them
if(pIndent) if (pIndent)
pIndent->status = IndentMarker::VALID; pIndent->status = IndentMarker::VALID;
if(pMapStart) if (pMapStart)
pMapStart->status = Token::VALID; pMapStart->status = Token::VALID;
if(pKey) if (pKey)
pKey->status = Token::VALID; pKey->status = Token::VALID;
} }
void Scanner::SimpleKey::Invalidate() void Scanner::SimpleKey::Invalidate() {
{ if (pIndent)
if(pIndent)
pIndent->status = IndentMarker::INVALID; pIndent->status = IndentMarker::INVALID;
if(pMapStart) if (pMapStart)
pMapStart->status = Token::INVALID; pMapStart->status = Token::INVALID;
if(pKey) if (pKey)
pKey->status = Token::INVALID; pKey->status = Token::INVALID;
} }
// CanInsertPotentialSimpleKey // CanInsertPotentialSimpleKey
bool Scanner::CanInsertPotentialSimpleKey() const bool Scanner::CanInsertPotentialSimpleKey() const {
{ if (!m_simpleKeyAllowed)
if(!m_simpleKeyAllowed)
return false; return false;
return !ExistsActiveSimpleKey(); return !ExistsActiveSimpleKey();
} }
// ExistsActiveSimpleKey // ExistsActiveSimpleKey
// . Returns true if there's a potential simple key at our flow level // . Returns true if there's a potential simple key at our flow level
// (there's allowed at most one per flow level, i.e., at the start of the flow start token) // (there's allowed at most one per flow level, i.e., at the start of the flow
bool Scanner::ExistsActiveSimpleKey() const // start token)
{ bool Scanner::ExistsActiveSimpleKey() const {
if(m_simpleKeys.empty()) if (m_simpleKeys.empty())
return false; return false;
const SimpleKey& key = m_simpleKeys.top(); const SimpleKey& key = m_simpleKeys.top();
return key.flowLevel == GetFlowLevel(); return key.flowLevel == GetFlowLevel();
} }
// InsertPotentialSimpleKey // InsertPotentialSimpleKey
// . If we can, add a potential simple key to the queue, // . If we can, add a potential simple key to the queue,
// and save it on a stack. // and save it on a stack.
void Scanner::InsertPotentialSimpleKey() void Scanner::InsertPotentialSimpleKey() {
{ if (!CanInsertPotentialSimpleKey())
if(!CanInsertPotentialSimpleKey())
return; return;
SimpleKey key(INPUT.mark(), GetFlowLevel()); SimpleKey key(INPUT.mark(), GetFlowLevel());
// first add a map start, if necessary // first add a map start, if necessary
if(InBlockContext()) { if (InBlockContext()) {
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
if(key.pIndent) { if (key.pIndent) {
key.pIndent->status = IndentMarker::UNKNOWN; key.pIndent->status = IndentMarker::UNKNOWN;
key.pMapStart = key.pIndent->pStartToken; key.pMapStart = key.pIndent->pStartToken;
key.pMapStart->status = Token::UNVERIFIED; key.pMapStart->status = Token::UNVERIFIED;
@@ -80,37 +73,35 @@ namespace YAML
key.pKey->status = Token::UNVERIFIED; key.pKey->status = Token::UNVERIFIED;
m_simpleKeys.push(key); m_simpleKeys.push(key);
} }
// InvalidateSimpleKey // InvalidateSimpleKey
// . Automatically invalidate the simple key in our flow level // . Automatically invalidate the simple key in our flow level
void Scanner::InvalidateSimpleKey() void Scanner::InvalidateSimpleKey() {
{ if (m_simpleKeys.empty())
if(m_simpleKeys.empty())
return; return;
// grab top key // grab top key
SimpleKey& key = m_simpleKeys.top(); SimpleKey& key = m_simpleKeys.top();
if(key.flowLevel != GetFlowLevel()) if (key.flowLevel != GetFlowLevel())
return; return;
key.Invalidate(); key.Invalidate();
m_simpleKeys.pop(); m_simpleKeys.pop();
} }
// VerifySimpleKey // VerifySimpleKey
// . Determines whether the latest simple key to be added is valid, // . Determines whether the latest simple key to be added is valid,
// and if so, makes it valid. // and if so, makes it valid.
bool Scanner::VerifySimpleKey() bool Scanner::VerifySimpleKey() {
{ if (m_simpleKeys.empty())
if(m_simpleKeys.empty())
return false; return false;
// grab top key // grab top key
SimpleKey key = m_simpleKeys.top(); SimpleKey key = m_simpleKeys.top();
// only validate if we're in the correct flow level // only validate if we're in the correct flow level
if(key.flowLevel != GetFlowLevel()) if (key.flowLevel != GetFlowLevel())
return false; return false;
m_simpleKeys.pop(); m_simpleKeys.pop();
@@ -118,22 +109,20 @@ namespace YAML
bool isValid = true; bool isValid = true;
// needs to be less than 1024 characters and inline // needs to be less than 1024 characters and inline
if(INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
isValid = false; isValid = false;
// invalidate key // invalidate key
if(isValid) if (isValid)
key.Validate(); key.Validate();
else else
key.Invalidate(); key.Invalidate();
return isValid; return isValid;
}
void Scanner::PopAllSimpleKeys()
{
while(!m_simpleKeys.empty())
m_simpleKeys.pop();
}
} }
void Scanner::PopAllSimpleKeys() {
while (!m_simpleKeys.empty())
m_simpleKeys.pop();
}
}

View File

@@ -1,37 +1,38 @@
#include "singledocparser.h" #include <algorithm>
#include "collectionstack.h" #include <cstdio>
#include "directives.h" #include <sstream>
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/exceptions.h" #include "collectionstack.h" // IWYU pragma: keep
#include "scanner.h" #include "scanner.h"
#include "singledocparser.h"
#include "tag.h" #include "tag.h"
#include "token.h" #include "token.h"
#include <sstream> #include "yaml-cpp/emitterstyle.h"
#include <cstdio> #include "yaml-cpp/eventhandler.h"
#include <algorithm> #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
#include "yaml-cpp/mark.h"
#include "yaml-cpp/null.h"
namespace YAML namespace YAML {
{ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0) : m_scanner(scanner),
{ m_directives(directives),
} m_pCollectionStack(new CollectionStack),
m_curAnchor(0) {}
SingleDocParser::~SingleDocParser() SingleDocParser::~SingleDocParser() {}
{
}
// HandleDocument // HandleDocument
// . Handles the next document // . Handles the next document
// . Throws a ParserException on error. // . Throws a ParserException on error.
void SingleDocParser::HandleDocument(EventHandler& eventHandler) void SingleDocParser::HandleDocument(EventHandler& eventHandler) {
{
assert(!m_scanner.empty()); // guaranteed that there are tokens assert(!m_scanner.empty()); // guaranteed that there are tokens
assert(!m_curAnchor); assert(!m_curAnchor);
eventHandler.OnDocumentStart(m_scanner.peek().mark); eventHandler.OnDocumentStart(m_scanner.peek().mark);
// eat doc start // eat doc start
if(m_scanner.peek().type == Token::DOC_START) if (m_scanner.peek().type == Token::DOC_START)
m_scanner.pop(); m_scanner.pop();
// recurse! // recurse!
@@ -40,14 +41,13 @@ namespace YAML
eventHandler.OnDocumentEnd(); eventHandler.OnDocumentEnd();
// and finally eat any doc ends we see // and finally eat any doc ends we see
while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END) while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
m_scanner.pop(); m_scanner.pop();
} }
void SingleDocParser::HandleNode(EventHandler& eventHandler) void SingleDocParser::HandleNode(EventHandler& eventHandler) {
{
// an empty node *is* a possibility // an empty node *is* a possibility
if(m_scanner.empty()) { if (m_scanner.empty()) {
eventHandler.OnNull(m_scanner.mark(), NullAnchor); eventHandler.OnNull(m_scanner.mark(), NullAnchor);
return; return;
} }
@@ -56,15 +56,15 @@ namespace YAML
Mark mark = m_scanner.peek().mark; Mark mark = m_scanner.peek().mark;
// special case: a value node by itself must be a map, with no header // special case: a value node by itself must be a map, with no header
if(m_scanner.peek().type == Token::VALUE) { if (m_scanner.peek().type == Token::VALUE) {
eventHandler.OnMapStart(mark, "?", NullAnchor); eventHandler.OnMapStart(mark, "?", NullAnchor, EmitterStyle::Default);
HandleMap(eventHandler); HandleMap(eventHandler);
eventHandler.OnMapEnd(); eventHandler.OnMapEnd();
return; return;
} }
// special case: an alias node // special case: an alias node
if(m_scanner.peek().type == Token::ALIAS) { if (m_scanner.peek().type == Token::ALIAS) {
eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value)); eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
m_scanner.pop(); m_scanner.pop();
return; return;
@@ -76,39 +76,48 @@ namespace YAML
const Token& token = m_scanner.peek(); const Token& token = m_scanner.peek();
if(token.type == Token::PLAIN_SCALAR && token.value == "null") { if (token.type == Token::PLAIN_SCALAR && IsNullString(token.value)) {
eventHandler.OnNull(mark, anchor); eventHandler.OnNull(mark, anchor);
m_scanner.pop(); m_scanner.pop();
return; return;
} }
// add non-specific tags // add non-specific tags
if(tag.empty()) if (tag.empty())
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?"); tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
// now split based on what kind of node we should be // now split based on what kind of node we should be
switch(token.type) { switch (token.type) {
case Token::PLAIN_SCALAR: case Token::PLAIN_SCALAR:
case Token::NON_PLAIN_SCALAR: case Token::NON_PLAIN_SCALAR:
eventHandler.OnScalar(mark, tag, anchor, token.value); eventHandler.OnScalar(mark, tag, anchor, token.value);
m_scanner.pop(); m_scanner.pop();
return; return;
case Token::FLOW_SEQ_START: case Token::FLOW_SEQ_START:
eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Flow);
HandleSequence(eventHandler);
eventHandler.OnSequenceEnd();
return;
case Token::BLOCK_SEQ_START: case Token::BLOCK_SEQ_START:
eventHandler.OnSequenceStart(mark, tag, anchor); eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Block);
HandleSequence(eventHandler); HandleSequence(eventHandler);
eventHandler.OnSequenceEnd(); eventHandler.OnSequenceEnd();
return; return;
case Token::FLOW_MAP_START: case Token::FLOW_MAP_START:
eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
HandleMap(eventHandler);
eventHandler.OnMapEnd();
return;
case Token::BLOCK_MAP_START: case Token::BLOCK_MAP_START:
eventHandler.OnMapStart(mark, tag, anchor); eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Block);
HandleMap(eventHandler); HandleMap(eventHandler);
eventHandler.OnMapEnd(); eventHandler.OnMapEnd();
return; return;
case Token::KEY: case Token::KEY:
// compact maps can only go in a flow sequence // compact maps can only go in a flow sequence
if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) { if (m_pCollectionStack->GetCurCollectionType() ==
eventHandler.OnMapStart(mark, tag, anchor); CollectionType::FlowSeq) {
eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
HandleMap(eventHandler); HandleMap(eventHandler);
eventHandler.OnMapEnd(); eventHandler.OnMapEnd();
return; return;
@@ -118,44 +127,48 @@ namespace YAML
break; break;
} }
if(tag == "?") if (tag == "?")
eventHandler.OnNull(mark, anchor); eventHandler.OnNull(mark, anchor);
else else
eventHandler.OnScalar(mark, tag, anchor, ""); eventHandler.OnScalar(mark, tag, anchor, "");
} }
void SingleDocParser::HandleSequence(EventHandler& eventHandler) void SingleDocParser::HandleSequence(EventHandler& eventHandler) {
{
// split based on start token // split based on start token
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break; case Token::BLOCK_SEQ_START:
case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break; HandleBlockSequence(eventHandler);
default: break; break;
} case Token::FLOW_SEQ_START:
HandleFlowSequence(eventHandler);
break;
default:
break;
} }
}
void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq); m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
Token token = m_scanner.peek(); Token token = m_scanner.peek();
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END) if (token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ); throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
m_scanner.pop(); m_scanner.pop();
if(token.type == Token::BLOCK_SEQ_END) if (token.type == Token::BLOCK_SEQ_END)
break; break;
// check for null // check for null
if(!m_scanner.empty()) { if (!m_scanner.empty()) {
const Token& token = m_scanner.peek(); const Token& token = m_scanner.peek();
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) { if (token.type == Token::BLOCK_ENTRY ||
token.type == Token::BLOCK_SEQ_END) {
eventHandler.OnNull(token.mark, NullAnchor); eventHandler.OnNull(token.mark, NullAnchor);
continue; continue;
} }
@@ -165,20 +178,19 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq); m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
} }
void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq); m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// first check for end // first check for end
if(m_scanner.peek().type == Token::FLOW_SEQ_END) { if (m_scanner.peek().type == Token::FLOW_SEQ_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
@@ -186,53 +198,62 @@ namespace YAML
// then read the node // then read the node
HandleNode(eventHandler); HandleNode(eventHandler);
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node) // now eat the separator (or could be a sequence end, which we ignore - but
// if it's neither, then it's a bad node)
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if(token.type == Token::FLOW_ENTRY) if (token.type == Token::FLOW_ENTRY)
m_scanner.pop(); m_scanner.pop();
else if(token.type != Token::FLOW_SEQ_END) else if (token.type != Token::FLOW_SEQ_END)
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
} }
m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq); m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
} }
void SingleDocParser::HandleMap(EventHandler& eventHandler) void SingleDocParser::HandleMap(EventHandler& eventHandler) {
{
// split based on start token // split based on start token
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break; case Token::BLOCK_MAP_START:
case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break; HandleBlockMap(eventHandler);
case Token::KEY: HandleCompactMap(eventHandler); break; break;
case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break; case Token::FLOW_MAP_START:
default: break; HandleFlowMap(eventHandler);
} break;
case Token::KEY:
HandleCompactMap(eventHandler);
break;
case Token::VALUE:
HandleCompactMapWithNoKey(eventHandler);
break;
default:
break;
} }
}
void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockMap); m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
Token token = m_scanner.peek(); Token token = m_scanner.peek();
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END) if (token.type != Token::KEY && token.type != Token::VALUE &&
token.type != Token::BLOCK_MAP_END)
throw ParserException(token.mark, ErrorMsg::END_OF_MAP); throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
if(token.type == Token::BLOCK_MAP_END) { if (token.type == Token::BLOCK_MAP_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
// grab key (if non-null) // grab key (if non-null)
if(token.type == Token::KEY) { if (token.type == Token::KEY) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -240,7 +261,7 @@ namespace YAML
} }
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -249,28 +270,27 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::BlockMap); m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
} }
void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowMap); m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
const Mark mark = token.mark; const Mark mark = token.mark;
// first check for end // first check for end
if(token.type == Token::FLOW_MAP_END) { if (token.type == Token::FLOW_MAP_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
// grab key (if non-null) // grab key (if non-null)
if(token.type == Token::KEY) { if (token.type == Token::KEY) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -278,30 +298,30 @@ namespace YAML
} }
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
eventHandler.OnNull(mark, NullAnchor); eventHandler.OnNull(mark, NullAnchor);
} }
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node) // 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 = m_scanner.peek(); Token& nextToken = m_scanner.peek();
if(nextToken.type == Token::FLOW_ENTRY) if (nextToken.type == Token::FLOW_ENTRY)
m_scanner.pop(); m_scanner.pop();
else if(nextToken.type != Token::FLOW_MAP_END) else if (nextToken.type != Token::FLOW_MAP_END)
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
} }
m_pCollectionStack->PopCollectionType(CollectionType::FlowMap); m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
} }
// . Single "key: value" pair in a flow sequence // . Single "key: value" pair in a flow sequence
void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) {
{
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
// grab key // grab key
@@ -310,7 +330,7 @@ namespace YAML
HandleNode(eventHandler); HandleNode(eventHandler);
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -318,11 +338,10 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
} }
// . Single ": value" pair in a flow sequence // . Single ": value" pair in a flow sequence
void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) {
{
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
// null key // null key
@@ -333,62 +352,63 @@ namespace YAML
HandleNode(eventHandler); HandleNode(eventHandler);
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
} }
// ParseProperties // ParseProperties
// . Grabs any tag or anchor tokens and deals with them. // . Grabs any tag or anchor tokens and deals with them.
void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
{
tag.clear(); tag.clear();
anchor = NullAnchor; anchor = NullAnchor;
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
return; return;
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::TAG: ParseTag(tag); break; case Token::TAG:
case Token::ANCHOR: ParseAnchor(anchor); break; ParseTag(tag);
default: return; break;
} case Token::ANCHOR:
ParseAnchor(anchor);
break;
default:
return;
} }
} }
}
void SingleDocParser::ParseTag(std::string& tag) void SingleDocParser::ParseTag(std::string& tag) {
{
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if(!tag.empty()) if (!tag.empty())
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS); throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
Tag tagInfo(token); Tag tagInfo(token);
tag = tagInfo.Translate(m_directives); tag = tagInfo.Translate(m_directives);
m_scanner.pop(); m_scanner.pop();
} }
void SingleDocParser::ParseAnchor(anchor_t& anchor) void SingleDocParser::ParseAnchor(anchor_t& anchor) {
{
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if(anchor) if (anchor)
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
anchor = RegisterAnchor(token.value); anchor = RegisterAnchor(token.value);
m_scanner.pop(); m_scanner.pop();
} }
anchor_t SingleDocParser::RegisterAnchor(const std::string& name) anchor_t SingleDocParser::RegisterAnchor(const std::string& name) {
{ if (name.empty())
if(name.empty())
return NullAnchor; return NullAnchor;
return m_anchors[name] = ++m_curAnchor; return m_anchors[name] = ++m_curAnchor;
} }
anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
{ const std::string& name) const {
Anchors::const_iterator it = m_anchors.find(name); Anchors::const_iterator it = m_anchors.find(name);
if(it == m_anchors.end()) if (it == m_anchors.end())
throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR); throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
return it->second; return it->second;
} }
} }

View File

@@ -1,29 +1,29 @@
#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SINGLEDOCPARSER_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <map>
#include <memory>
#include <string>
#include "yaml-cpp/anchor.h" #include "yaml-cpp/anchor.h"
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include <string>
#include <map>
#include <memory>
namespace YAML namespace YAML {
{ class CollectionStack;
struct Directives; class EventHandler;
struct Mark; class Node;
struct Token; class Scanner;
class CollectionStack; struct Directives;
class EventHandler; struct Mark;
class Node; struct Token;
class Scanner;
class SingleDocParser: private noncopyable class SingleDocParser : private noncopyable {
{
public: public:
SingleDocParser(Scanner& scanner, const Directives& directives); SingleDocParser(Scanner& scanner, const Directives& directives);
~SingleDocParser(); ~SingleDocParser();
@@ -53,13 +53,13 @@ namespace YAML
private: private:
Scanner& m_scanner; Scanner& m_scanner;
const Directives& m_directives; const Directives& m_directives;
std::auto_ptr<CollectionStack> m_pCollectionStack; std::unique_ptr<CollectionStack> m_pCollectionStack;
typedef std::map<std::string, anchor_t> Anchors; typedef std::map<std::string, anchor_t> Anchors;
Anchors m_anchors; Anchors m_anchors;
anchor_t m_curAnchor; anchor_t m_curAnchor;
}; };
} }
#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,19 +1,18 @@
#include "stream.h"
#include <iostream> #include <iostream>
#include "exp.h"
#include "stream.h"
#ifndef YAML_PREFETCH_SIZE #ifndef YAML_PREFETCH_SIZE
#define YAML_PREFETCH_SIZE 2048 #define YAML_PREFETCH_SIZE 2048
#endif #endif
#define S_ARRAY_SIZE( A ) (sizeof(A)/sizeof(*(A))) #define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
#define S_ARRAY_END( A ) ((A) + S_ARRAY_SIZE(A)) #define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A))
#define CP_REPLACEMENT_CHARACTER (0xFFFD) #define CP_REPLACEMENT_CHARACTER (0xFFFD)
namespace YAML namespace YAML {
{ enum UtfIntroState {
enum UtfIntroState {
uis_start, uis_start,
uis_utfbe_b1, uis_utfbe_b1,
uis_utf32be_b2, uis_utf32be_b2,
@@ -33,9 +32,9 @@ namespace YAML
uis_utf8_bom2, uis_utf8_bom2,
uis_utf8, uis_utf8,
uis_error uis_error
}; };
enum UtfIntroCharType { enum UtfIntroCharType {
uict00, uict00,
uictBB, uictBB,
uictBF, uictBF,
@@ -45,53 +44,72 @@ namespace YAML
uictAscii, uictAscii,
uictOther, uictOther,
uictMax uictMax
}; };
static bool s_introFinalState[] = { static bool s_introFinalState[] = {
false, //uis_start false, // uis_start
false, //uis_utfbe_b1 false, // uis_utfbe_b1
false, //uis_utf32be_b2 false, // uis_utf32be_b2
false, //uis_utf32be_bom3 false, // uis_utf32be_bom3
true, //uis_utf32be true, // uis_utf32be
true, //uis_utf16be true, // uis_utf16be
false, //uis_utf16be_bom1 false, // uis_utf16be_bom1
false, //uis_utfle_bom1 false, // uis_utfle_bom1
false, //uis_utf16le_bom2 false, // uis_utf16le_bom2
false, //uis_utf32le_bom3 false, // uis_utf32le_bom3
true, //uis_utf16le true, // uis_utf16le
true, //uis_utf32le true, // uis_utf32le
false, //uis_utf8_imp false, // uis_utf8_imp
false, //uis_utf16le_imp false, // uis_utf16le_imp
false, //uis_utf32le_imp3 false, // uis_utf32le_imp3
false, //uis_utf8_bom1 false, // uis_utf8_bom1
false, //uis_utf8_bom2 false, // uis_utf8_bom2
true, //uis_utf8 true, // uis_utf8
true, //uis_error true, // uis_error
}; };
static UtfIntroState s_introTransitions[][uictMax] = { static UtfIntroState s_introTransitions[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther // uict00, uictBB, uictBF, uictEF,
{uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1, uis_utfle_bom1, uis_utf8_imp, uis_utf8}, // uictFE, uictFF, uictAscii, uictOther
{uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8}, {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1,
{uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8, uis_utf8, uis_utf8}, uis_utfle_bom1, uis_utf8_imp, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8, uis_utf8}, {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
{uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be}, uis_utf16be, uis_utf8},
{uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be}, {uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8,
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8, uis_utf8}, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8, uis_utf8, uis_utf8}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8,
{uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf8},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be,
{uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf32be, uis_utf32be, uis_utf32be},
{uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le}, {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be,
{uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, uis_utf16be, uis_utf16be, uis_utf16be},
{uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8,
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf8},
{uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8,
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
}; uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le,
uis_utf32le, uis_utf32le, uis_utf32le},
{uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8, uis_utf8},
{uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8},
};
static char s_introUngetCount[][uictMax] = { static char s_introUngetCount[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
{0, 1, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 0, 1},
{0, 2, 2, 2, 2, 2, 2, 2}, {0, 2, 2, 2, 2, 2, 2, 2},
@@ -111,21 +129,26 @@ namespace YAML
{2, 0, 2, 2, 2, 2, 2, 2}, {2, 0, 2, 2, 2, 2, 2, 2},
{3, 3, 0, 3, 3, 3, 3, 3}, {3, 3, 0, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},
}; };
inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
{
if (std::istream::traits_type::eof() == ch) { if (std::istream::traits_type::eof() == ch) {
return uictOther; return uictOther;
} }
switch (ch) { switch (ch) {
case 0: return uict00; case 0:
case 0xBB: return uictBB; return uict00;
case 0xBF: return uictBF; case 0xBB:
case 0xEF: return uictEF; return uictBB;
case 0xFE: return uictFE; case 0xBF:
case 0xFF: return uictFF; return uictBF;
case 0xEF:
return uictEF;
case 0xFE:
return uictFE;
case 0xFF:
return uictFF;
} }
if ((ch > 0) && (ch < 0xFF)) { if ((ch > 0) && (ch < 0xFF)) {
@@ -133,58 +156,48 @@ namespace YAML
} }
return uictOther; return uictOther;
} }
inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, unsigned char rshift) inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
{ unsigned char rshift) {
const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits); const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits);
const unsigned char mask = (0xFF >> (lead_bits + 1)); const unsigned char mask = (0xFF >> (lead_bits + 1));
return static_cast<char>(static_cast<unsigned char>( return static_cast<char>(
header | ((ch >> rshift) & mask) static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
)); }
}
inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
{
// We are not allowed to queue the Stream::eof() codepoint, so // We are not allowed to queue the Stream::eof() codepoint, so
// replace it with CP_REPLACEMENT_CHARACTER // replace it with CP_REPLACEMENT_CHARACTER
if (static_cast<unsigned long>(Stream::eof()) == ch) if (static_cast<unsigned long>(Stream::eof()) == ch) {
{
ch = CP_REPLACEMENT_CHARACTER; ch = CP_REPLACEMENT_CHARACTER;
} }
if (ch < 0x80) if (ch < 0x80) {
{
q.push_back(Utf8Adjust(ch, 0, 0)); q.push_back(Utf8Adjust(ch, 0, 0));
} } else if (ch < 0x800) {
else if (ch < 0x800)
{
q.push_back(Utf8Adjust(ch, 2, 6)); q.push_back(Utf8Adjust(ch, 2, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} } else if (ch < 0x10000) {
else if (ch < 0x10000)
{
q.push_back(Utf8Adjust(ch, 3, 12)); q.push_back(Utf8Adjust(ch, 3, 12));
q.push_back(Utf8Adjust(ch, 1, 6)); q.push_back(Utf8Adjust(ch, 1, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} } else {
else
{
q.push_back(Utf8Adjust(ch, 4, 18)); q.push_back(Utf8Adjust(ch, 4, 18));
q.push_back(Utf8Adjust(ch, 1, 12)); q.push_back(Utf8Adjust(ch, 1, 12));
q.push_back(Utf8Adjust(ch, 1, 6)); q.push_back(Utf8Adjust(ch, 1, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} }
} }
Stream::Stream(std::istream& input) Stream::Stream(std::istream& input)
: m_input(input), : m_input(input),
m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
m_nPrefetchedAvailable(0), m_nPrefetchedUsed(0) m_nPrefetchedAvailable(0),
{ m_nPrefetchedUsed(0) {
typedef std::istream::traits_type char_traits; typedef std::istream::traits_type char_traits;
if(!input) if (!input)
return; return;
// Determine (or guess) the character-set by reading the BOM, if any. See // Determine (or guess) the character-set by reading the BOM, if any. See
@@ -192,16 +205,16 @@ namespace YAML
char_traits::int_type intro[4]; char_traits::int_type intro[4];
int nIntroUsed = 0; int nIntroUsed = 0;
UtfIntroState state = uis_start; UtfIntroState state = uis_start;
for(; !s_introFinalState[state]; ) { for (; !s_introFinalState[state];) {
std::istream::int_type ch = input.get(); std::istream::int_type ch = input.get();
intro[nIntroUsed++] = ch; intro[nIntroUsed++] = ch;
UtfIntroCharType charType = IntroCharTypeOf(ch); UtfIntroCharType charType = IntroCharTypeOf(ch);
UtfIntroState newState = s_introTransitions[state][charType]; UtfIntroState newState = s_introTransitions[state][charType];
int nUngets = s_introUngetCount[state][charType]; int nUngets = s_introUngetCount[state][charType];
if(nUngets > 0) { if (nUngets > 0) {
input.clear(); input.clear();
for(; nUngets > 0; --nUngets) { for (; nUngets > 0; --nUngets) {
if(char_traits::eof() != intro[--nIntroUsed]) if (char_traits::eof() != intro[--nIntroUsed])
input.putback(char_traits::to_char_type(intro[nIntroUsed])); input.putback(char_traits::to_char_type(intro[nIntroUsed]));
} }
} }
@@ -209,166 +222,163 @@ namespace YAML
} }
switch (state) { switch (state) {
case uis_utf8: m_charSet = utf8; break; case uis_utf8:
case uis_utf16le: m_charSet = utf16le; break; m_charSet = utf8;
case uis_utf16be: m_charSet = utf16be; break; break;
case uis_utf32le: m_charSet = utf32le; break; case uis_utf16le:
case uis_utf32be: m_charSet = utf32be; break; m_charSet = utf16le;
default: m_charSet = utf8; break; break;
case uis_utf16be:
m_charSet = utf16be;
break;
case uis_utf32le:
m_charSet = utf32le;
break;
case uis_utf32be:
m_charSet = utf32be;
break;
default:
m_charSet = utf8;
break;
} }
ReadAheadTo(0); ReadAheadTo(0);
} }
Stream::~Stream() Stream::~Stream() { delete[] m_pPrefetched; }
{
delete[] m_pPrefetched;
}
char Stream::peek() const char Stream::peek() const {
{ if (m_readahead.empty()) {
if (m_readahead.empty())
{
return Stream::eof(); return Stream::eof();
} }
return m_readahead[0]; return m_readahead[0];
} }
Stream::operator bool() const Stream::operator bool() const {
{ return m_input.good() ||
return m_input.good() || (!m_readahead.empty() && m_readahead[0] != Stream::eof()); (!m_readahead.empty() && m_readahead[0] != Stream::eof());
} }
// get // get
// . Extracts a character from the stream and updates our position // . Extracts a character from the stream and updates our position
char Stream::get() char Stream::get() {
{
char ch = peek(); char ch = peek();
AdvanceCurrent(); AdvanceCurrent();
m_mark.column++; m_mark.column++;
if(ch == '\n') { if (ch == '\n') {
m_mark.column = 0; m_mark.column = 0;
m_mark.line++; m_mark.line++;
} }
return ch; return ch;
} }
// get // get
// . Extracts 'n' characters from the stream and updates our position // . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) std::string Stream::get(int n) {
{
std::string ret; std::string ret;
ret.reserve(n); ret.reserve(n);
for(int i=0;i<n;i++) for (int i = 0; i < n; i++)
ret += get(); ret += get();
return ret; return ret;
} }
// eat // eat
// . Eats 'n' characters and updates our position. // . Eats 'n' characters and updates our position.
void Stream::eat(int n) void Stream::eat(int n) {
{ for (int i = 0; i < n; i++)
for(int i=0;i<n;i++)
get(); get();
} }
void Stream::AdvanceCurrent() void Stream::AdvanceCurrent() {
{ if (!m_readahead.empty()) {
if (!m_readahead.empty())
{
m_readahead.pop_front(); m_readahead.pop_front();
m_mark.pos++; m_mark.pos++;
} }
ReadAheadTo(0); ReadAheadTo(0);
} }
bool Stream::_ReadAheadTo(size_t i) const bool Stream::_ReadAheadTo(size_t i) const {
{ while (m_input.good() && (m_readahead.size() <= i)) {
while (m_input.good() && (m_readahead.size() <= i)) switch (m_charSet) {
{ case utf8:
switch (m_charSet) StreamInUtf8();
{ break;
case utf8: StreamInUtf8(); break; case utf16le:
case utf16le: StreamInUtf16(); break; StreamInUtf16();
case utf16be: StreamInUtf16(); break; break;
case utf32le: StreamInUtf32(); break; case utf16be:
case utf32be: StreamInUtf32(); break; StreamInUtf16();
break;
case utf32le:
StreamInUtf32();
break;
case utf32be:
StreamInUtf32();
break;
} }
} }
// signal end of stream // signal end of stream
if(!m_input.good()) if (!m_input.good())
m_readahead.push_back(Stream::eof()); m_readahead.push_back(Stream::eof());
return m_readahead.size() > i; return m_readahead.size() > i;
} }
void Stream::StreamInUtf8() const void Stream::StreamInUtf8() const {
{
unsigned char b = GetNextByte(); unsigned char b = GetNextByte();
if (m_input.good()) if (m_input.good()) {
{
m_readahead.push_back(b); m_readahead.push_back(b);
} }
} }
void Stream::StreamInUtf16() const void Stream::StreamInUtf16() const {
{
unsigned long ch = 0; unsigned long ch = 0;
unsigned char bytes[2]; unsigned char bytes[2];
int nBigEnd = (m_charSet == utf16be) ? 0 : 1; int nBigEnd = (m_charSet == utf16be) ? 0 : 1;
bytes[0] = GetNextByte(); bytes[0] = GetNextByte();
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
return; return;
} }
ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
static_cast<unsigned long>(bytes[1 ^ nBigEnd]); static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
if (ch >= 0xDC00 && ch < 0xE000) if (ch >= 0xDC00 && ch < 0xE000) {
{
// Trailing (low) surrogate...ugh, wrong order // Trailing (low) surrogate...ugh, wrong order
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
return; return;
} } else if (ch >= 0xD800 && ch < 0xDC00) {
else if (ch >= 0xD800 && ch < 0xDC00)
{
// ch is a leading (high) surrogate // ch is a leading (high) surrogate
// Four byte UTF-8 code point // Four byte UTF-8 code point
// Read the trailing (low) surrogate // Read the trailing (low) surrogate
for (;;) for (;;) {
{
bytes[0] = GetNextByte(); bytes[0] = GetNextByte();
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
return; return;
} }
unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
static_cast<unsigned long>(bytes[1 ^ nBigEnd]); static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
if (chLow < 0xDC00 || ch >= 0xE000) if (chLow < 0xDC00 || chLow >= 0xE000) {
{ // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the
// Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the stream. // stream.
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
// Deal with the next UTF-16 unit // Deal with the next UTF-16 unit
if (chLow < 0xD800 || ch >= 0xE000) if (chLow < 0xD800 || chLow >= 0xE000) {
{
// Easiest case: queue the codepoint and return // Easiest case: queue the codepoint and return
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
return; return;
} } else {
else
{
// Start the loop over with the new high surrogate // Start the loop over with the new high surrogate
ch = chLow; ch = chLow;
continue; continue;
@@ -384,44 +394,37 @@ namespace YAML
// Add the surrogacy offset // Add the surrogacy offset
ch += 0x10000; ch += 0x10000;
break;
} }
} }
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
} }
inline char* ReadBuffer(unsigned char* pBuffer) inline char* ReadBuffer(unsigned char* pBuffer) {
{
return reinterpret_cast<char*>(pBuffer); return reinterpret_cast<char*>(pBuffer);
} }
unsigned char Stream::GetNextByte() const unsigned char Stream::GetNextByte() const {
{ if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) {
if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) std::streambuf* pBuf = m_input.rdbuf();
{ m_nPrefetchedAvailable = static_cast<std::size_t>(
std::streambuf *pBuf = m_input.rdbuf(); pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE));
m_nPrefetchedAvailable = static_cast<std::size_t>(pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE));
m_nPrefetchedUsed = 0; m_nPrefetchedUsed = 0;
if (!m_nPrefetchedAvailable) if (!m_nPrefetchedAvailable) {
{
m_input.setstate(std::ios_base::eofbit); m_input.setstate(std::ios_base::eofbit);
} }
if (0 == m_nPrefetchedAvailable) if (0 == m_nPrefetchedAvailable) {
{
return 0; return 0;
} }
} }
return m_pPrefetched[m_nPrefetchedUsed++]; return m_pPrefetched[m_nPrefetchedUsed++];
} }
void Stream::StreamInUtf32() const void Stream::StreamInUtf32() const {
{ static int indexes[2][4] = {{3, 2, 1, 0}, {0, 1, 2, 3}};
static int indexes[2][4] = {
{3, 2, 1, 0},
{0, 1, 2, 3}
};
unsigned long ch = 0; unsigned long ch = 0;
unsigned char bytes[4]; unsigned char bytes[4];
@@ -431,17 +434,15 @@ namespace YAML
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
bytes[2] = GetNextByte(); bytes[2] = GetNextByte();
bytes[3] = GetNextByte(); bytes[3] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
return; return;
} }
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i) {
{
ch <<= 8; ch <<= 8;
ch |= bytes[pIndexes[i]]; ch |= bytes[pIndexes[i]];
} }
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
} }
} }

View File

@@ -1,11 +1,12 @@
#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STREAM_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <cstddef> #include <cstddef>
@@ -15,10 +16,8 @@
#include <set> #include <set>
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Stream : private noncopyable {
class Stream: private noncopyable
{
public: public:
friend class StreamCharSource; friend class StreamCharSource;
@@ -26,7 +25,7 @@ namespace YAML
~Stream(); ~Stream();
operator bool() const; operator bool() const;
bool operator !() const { return !static_cast <bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
char peek() const; char peek() const;
char get(); char get();
@@ -42,7 +41,7 @@ namespace YAML
void ResetColumn() { m_mark.column = 0; } void ResetColumn() { m_mark.column = 0; }
private: private:
enum CharacterSet {utf8, utf16le, utf16be, utf32le, utf32be}; enum CharacterSet { utf8, utf16le, utf16be, utf32le, utf32be };
std::istream& m_input; std::istream& m_input;
Mark m_mark; Mark m_mark;
@@ -61,19 +60,17 @@ namespace YAML
void StreamInUtf16() const; void StreamInUtf16() const;
void StreamInUtf32() const; void StreamInUtf32() const;
unsigned char GetNextByte() const; unsigned char GetNextByte() const;
}; };
// CharAt // CharAt
// . Unchecked access // . Unchecked access
inline char Stream::CharAt(size_t i) const { inline char Stream::CharAt(size_t i) const { return m_readahead[i]; }
return m_readahead[i];
}
inline bool Stream::ReadAheadTo(size_t i) const { inline bool Stream::ReadAheadTo(size_t i) const {
if(m_readahead.size() > i) if (m_readahead.size() > i)
return true; return true;
return _ReadAheadTo(i); return _ReadAheadTo(i);
} }
} }
#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,48 +1,48 @@
#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STREAMCHARSOURCE_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ class StreamCharSource {
class StreamCharSource
{
public: public:
StreamCharSource(const Stream& stream): m_offset(0), m_stream(stream) {} StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
StreamCharSource(const StreamCharSource& source): m_offset(source.m_offset), m_stream(source.m_stream) {} StreamCharSource(const StreamCharSource& source)
: m_offset(source.m_offset), m_stream(source.m_stream) {}
~StreamCharSource() {} ~StreamCharSource() {}
operator bool() const; operator bool() const;
char operator [] (std::size_t i) const { return m_stream.CharAt(m_offset + i); } char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); }
bool operator !() const { return !static_cast<bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
const StreamCharSource operator + (int i) const; const StreamCharSource operator+(int i) const;
private: private:
std::size_t m_offset; std::size_t m_offset;
const Stream& m_stream; const Stream& m_stream;
StreamCharSource& operator = (const StreamCharSource&); // non-assignable StreamCharSource& operator=(const StreamCharSource&); // non-assignable
}; };
inline StreamCharSource::operator bool() const { inline StreamCharSource::operator bool() const {
return m_stream.ReadAheadTo(m_offset); return m_stream.ReadAheadTo(m_offset);
} }
inline const StreamCharSource StreamCharSource::operator + (int i) const { inline const StreamCharSource StreamCharSource::operator+(int i) const {
StreamCharSource source(*this); StreamCharSource source(*this);
if(static_cast<int> (source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += i;
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;
} }
} }
#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,47 +1,48 @@
#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STRINGSOURCE_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 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ class StringCharSource {
class StringCharSource
{
public: public:
StringCharSource(const char *str, std::size_t size): m_str(str), m_size(size), m_offset(0) {} StringCharSource(const char* str, std::size_t size)
: m_str(str), m_size(size), m_offset(0) {}
operator bool() const { return m_offset < m_size; } operator bool() const { return m_offset < m_size; }
char operator [] (std::size_t i) const { return m_str[m_offset + i]; } char operator[](std::size_t i) const { return m_str[m_offset + i]; }
bool operator !() const { return !static_cast<bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
const StringCharSource operator + (int i) const { const StringCharSource operator+(int i) const {
StringCharSource source(*this); StringCharSource source(*this);
if(static_cast<int> (source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += i;
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;
} }
StringCharSource& operator ++ () { StringCharSource& operator++() {
++m_offset; ++m_offset;
return *this; return *this;
} }
StringCharSource& operator += (std::size_t offset) { StringCharSource& operator+=(std::size_t offset) {
m_offset += offset; m_offset += offset;
return *this; return *this;
} }
private: private:
const char *m_str; const char* m_str;
std::size_t m_size; std::size_t m_size;
std::size_t m_offset; std::size_t m_offset;
}; };
} }
#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,14 +1,13 @@
#include "tag.h"
#include "directives.h"
#include "token.h"
#include <cassert> #include <cassert>
#include <stdexcept> #include <stdexcept>
namespace YAML #include "directives.h" // IWYU pragma: keep
{ #include "tag.h"
Tag::Tag(const Token& token): type(static_cast<TYPE>(token.data)) #include "token.h"
{
switch(type) { namespace YAML {
Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
switch (type) {
case VERBATIM: case VERBATIM:
value = token.value; value = token.value;
break; break;
@@ -27,11 +26,10 @@ namespace YAML
default: default:
assert(false); assert(false);
} }
} }
const std::string Tag::Translate(const Directives& directives) const std::string Tag::Translate(const Directives& directives) {
{ switch (type) {
switch(type) {
case VERBATIM: case VERBATIM:
return value; return value;
case PRIMARY_HANDLE: case PRIMARY_HANDLE:
@@ -47,6 +45,5 @@ namespace YAML
assert(false); assert(false);
} }
throw std::runtime_error("yaml-cpp: internal error, bad tag type"); throw std::runtime_error("yaml-cpp: internal error, bad tag type");
}
} }
}

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