mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
Compare commits
639 Commits
release-0.
...
yaml-cpp-0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a3624205e | ||
![]() |
968e0c1f02 | ||
![]() |
b218787b98 | ||
![]() |
db0bda7087 | ||
![]() |
6cdf363625 | ||
![]() |
d638508d33 | ||
![]() |
90350662c9 | ||
![]() |
e0e01d53c2 | ||
![]() |
0122697561 | ||
![]() |
bd7f8c60c8 | ||
![]() |
82e9571213 | ||
![]() |
0d5c57150c | ||
![]() |
eca9cfd648 | ||
![]() |
a2a113c6ff | ||
![]() |
283d06f9f7 | ||
![]() |
b87c76a2ef | ||
![]() |
abf941b20d | ||
![]() |
b659858b19 | ||
![]() |
2443da5224 | ||
![]() |
54fc4dadbb | ||
![]() |
774f25800e | ||
![]() |
ca77ef716e | ||
![]() |
ee99c4151c | ||
![]() |
d0da14404e | ||
![]() |
45d9035a33 | ||
![]() |
b71e672caf | ||
![]() |
5e79f5eed3 | ||
![]() |
c90c08ccc9 | ||
![]() |
3e33bb3166 | ||
![]() |
1698b47b65 | ||
![]() |
0f9a586ca1 | ||
![]() |
4fb1c4b92b | ||
![]() |
ab5f9259a4 | ||
![]() |
124ae47600 | ||
![]() |
f996468a6a | ||
![]() |
562aefc114 | ||
![]() |
5d5bb52ec2 | ||
![]() |
f5d5604a2c | ||
![]() |
aac4df342b | ||
![]() |
4c9e3d87e1 | ||
![]() |
cfb7606a84 | ||
![]() |
86ae3a5aa7 | ||
![]() |
752804372c | ||
![]() |
3f33f337a7 | ||
![]() |
5a519a4c6c | ||
![]() |
58687ee7c4 | ||
![]() |
dc9c750efd | ||
![]() |
d96826f12b | ||
![]() |
46dcdc3ea2 | ||
![]() |
beb44b872c | ||
![]() |
5e24f35816 | ||
![]() |
e2818c423e | ||
![]() |
efbfa1c7c7 | ||
![]() |
11607eb5bf | ||
![]() |
0fdb1b910c | ||
![]() |
c5457e1c6a | ||
![]() |
bedb28fdb4 | ||
![]() |
86c69bb73c | ||
![]() |
f82861001a | ||
![]() |
3757b2023b | ||
![]() |
147d909fe6 | ||
![]() |
e3492bb3fa | ||
![]() |
8ff7d76e19 | ||
![]() |
2b58c9bc42 | ||
![]() |
0f20ddcdcb | ||
![]() |
d025040049 | ||
![]() |
1f4b6d5c85 | ||
![]() |
3d9ad75af7 | ||
![]() |
380ecb404e | ||
![]() |
994cf97b59 | ||
![]() |
96598c5c25 | ||
![]() |
b5b03bb9ad | ||
![]() |
086fec5c35 | ||
![]() |
85af926ddc | ||
![]() |
519d33fea3 | ||
![]() |
f0b15cd6a0 | ||
![]() |
f74ae543b4 | ||
![]() |
7c33b3cdab | ||
![]() |
728e26e426 | ||
![]() |
3392ab980e | ||
![]() |
6c569e58b0 | ||
![]() |
148da47114 | ||
![]() |
a45a61742b | ||
![]() |
6e79997bb2 | ||
![]() |
f35f4a19fa | ||
![]() |
7d2873ce9f | ||
![]() |
091ddfa52d | ||
![]() |
883a1e8540 | ||
![]() |
0d810ad6d5 | ||
![]() |
51b59d11ba | ||
![]() |
bfb5703ce9 | ||
![]() |
cc229e87b3 | ||
![]() |
ca34a379c7 | ||
![]() |
2a02cee1c8 | ||
![]() |
2176fd994e | ||
![]() |
0535811c18 | ||
![]() |
c5f6482325 | ||
![]() |
d155b0d0d2 | ||
![]() |
52bcefa1f1 | ||
![]() |
34bd1a7083 | ||
![]() |
500db60f89 | ||
![]() |
178c8d1f27 | ||
![]() |
0a1352525a | ||
![]() |
f327b565ba | ||
![]() |
57805dfd6a | ||
![]() |
005a6a19ee | ||
![]() |
8c35a8ffab | ||
![]() |
9e37409b4b | ||
![]() |
a5b72f7ae6 | ||
![]() |
dfbb388409 | ||
![]() |
e92321aee5 | ||
![]() |
24fa1b3380 | ||
![]() |
4376ebacaa | ||
![]() |
b57efe94e7 | ||
![]() |
36fd93a8d5 | ||
![]() |
97d56c3f36 | ||
![]() |
320b02b14a | ||
![]() |
03d6e7d672 | ||
![]() |
b426fafff6 | ||
![]() |
b0a4de3dd9 | ||
![]() |
b43db54810 | ||
![]() |
5c390e8d6c | ||
![]() |
aa928b925b | ||
![]() |
908d38ebef | ||
![]() |
ec8aa4fa62 | ||
![]() |
5de38a76b6 | ||
![]() |
25f3935b7c | ||
![]() |
4d44602a5d | ||
![]() |
897cfd5b2e | ||
![]() |
1a6cb7376a | ||
![]() |
66acd0d54b | ||
![]() |
998d7bf31e | ||
![]() |
25c466a152 | ||
![]() |
7092a0b099 | ||
![]() |
25b2ed0787 | ||
![]() |
67e37d000a | ||
![]() |
b1322770c2 | ||
![]() |
39e7b651dc | ||
![]() |
0970a108bd | ||
![]() |
f9ff72dee7 | ||
![]() |
1025f76df1 | ||
![]() |
a5e86cde59 | ||
![]() |
77c90a08e8 | ||
![]() |
1006bee48a | ||
![]() |
899b6614c1 | ||
![]() |
bc86fd4aec | ||
![]() |
7d932f0a10 | ||
![]() |
087e0673f3 | ||
![]() |
c9729b26a4 | ||
![]() |
f1a889a0b9 | ||
![]() |
fcbec237c9 | ||
![]() |
c324bf8a7d | ||
![]() |
2b2e607118 | ||
![]() |
891c7338bf | ||
![]() |
391111c055 | ||
![]() |
570ab9d3fb | ||
![]() |
0c8a539361 | ||
![]() |
9eae039c91 | ||
![]() |
0c280724e9 | ||
![]() |
9880b608b9 | ||
![]() |
ad712c4f2d | ||
![]() |
a397ad2925 | ||
![]() |
c7752ca336 | ||
![]() |
2c340f0546 | ||
![]() |
1aa25e7679 | ||
![]() |
541fef1545 | ||
![]() |
a499d2edad | ||
![]() |
47af59f09c | ||
![]() |
66e5c07b4f | ||
![]() |
13130ec20d | ||
![]() |
dea3428ce0 | ||
![]() |
edf8ebe246 | ||
![]() |
e0b293e757 | ||
![]() |
a4a79835c9 | ||
![]() |
dc8d91ce45 | ||
![]() |
d59586630e | ||
![]() |
066359802b | ||
![]() |
fe8ca77a1b | ||
![]() |
833f2996bc | ||
![]() |
7a68eaafd9 | ||
![]() |
98a181c7a7 | ||
![]() |
fcfd6635b0 | ||
![]() |
bf6482c07e | ||
![]() |
a2a096f2f3 | ||
![]() |
3bd412ccc3 | ||
![]() |
114db22335 | ||
![]() |
253c80d09e | ||
![]() |
06bf012d81 | ||
![]() |
ad0a3311a7 | ||
![]() |
33424ecb65 | ||
![]() |
d508a7cb0d | ||
![]() |
2e8841c6fa | ||
![]() |
ad2953f660 | ||
![]() |
ebf14ec83a | ||
![]() |
066b71a755 | ||
![]() |
f946473437 | ||
![]() |
90d7562be3 | ||
![]() |
1327ce6d73 | ||
![]() |
05834520e5 | ||
![]() |
dfa32c7f44 | ||
![]() |
a4382b1370 | ||
![]() |
ace9c49e31 | ||
![]() |
e3f120b99d | ||
![]() |
be85bb3212 | ||
![]() |
f6a6f46ba4 | ||
![]() |
da118bbb0d | ||
![]() |
5a24459ea1 | ||
![]() |
80bdfa6dba | ||
![]() |
599d050eb2 | ||
![]() |
314baa6e13 | ||
![]() |
4b40441cee | ||
![]() |
8d7eb02c46 | ||
![]() |
5fd25df859 | ||
![]() |
c7567b7b07 | ||
![]() |
d98ab9f342 | ||
![]() |
0fbeac8f4f | ||
![]() |
396a97050d | ||
![]() |
9583d1ab07 | ||
![]() |
db82302ed0 | ||
![]() |
32125697f2 | ||
![]() |
d63ec48c8a | ||
![]() |
3355bbb399 | ||
![]() |
9b4db068bb | ||
![]() |
5b88931143 | ||
![]() |
25881c4f96 | ||
![]() |
0305ad13e4 | ||
![]() |
dd0f2577ae | ||
![]() |
e40ed4f94e | ||
![]() |
4f858a47d6 | ||
![]() |
fa6a71e37f | ||
![]() |
e5aa599b27 | ||
![]() |
2375f2c66b | ||
![]() |
895af26226 | ||
![]() |
ae42def6cf | ||
![]() |
e0ae477b8f | ||
![]() |
434c6a5697 | ||
![]() |
097ac171c6 | ||
![]() |
0482463569 | ||
![]() |
5dbcf7eeb1 | ||
![]() |
f5418306d6 | ||
![]() |
04937649b7 | ||
![]() |
71f35b1104 | ||
![]() |
c335c8dd75 | ||
![]() |
6276189716 | ||
![]() |
8c517bf0fd | ||
![]() |
15b60e2a3b | ||
![]() |
4e1bdd08d3 | ||
![]() |
490265cf22 | ||
![]() |
bcdda4027f | ||
![]() |
eb02dd8dc3 | ||
![]() |
5721ac6194 | ||
![]() |
0c72825303 | ||
![]() |
6539648dac | ||
![]() |
b12e4b0781 | ||
![]() |
16f05e73b9 | ||
![]() |
06e09d1d64 | ||
![]() |
0c772c4c3f | ||
![]() |
a03e861d8c | ||
![]() |
09b4706faf | ||
![]() |
a645866ffa | ||
![]() |
979a91692f | ||
![]() |
1d1d6886cc | ||
![]() |
d770a7dc97 | ||
![]() |
823311384f | ||
![]() |
f29ea4b070 | ||
![]() |
68dd9b5d18 | ||
![]() |
2d815c5d6a | ||
![]() |
c722684f0d | ||
![]() |
5c097d417a | ||
![]() |
ab36ca930f | ||
![]() |
d5130a4109 | ||
![]() |
6c690e8294 | ||
![]() |
a78069a6e2 | ||
![]() |
bc3f72b565 | ||
![]() |
772969270d | ||
![]() |
2ffdc5b4d1 | ||
![]() |
e6d4a915dc | ||
![]() |
7c85e9d5de | ||
![]() |
1602f78974 | ||
![]() |
4116d89f2c | ||
![]() |
2dd1cf4596 | ||
![]() |
f011975769 | ||
![]() |
288c7e51f2 | ||
![]() |
52813050d2 | ||
![]() |
1ab9469f10 | ||
![]() |
3ddfeff4f5 | ||
![]() |
fdfffb0916 | ||
![]() |
52d01ff154 | ||
![]() |
c197d822c1 | ||
![]() |
277132a21f | ||
![]() |
5af3fc04c6 | ||
![]() |
0fb59c18dd | ||
![]() |
115101d25d | ||
![]() |
8d529cbcf2 | ||
![]() |
7d7075fdf9 | ||
![]() |
8aabc0766b | ||
![]() |
abd49d8bca | ||
![]() |
8b3778a639 | ||
![]() |
0abbf650b5 | ||
![]() |
c664d50d5c | ||
![]() |
ad275901b2 | ||
![]() |
a6fe313d32 | ||
![]() |
4123583159 | ||
![]() |
2c2b788391 | ||
![]() |
bc884061e2 | ||
![]() |
611d243b84 | ||
![]() |
b2f9a61c46 | ||
![]() |
f4278fe39f | ||
![]() |
676e0b94ac | ||
![]() |
0e3e6791ff | ||
![]() |
b8a87c43bc | ||
![]() |
2670ce8aaf | ||
![]() |
faa2e50605 | ||
![]() |
cdfbac1fd7 | ||
![]() |
944ebb7d1e | ||
![]() |
bf07af52ff | ||
![]() |
41e4cd3308 | ||
![]() |
952fe51c73 | ||
![]() |
c95bcae49f | ||
![]() |
cc559956a0 | ||
![]() |
879f96d2f6 | ||
![]() |
5e0886db87 | ||
![]() |
a626424baa | ||
![]() |
80823583a0 | ||
![]() |
eef692d7b2 | ||
![]() |
0814813302 | ||
![]() |
0f3f1e26a7 | ||
![]() |
f72e325c40 | ||
![]() |
07e88a78cb | ||
![]() |
c5e4bdee94 | ||
![]() |
d3801b7482 | ||
![]() |
b0dd0f862a | ||
![]() |
3cae26a75e | ||
![]() |
91eac5d93d | ||
![]() |
35d827f187 | ||
![]() |
23fb2dc811 | ||
![]() |
b5d8241dfa | ||
![]() |
d86cfc1c63 | ||
![]() |
65d80ebc11 | ||
![]() |
923ccc8fed | ||
![]() |
5a2183f55b | ||
![]() |
41c2ddc03e | ||
![]() |
39165338e0 | ||
![]() |
d8bdeb5b51 | ||
![]() |
16fd111a6b | ||
![]() |
f17cfacdbb | ||
![]() |
030f48583a | ||
![]() |
729ac991c7 | ||
![]() |
7d57209033 | ||
![]() |
4086c285fa | ||
![]() |
4245c36a84 | ||
![]() |
84b68c3868 | ||
![]() |
c2b22d6129 | ||
![]() |
58d4fedfc3 | ||
![]() |
55fc800989 | ||
![]() |
1f4d8ee3b4 | ||
![]() |
e09fbacd35 | ||
![]() |
06cb65c6b3 | ||
![]() |
6c8b369312 | ||
![]() |
be92547264 | ||
![]() |
c22512649e | ||
![]() |
c8a539f4f4 | ||
![]() |
683c60f490 | ||
![]() |
a183293ff0 | ||
![]() |
0d32d19ed8 | ||
![]() |
fca7b7e190 | ||
![]() |
4ca9269e24 | ||
![]() |
d6a0fc6f01 | ||
![]() |
5d6e09d699 | ||
![]() |
572e940c83 | ||
![]() |
01eb370300 | ||
![]() |
d760d037ca | ||
![]() |
6105d4cfeb | ||
![]() |
e145488547 | ||
![]() |
b688c93050 | ||
![]() |
1723523c43 | ||
![]() |
d772361f15 | ||
![]() |
a441e1a14c | ||
![]() |
fb0802097c | ||
![]() |
643ea61a98 | ||
![]() |
d1e4c2640c | ||
![]() |
ddc578dbd7 | ||
![]() |
8906ae9a0d | ||
![]() |
4e350e5808 | ||
![]() |
7ace0e93d2 | ||
![]() |
0e61ddb6d9 | ||
![]() |
97fa02a484 | ||
![]() |
5024caa69c | ||
![]() |
21ed2b5817 | ||
![]() |
92a35581d7 | ||
![]() |
5b32d89222 | ||
![]() |
812a2dc684 | ||
![]() |
add460947b | ||
![]() |
3099d51ba4 | ||
![]() |
6f4608ce05 | ||
![]() |
5abfbf5aac | ||
![]() |
d78d16532a | ||
![]() |
62634f53ec | ||
![]() |
860365b263 | ||
![]() |
e8e5d4bc40 | ||
![]() |
b077e8390e | ||
![]() |
c953ce0b07 | ||
![]() |
f87dced5c9 | ||
![]() |
62361e6f27 | ||
![]() |
70e1eb3f9c | ||
![]() |
77cc54585f | ||
![]() |
e69f51ee16 | ||
![]() |
ee795d7e3e | ||
![]() |
f6d6c90aa9 | ||
![]() |
d9c7bcf32f | ||
![]() |
f3b230693a | ||
![]() |
f64f619c29 | ||
![]() |
8e5fc0e304 | ||
![]() |
976e8b184c | ||
![]() |
e5d0366797 | ||
![]() |
c3798d9bd4 | ||
![]() |
40c47f6312 | ||
![]() |
e3d5ec189d | ||
![]() |
5be19ccbfd | ||
![]() |
98830a4a15 | ||
![]() |
3a88c4b4a1 | ||
![]() |
69af9b420a | ||
![]() |
0987b234c3 | ||
![]() |
2dfccbb945 | ||
![]() |
a9be4849d8 | ||
![]() |
b1100d7c54 | ||
![]() |
64e381f2c1 | ||
![]() |
f6b728d56c | ||
![]() |
edd6650536 | ||
![]() |
a04dfdeb07 | ||
![]() |
1721750d9e | ||
![]() |
a8f82af604 | ||
![]() |
0c321a6dc6 | ||
![]() |
08b3ddfd3e | ||
![]() |
fddc991b60 | ||
![]() |
3337df7ca2 | ||
![]() |
41533a8c49 | ||
![]() |
a6e1d4cf74 | ||
![]() |
5397a93702 | ||
![]() |
b9583dde76 | ||
![]() |
f22f38f7f2 | ||
![]() |
9e62bf8349 | ||
![]() |
f9d826c22a | ||
![]() |
4770ec798c | ||
![]() |
4568dd0b19 | ||
![]() |
a308b73e8a | ||
![]() |
c2a8a2c1f7 | ||
![]() |
a03af5dd73 | ||
![]() |
b50264e74d | ||
![]() |
ecdd9cc66d | ||
![]() |
3a90454d50 | ||
![]() |
2d81e46655 | ||
![]() |
b4963ab0fa | ||
![]() |
432268917b | ||
![]() |
2d06df474b | ||
![]() |
03fc837236 | ||
![]() |
80cf3c98db | ||
![]() |
f7b2247217 | ||
![]() |
36c63980b9 | ||
![]() |
0d1b5224c8 | ||
![]() |
ac81d7c883 | ||
![]() |
78b7a1b8a9 | ||
![]() |
12364895cb | ||
![]() |
5012063143 | ||
![]() |
c3b0ba9d61 | ||
![]() |
4fdbb748ec | ||
![]() |
b1730ea3da | ||
![]() |
3865d37bc7 | ||
![]() |
f5a9d4c8e3 | ||
![]() |
09beb5c47a | ||
![]() |
6e03bebeb0 | ||
![]() |
a7bdf08c7e | ||
![]() |
cf198080d0 | ||
![]() |
190a556756 | ||
![]() |
9aa3eb56f2 | ||
![]() |
ff1a8fc59a | ||
![]() |
7bbf712c36 | ||
![]() |
9b985c5ce2 | ||
![]() |
d3bbd08273 | ||
![]() |
4f8680b540 | ||
![]() |
ec95e61c04 | ||
![]() |
6ffc9ac788 | ||
![]() |
0e197b8723 | ||
![]() |
3d84f57008 | ||
![]() |
a7ebb3615a | ||
![]() |
a95baeafd6 | ||
![]() |
1ab16bac62 | ||
![]() |
4aa61944fe | ||
![]() |
e225509210 | ||
![]() |
d1eca90216 | ||
![]() |
020cd97915 | ||
![]() |
f0174ca08b | ||
![]() |
fed95c5da4 | ||
![]() |
a530630f1c | ||
![]() |
00e4a56d15 | ||
![]() |
1e6877043e | ||
![]() |
248b18a2d0 | ||
![]() |
7e79edc058 | ||
![]() |
8b97dfe77e | ||
![]() |
3eeb270ef5 | ||
![]() |
c1d75dd4f7 | ||
![]() |
dd1eb715c4 | ||
![]() |
fadca5a89d | ||
![]() |
7e129c9b64 | ||
![]() |
3e94c0a037 | ||
![]() |
d7feb2e9b9 | ||
![]() |
8ba5e3fbf6 | ||
![]() |
857c7d93a0 | ||
![]() |
b690648308 | ||
![]() |
d904b600a9 | ||
![]() |
bacb74e8ec | ||
![]() |
b1ac3289b8 | ||
![]() |
835b86d9f7 | ||
![]() |
94dc63af04 | ||
![]() |
50474b6b9f | ||
![]() |
4c3926a5c7 | ||
![]() |
9fbcfe9ec5 | ||
![]() |
d98687afc3 | ||
![]() |
f42580be41 | ||
![]() |
6e0e9554c6 | ||
![]() |
dc5bd4afce | ||
![]() |
c67b41c966 | ||
![]() |
221d17b0c6 | ||
![]() |
9a72702a61 | ||
![]() |
ebdfeb0349 | ||
![]() |
6152fb345e | ||
![]() |
f9e1a882e8 | ||
![]() |
681c862f54 | ||
![]() |
bb463d8d8b | ||
![]() |
943d000ab3 | ||
![]() |
cb632b3968 | ||
![]() |
b9d4ccd254 | ||
![]() |
d6aeb16450 | ||
![]() |
a518d87cfc | ||
![]() |
27617ec2be | ||
![]() |
1f9cc2d327 | ||
![]() |
9128d841f5 | ||
![]() |
ca5992b971 | ||
![]() |
ced50538fe | ||
![]() |
1371fc446c | ||
![]() |
7998db8397 | ||
![]() |
39c396ab01 | ||
![]() |
1e0c36c5cc | ||
![]() |
f34d60ca65 | ||
![]() |
4caedfda74 | ||
![]() |
2faeb76e2d | ||
![]() |
75a2fbe564 | ||
![]() |
4d95e4da74 | ||
![]() |
802cc6bcd6 | ||
![]() |
04bc13caf8 | ||
![]() |
c65a7dfc7c | ||
![]() |
d1cb1aa74f | ||
![]() |
be1b14f369 | ||
![]() |
337cb553d0 | ||
![]() |
99089bf218 | ||
![]() |
e293d4af8a | ||
![]() |
a6afaabcb0 | ||
![]() |
d508203ed8 | ||
![]() |
f1697dea15 | ||
![]() |
6b7cb45ac8 | ||
![]() |
1e4210401f | ||
![]() |
a04e2da1ff | ||
![]() |
51c84f1c02 | ||
![]() |
18a805e46c | ||
![]() |
a19336fd98 | ||
![]() |
9ad3a1b905 | ||
![]() |
21be19d493 | ||
![]() |
5b8ca9ce01 | ||
![]() |
a71c03a18b | ||
![]() |
0a02403fb0 | ||
![]() |
9820d13840 | ||
![]() |
326899815f | ||
![]() |
083a97b171 | ||
![]() |
2226987442 | ||
![]() |
bca7737463 | ||
![]() |
6f40b09525 | ||
![]() |
3a755de572 | ||
![]() |
9718e58120 | ||
![]() |
8723b8f358 | ||
![]() |
03df73a7b0 | ||
![]() |
3307f0941c | ||
![]() |
54b68230ae | ||
![]() |
32491166ac | ||
![]() |
6f94f954bb | ||
![]() |
90fd24d149 | ||
![]() |
9a21a3ec8d | ||
![]() |
3779e4255d | ||
![]() |
ec62dc547e | ||
![]() |
a9b9e1ccec | ||
![]() |
e04be7890a | ||
![]() |
ecb30132e9 | ||
![]() |
52be1ccfb9 | ||
![]() |
3405a6fe01 | ||
![]() |
d372729b92 | ||
![]() |
fadc2ad39f | ||
![]() |
a5607f82a3 | ||
![]() |
f4c683ac22 | ||
![]() |
8c9c9d90da | ||
![]() |
a372bfdc60 | ||
![]() |
fe57829aca | ||
![]() |
b5c53d9e3a | ||
![]() |
f2a2d25ec0 | ||
![]() |
a706ffaf62 | ||
![]() |
8f48e693fe | ||
![]() |
a0bf12e7a1 | ||
![]() |
2314c04d5d | ||
![]() |
22410f46f5 | ||
![]() |
9559a661aa | ||
![]() |
beb524489c | ||
![]() |
4ffb93c12b | ||
![]() |
ae06a40fe6 | ||
![]() |
315b00065b | ||
![]() |
6f02f7556e | ||
![]() |
fa0af88dfe | ||
![]() |
bce845bb1f | ||
![]() |
ed570b9f7c | ||
![]() |
59b0e986bf | ||
![]() |
cffb98d15b | ||
![]() |
3e1ba0f3b4 | ||
![]() |
d0b5bf4b7b | ||
![]() |
7db39e66b8 | ||
![]() |
94eb7f1dbd | ||
![]() |
5733b77b84 | ||
![]() |
98bebfb628 | ||
![]() |
7c4cc9bf5f | ||
![]() |
fa885d1813 | ||
![]() |
da4614eb8b | ||
![]() |
4dcd222d1f | ||
![]() |
7bdd31b34b | ||
![]() |
a4b8521efe | ||
![]() |
7037562998 | ||
![]() |
f3ff6ffc55 | ||
![]() |
e3ff87ecde | ||
![]() |
45ac700fff | ||
![]() |
2aab5acab4 | ||
![]() |
e9d760eea9 | ||
![]() |
d485d0a834 | ||
![]() |
973ac4b3bd | ||
![]() |
e91a152e06 |
47
.clang-format
Normal file
47
.clang-format
Normal 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
50
.codedocs
Normal 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 =
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build/
|
||||
/tags
|
28
.travis.yml
Normal file
28
.travis.yml
Normal 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
|
393
CMakeLists.txt
393
CMakeLists.txt
@@ -1,68 +1,367 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
###
|
||||
### CMake settings
|
||||
###
|
||||
# see http://www.cmake.org/Wiki/CMake_Policies
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project (YAML_CPP)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(LIB_TYPE SHARED)
|
||||
###
|
||||
### Project settings
|
||||
###
|
||||
project(YAML_CPP VERSION 0.6.3)
|
||||
|
||||
###
|
||||
### Project options
|
||||
###
|
||||
## Project stuff
|
||||
option(YAML_CPP_BUILD_TESTS "Enable testing" ON)
|
||||
option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON)
|
||||
option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
|
||||
option(YAML_CPP_INSTALL "Enable generation of install target" ON)
|
||||
|
||||
## Build options
|
||||
# --> General
|
||||
# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS
|
||||
# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library
|
||||
option(YAML_BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||
|
||||
# --> Apple
|
||||
if(APPLE)
|
||||
option(YAML_APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
|
||||
endif()
|
||||
|
||||
# --> Microsoft Visual C++
|
||||
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
|
||||
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
|
||||
if(MSVC)
|
||||
option(YAML_MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
|
||||
option(YAML_MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)
|
||||
endif()
|
||||
|
||||
###
|
||||
### Sources, headers, directories and libs
|
||||
###
|
||||
|
||||
# From http://www.cmake.org/pipermail/cmake/2010-March/035992.html:
|
||||
# function to collect all the sources from sub-directories
|
||||
# into a single list
|
||||
function(add_sources)
|
||||
get_property(is_defined GLOBAL PROPERTY SRCS_LIST DEFINED)
|
||||
if(NOT is_defined)
|
||||
define_property(GLOBAL PROPERTY SRCS_LIST
|
||||
BRIEF_DOCS "List of source files"
|
||||
FULL_DOCS "List of all source files in the entire project")
|
||||
endif()
|
||||
# make absolute paths
|
||||
set(SRCS)
|
||||
foreach(s IN LISTS ARGN)
|
||||
if(NOT IS_ABSOLUTE "${s}")
|
||||
get_filename_component(s "${s}" ABSOLUTE)
|
||||
endif()
|
||||
list(APPEND SRCS "${s}")
|
||||
endforeach()
|
||||
# append to global list
|
||||
set_property(GLOBAL APPEND PROPERTY SRCS_LIST "${SRCS}")
|
||||
endfunction(add_sources)
|
||||
|
||||
set(header_directory "include/yaml-cpp/")
|
||||
|
||||
file(GLOB sources "src/[a-zA-Z]*.cpp")
|
||||
file(GLOB_RECURSE public_headers "include/yaml-cpp/[a-zA-Z]*.h")
|
||||
file(GLOB private_headers "src/[a-zA-Z]*.h")
|
||||
|
||||
if(YAML_CPP_BUILD_CONTRIB)
|
||||
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
|
||||
file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h")
|
||||
file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h")
|
||||
else()
|
||||
add_definitions(-DYAML_CPP_NO_CONTRIB)
|
||||
endif()
|
||||
|
||||
set(library_sources
|
||||
${sources}
|
||||
${public_headers}
|
||||
${private_headers}
|
||||
${contrib_sources}
|
||||
${contrib_public_headers}
|
||||
${contrib_private_headers}
|
||||
)
|
||||
add_sources(${library_sources})
|
||||
|
||||
if(VERBOSE)
|
||||
message(STATUS "sources: ${sources}")
|
||||
message(STATUS "public_headers: ${public_headers}")
|
||||
message(STATUS "private_headers: ${private_headers}")
|
||||
message(STATUS "contrib_sources: ${contrib_sources}")
|
||||
message(STATUS "contrib_public_headers: ${contrib_public_headers}")
|
||||
message(STATUS "contrib_private_headers: ${contrib_private_headers}")
|
||||
endif()
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/src)
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
### General compilation settings
|
||||
###
|
||||
set(yaml_c_flags ${CMAKE_C_FLAGS})
|
||||
set(yaml_cxx_flags ${CMAKE_CXX_FLAGS})
|
||||
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
set(LABEL_SUFFIX "shared")
|
||||
else()
|
||||
set(LABEL_SUFFIX "static")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(YAML_APPLE_UNIVERSAL_BIN)
|
||||
set(CMAKE_OSX_ARCHITECTURES ppc;i386)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(IPHONE)
|
||||
set(CMAKE_OSX_SYSROOT iphoneos2.2.1)
|
||||
set(LIB_TYPE)
|
||||
endif(IPHONE)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
set(YAML_CPP_VERSION_MAJOR "0")
|
||||
set(YAML_CPP_VERSION_MINOR "2")
|
||||
set(YAML_CPP_VERSION_PATCH "0")
|
||||
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
||||
|
||||
enable_testing()
|
||||
set(CMAKE_OSX_SYSROOT "iphoneos4.2")
|
||||
set(CMAKE_OSX_ARCHITECTURES "armv6;armv7")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(_library_dir bin) # .dll are in PATH, like executables
|
||||
else(WIN32)
|
||||
set(_library_dir lib)
|
||||
endif(WIN32)
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
|
||||
endif()
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "C:/")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(INCLUDE_INSTALL_DIR include/yaml-cpp)
|
||||
set(LIB_INSTALL_DIR ${_library_dir}${LIB_SUFFIX})
|
||||
# GCC or Clang or Intel Compiler specialities
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
|
||||
(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") OR
|
||||
CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
### General stuff
|
||||
if(WIN32)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix
|
||||
set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs
|
||||
set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3)
|
||||
endif()
|
||||
|
||||
### Project stuff
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
#
|
||||
set(GCC_EXTRA_OPTIONS "")
|
||||
#
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
|
||||
endif()
|
||||
#
|
||||
set(FLAG_TESTED "-Wextra -Wshadow -Weffc++ -pedantic -pedantic-errors")
|
||||
check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
|
||||
if(FLAG_WEXTRA)
|
||||
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
|
||||
endif()
|
||||
#
|
||||
set(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${yaml_cxx_flags}")
|
||||
|
||||
### Make specific
|
||||
if(${CMAKE_BUILD_TOOL} MATCHES make OR ${CMAKE_BUILD_TOOL} MATCHES gmake)
|
||||
add_custom_target(debuggable ${CMAKE_MAKE_PROGRAM} clean
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Adjusting settings for debug compilation"
|
||||
VERBATIM)
|
||||
add_custom_target(releasable ${CMAKE_MAKE_PROGRAM} clean
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Adjusting settings for release compilation"
|
||||
VERBATIM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Microsoft VisualC++ specialities
|
||||
if(MSVC)
|
||||
### General stuff
|
||||
# a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003))
|
||||
# plus set lib suffix for later use and project label accordingly
|
||||
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
|
||||
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
|
||||
set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC
|
||||
set(LIB_RT_OPTION "/MD")
|
||||
#
|
||||
if(NOT YAML_MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML)
|
||||
if(YAML_MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries
|
||||
set(LIB_RT_SUFFIX "ml")
|
||||
set(LIB_RT_OPTION "/ML")
|
||||
if(NOT ${MSVC_VERSION} LESS 1400)
|
||||
message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).")
|
||||
endif()
|
||||
else()
|
||||
set(LIB_RT_SUFFIX "mt")
|
||||
set(LIB_RT_OPTION "/MT")
|
||||
endif()
|
||||
|
||||
# correct linker options
|
||||
foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
|
||||
set(var_name "${flag_var}")
|
||||
if(NOT "${config_name}" STREQUAL "")
|
||||
set(var_name "${var_name}_${config_name}")
|
||||
endif()
|
||||
string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}")
|
||||
set(${var_name} "${${var_name}}" CACHE STRING "" FORCE)
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif()
|
||||
#
|
||||
set(LABEL_SUFFIX "${LABEL_SUFFIX} ${LIB_RT_SUFFIX}")
|
||||
|
||||
# b) Change prefix for static libraries
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs
|
||||
|
||||
# c) Correct suffixes for static libraries
|
||||
if(NOT YAML_BUILD_SHARED_LIBS)
|
||||
### General stuff
|
||||
set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}")
|
||||
endif()
|
||||
|
||||
### Project stuff
|
||||
# /W3 = set warning level; see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx
|
||||
# /wd4127 = disable warning C4127 "conditional expression is constant"; see http://msdn.microsoft.com/en-us/library/6t66728h.aspx
|
||||
# /wd4355 = disable warning C4355 "'this' : used in base member initializer list"; http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
|
||||
set(yaml_cxx_flags "/W3 /wd4127 /wd4355 ${yaml_cxx_flags}")
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
### General install settings
|
||||
###
|
||||
set(INCLUDE_INSTALL_ROOT_DIR include)
|
||||
|
||||
set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
|
||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
|
||||
|
||||
#
|
||||
set(_INSTALL_DESTINATIONS
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
)
|
||||
#
|
||||
file(GLOB public_headers include/*.h)
|
||||
file(GLOB private_headers src/*.h)
|
||||
file(GLOB sources src/*.cpp)
|
||||
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
||||
add_library(yaml-cpp
|
||||
${LIB_TYPE}
|
||||
${public_headers}
|
||||
${private_headers}
|
||||
${sources}
|
||||
|
||||
###
|
||||
### Library
|
||||
###
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
add_library(yaml-cpp SHARED ${library_sources})
|
||||
else()
|
||||
add_library(yaml-cpp STATIC ${library_sources})
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
target_include_directories(yaml-cpp
|
||||
PUBLIC $<BUILD_INTERFACE:${YAML_CPP_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_ROOT_DIR}>
|
||||
PRIVATE $<BUILD_INTERFACE:${YAML_CPP_SOURCE_DIR}/src>)
|
||||
endif()
|
||||
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}"
|
||||
)
|
||||
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
VERSION "${YAML_CPP_VERSION}"
|
||||
SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}"
|
||||
PROJECT_LABEL "yaml-cpp ${LABEL_SUFFIX}"
|
||||
)
|
||||
|
||||
install(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS})
|
||||
install(
|
||||
FILES ${public_headers}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
if(IPHONE)
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
|
||||
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
|
||||
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif(UNIX)
|
||||
if(MSVC)
|
||||
if(NOT YAML_BUILD_SHARED_LIBS)
|
||||
# correct library names
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d"
|
||||
RELEASE_POSTFIX "${LIB_TARGET_SUFFIX}"
|
||||
MINSIZEREL_POSTFIX "${LIB_TARGET_SUFFIX}"
|
||||
RELWITHDEBINFO_POSTFIX "${LIB_TARGET_SUFFIX}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory (yaml-reader)
|
||||
add_subdirectory (util)
|
||||
if (YAML_CPP_INSTALL)
|
||||
install(TARGETS yaml-cpp EXPORT yaml-cpp-targets ${_INSTALL_DESTINATIONS})
|
||||
install(
|
||||
DIRECTORY ${header_directory}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
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)
|
||||
|
||||
if (YAML_CPP_INSTALL)
|
||||
install(FILES
|
||||
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
|
||||
install(EXPORT yaml-cpp-targets DESTINATION ${INSTALL_CMAKE_DIR})
|
||||
|
||||
if(UNIX)
|
||||
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
|
||||
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
|
||||
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
### Extras
|
||||
###
|
||||
if(YAML_CPP_BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
if(YAML_CPP_BUILD_TOOLS)
|
||||
add_subdirectory(util)
|
||||
endif()
|
||||
|
||||
### Formatting
|
||||
get_property(all_sources GLOBAL PROPERTY SRCS_LIST)
|
||||
add_custom_target(format
|
||||
COMMAND clang-format --style=file -i ${all_sources}
|
||||
COMMENT "Running clang-format"
|
||||
VERBATIM)
|
||||
|
26
CONTRIBUTING.md
Normal file
26
CONTRIBUTING.md
Normal 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.
|
@@ -1,19 +1,19 @@
|
||||
Copyright (c) 2008 Jesse Beder.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2008-2015 Jesse Beder.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# yaml-cpp [](https://travis-ci.org/jbeder/yaml-cpp) [](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] [-DYAML_BUILD_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 `-DYAML_BUILD_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.
|
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "null.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
inline bool Convert(const std::string& input, std::string& output) {
|
||||
output = input;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Convert(const std::string& input, bool& output);
|
||||
bool Convert(const std::string& input, _Null& output);
|
||||
|
||||
#define YAML_MAKE_STREAM_CONVERT(type) \
|
||||
inline bool Convert(const std::string& input, type& output) { \
|
||||
std::stringstream stream(input); \
|
||||
stream >> output; \
|
||||
return !stream.fail(); \
|
||||
}
|
||||
|
||||
YAML_MAKE_STREAM_CONVERT(char)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned char)
|
||||
YAML_MAKE_STREAM_CONVERT(int)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned int)
|
||||
YAML_MAKE_STREAM_CONVERT(short)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned short)
|
||||
YAML_MAKE_STREAM_CONVERT(long)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned long)
|
||||
YAML_MAKE_STREAM_CONVERT(float)
|
||||
YAML_MAKE_STREAM_CONVERT(double)
|
||||
YAML_MAKE_STREAM_CONVERT(long double)
|
||||
|
||||
#undef YAML_MAKE_STREAM_CONVERT
|
||||
}
|
||||
|
||||
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
// for detecting memory leaks
|
||||
#ifdef _DEBUG
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
#endif // CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,94 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "emittermanip.h"
|
||||
#include "ostream.h"
|
||||
#include "null.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class EmitterState;
|
||||
|
||||
class Emitter
|
||||
{
|
||||
public:
|
||||
Emitter();
|
||||
~Emitter();
|
||||
|
||||
// output
|
||||
const char *c_str() const;
|
||||
unsigned size() const;
|
||||
|
||||
// state checking
|
||||
bool good() const;
|
||||
const std::string GetLastError() const;
|
||||
|
||||
// global setters
|
||||
bool SetStringFormat(EMITTER_MANIP value);
|
||||
bool SetBoolFormat(EMITTER_MANIP value);
|
||||
bool SetIntBase(EMITTER_MANIP value);
|
||||
bool SetSeqFormat(EMITTER_MANIP value);
|
||||
bool SetMapFormat(EMITTER_MANIP value);
|
||||
bool SetIndent(unsigned n);
|
||||
bool SetPreCommentIndent(unsigned n);
|
||||
bool SetPostCommentIndent(unsigned n);
|
||||
|
||||
// local setters
|
||||
Emitter& SetLocalValue(EMITTER_MANIP value);
|
||||
Emitter& SetLocalIndent(const _Indent& indent);
|
||||
|
||||
// overloads of write
|
||||
Emitter& Write(const std::string& str);
|
||||
Emitter& Write(const char *str);
|
||||
Emitter& Write(int i);
|
||||
Emitter& Write(bool b);
|
||||
Emitter& Write(float f);
|
||||
Emitter& Write(double d);
|
||||
Emitter& Write(const _Alias& alias);
|
||||
Emitter& Write(const _Anchor& anchor);
|
||||
Emitter& Write(const _Comment& comment);
|
||||
Emitter& Write(const _Null& null);
|
||||
|
||||
private:
|
||||
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
|
||||
|
||||
void PreAtomicWrite();
|
||||
bool GotoNextPreAtomicState();
|
||||
void PostAtomicWrite();
|
||||
void EmitSeparationIfNecessary();
|
||||
|
||||
void EmitBeginSeq();
|
||||
void EmitEndSeq();
|
||||
void EmitBeginMap();
|
||||
void EmitEndMap();
|
||||
void EmitKey();
|
||||
void EmitValue();
|
||||
|
||||
private:
|
||||
ostream m_stream;
|
||||
std::auto_ptr <EmitterState> m_pState;
|
||||
};
|
||||
|
||||
// overloads of insertion
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, T v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
||||
return emitter.SetLocalValue(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
||||
return emitter.SetLocalIndent(indent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
enum EMITTER_MANIP {
|
||||
// general manipulators
|
||||
Auto,
|
||||
|
||||
// string manipulators
|
||||
// Auto, // duplicate
|
||||
SingleQuoted,
|
||||
DoubleQuoted,
|
||||
Literal,
|
||||
|
||||
// bool manipulators
|
||||
YesNoBool, // yes, no
|
||||
TrueFalseBool, // true, false
|
||||
OnOffBool, // on, off
|
||||
UpperCase, // TRUE, N
|
||||
LowerCase, // f, yes
|
||||
CamelCase, // No, Off
|
||||
LongBool, // yes, On
|
||||
ShortBool, // y, t
|
||||
|
||||
// int manipulators
|
||||
Dec,
|
||||
Hex,
|
||||
Oct,
|
||||
|
||||
// sequence manipulators
|
||||
BeginSeq,
|
||||
EndSeq,
|
||||
Flow,
|
||||
Block,
|
||||
|
||||
// map manipulators
|
||||
BeginMap,
|
||||
EndMap,
|
||||
Key,
|
||||
Value,
|
||||
// Flow, // duplicate
|
||||
// Block, // duplicate
|
||||
// Auto, // duplicate
|
||||
LongKey
|
||||
};
|
||||
|
||||
struct _Indent {
|
||||
_Indent(int value_): value(value_) {}
|
||||
int value;
|
||||
};
|
||||
|
||||
inline _Indent Indent(int value) {
|
||||
return _Indent(value);
|
||||
}
|
||||
|
||||
struct _Alias {
|
||||
_Alias(const std::string& content_): content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Alias Alias(const std::string content) {
|
||||
return _Alias(content);
|
||||
}
|
||||
|
||||
struct _Anchor {
|
||||
_Anchor(const std::string& content_): content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Anchor Anchor(const std::string content) {
|
||||
return _Anchor(content);
|
||||
}
|
||||
|
||||
struct _Comment {
|
||||
_Comment(const std::string& content_): content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Comment Comment(const std::string content) {
|
||||
return _Comment(content);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,137 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "mark.h"
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// error messages
|
||||
namespace ErrorMsg
|
||||
{
|
||||
const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
|
||||
const std::string YAML_VERSION = "bad YAML version: ";
|
||||
const std::string YAML_MAJOR_VERSION = "YAML major version too large";
|
||||
const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
|
||||
const std::string END_OF_MAP = "end of map not found";
|
||||
const std::string END_OF_MAP_FLOW = "end of map flow not found";
|
||||
const std::string END_OF_SEQ = "end of sequence not found";
|
||||
const std::string END_OF_SEQ_FLOW = "end of sequence flow not found";
|
||||
const std::string MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
|
||||
const std::string MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
|
||||
const std::string MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
|
||||
const std::string ALIAS_CONTENT = "aliases can't have any content, *including* tags";
|
||||
const std::string INVALID_HEX = "bad character found while scanning hex number";
|
||||
const std::string INVALID_UNICODE = "invalid unicode: ";
|
||||
const std::string INVALID_ESCAPE = "unknown escape character: ";
|
||||
const std::string UNKNOWN_TOKEN = "unknown token";
|
||||
const std::string DOC_IN_SCALAR = "illegal document indicator in scalar";
|
||||
const std::string EOF_IN_SCALAR = "illegal EOF in scalar";
|
||||
const std::string CHAR_IN_SCALAR = "illegal character in scalar";
|
||||
const std::string TAB_IN_INDENTATION = "illegal tab when looking for indentation";
|
||||
const std::string FLOW_END = "illegal flow end";
|
||||
const std::string BLOCK_ENTRY = "illegal block entry";
|
||||
const std::string MAP_KEY = "illegal map key";
|
||||
const std::string MAP_VALUE = "illegal map value";
|
||||
const std::string ALIAS_NOT_FOUND = "alias not found after *";
|
||||
const std::string ANCHOR_NOT_FOUND = "anchor not found after &";
|
||||
const std::string CHAR_IN_ALIAS = "illegal character found while scanning alias";
|
||||
const std::string CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
|
||||
const std::string ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
|
||||
const std::string CHAR_IN_BLOCK = "unexpected character in block scalar";
|
||||
const std::string AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
|
||||
const std::string UNKNOWN_ANCHOR = "the referenced anchor is not defined";
|
||||
|
||||
const std::string INVALID_SCALAR = "invalid scalar";
|
||||
const std::string KEY_NOT_FOUND = "key not found";
|
||||
const std::string BAD_DEREFERENCE = "bad dereference";
|
||||
|
||||
const std::string UNMATCHED_GROUP_TAG = "unmatched group tag";
|
||||
const std::string UNEXPECTED_END_SEQ = "unexpected end sequence token";
|
||||
const std::string UNEXPECTED_END_MAP = "unexpected end map token";
|
||||
const std::string SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
|
||||
const std::string INVALID_ANCHOR = "invalid anchor";
|
||||
const std::string INVALID_ALIAS = "invalid alias";
|
||||
const std::string EXPECTED_KEY_TOKEN = "expected key token";
|
||||
const std::string EXPECTED_VALUE_TOKEN = "expected value token";
|
||||
const std::string UNEXPECTED_KEY_TOKEN = "unexpected key token";
|
||||
const std::string UNEXPECTED_VALUE_TOKEN = "unexpected value token";
|
||||
}
|
||||
|
||||
class Exception: public std::exception {
|
||||
public:
|
||||
Exception(const Mark& mark_, const std::string& msg_)
|
||||
: mark(mark_), msg(msg_) {
|
||||
std::stringstream output;
|
||||
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
|
||||
what_ = output.str();
|
||||
}
|
||||
virtual ~Exception() throw() {}
|
||||
virtual const char *what() const throw() { return what_.c_str(); }
|
||||
|
||||
Mark mark;
|
||||
std::string msg;
|
||||
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
class ParserException: public Exception {
|
||||
public:
|
||||
ParserException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
class RepresentationException: public Exception {
|
||||
public:
|
||||
RepresentationException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
};
|
||||
|
||||
// representation exceptions
|
||||
class InvalidScalar: public RepresentationException {
|
||||
public:
|
||||
InvalidScalar(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
|
||||
};
|
||||
|
||||
class KeyNotFound: public RepresentationException {
|
||||
public:
|
||||
KeyNotFound(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedKeyNotFound: public KeyNotFound {
|
||||
public:
|
||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
||||
: KeyNotFound(mark_), key(key_) {}
|
||||
~TypedKeyNotFound() throw() {}
|
||||
|
||||
T key;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
|
||||
return TypedKeyNotFound <T> (mark, key);
|
||||
}
|
||||
|
||||
class BadDereference: public RepresentationException {
|
||||
public:
|
||||
BadDereference()
|
||||
: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
|
||||
};
|
||||
|
||||
class EmitterException: public Exception {
|
||||
public:
|
||||
EmitterException(const std::string& msg_)
|
||||
: Exception(Mark::null(), msg_) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
struct IterPriv;
|
||||
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
Iterator();
|
||||
Iterator(IterPriv *pData);
|
||||
Iterator(const Iterator& rhs);
|
||||
~Iterator();
|
||||
|
||||
Iterator& operator = (const Iterator& rhs);
|
||||
Iterator& operator ++ ();
|
||||
Iterator operator ++ (int);
|
||||
const Node& operator * () const;
|
||||
const Node *operator -> () const;
|
||||
const Node& first() const;
|
||||
const Node& second() const;
|
||||
|
||||
friend bool operator == (const Iterator& it, const Iterator& jt);
|
||||
friend bool operator != (const Iterator& it, const Iterator& jt);
|
||||
|
||||
private:
|
||||
IterPriv *m_pData;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Mark {
|
||||
Mark(): pos(0), line(0), column(0) {}
|
||||
|
||||
static const Mark null() { return Mark(-1, -1, -1); }
|
||||
|
||||
int pos;
|
||||
int line, column;
|
||||
|
||||
private:
|
||||
Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
138
include/node.h
138
include/node.h
@@ -1,138 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "conversion.h"
|
||||
#include "exceptions.h"
|
||||
#include "iterator.h"
|
||||
#include "mark.h"
|
||||
#include "noncopyable.h"
|
||||
#include "parserstate.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Content;
|
||||
class Scanner;
|
||||
class Emitter;
|
||||
|
||||
enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP };
|
||||
|
||||
class Node: private noncopyable
|
||||
{
|
||||
public:
|
||||
Node();
|
||||
~Node();
|
||||
|
||||
void Clear();
|
||||
std::auto_ptr<Node> Clone() const;
|
||||
void Parse(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
CONTENT_TYPE GetType() const;
|
||||
|
||||
// file location of start of this node
|
||||
const Mark GetMark() const { return m_mark; }
|
||||
|
||||
// accessors
|
||||
Iterator begin() const;
|
||||
Iterator end() const;
|
||||
std::size_t size() const;
|
||||
|
||||
// extraction of scalars
|
||||
bool GetScalar(std::string& s) const;
|
||||
|
||||
// we can specialize this for other values
|
||||
template <typename T>
|
||||
bool Read(T& value) const;
|
||||
|
||||
template <typename T>
|
||||
const T Read() const;
|
||||
|
||||
template <typename T>
|
||||
operator T() const;
|
||||
|
||||
template <typename T>
|
||||
friend void operator >> (const Node& node, T& value);
|
||||
|
||||
// retrieval for maps and sequences
|
||||
template <typename T>
|
||||
const Node *FindValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node& operator [] (const T& key) const;
|
||||
|
||||
// specific to maps
|
||||
const Node *FindValue(const char *key) const;
|
||||
const Node& operator [] (const char *key) const;
|
||||
|
||||
// for anchors/aliases
|
||||
const Node *Identity() const { return m_pIdentity; }
|
||||
bool IsAlias() const { return m_alias; }
|
||||
bool IsReferenced() const { return m_referenced; }
|
||||
|
||||
// emitting
|
||||
friend Emitter& operator << (Emitter& out, const Node& node);
|
||||
|
||||
// ordering
|
||||
int Compare(const Node& rhs) const;
|
||||
friend bool operator < (const Node& n1, const Node& n2);
|
||||
|
||||
private:
|
||||
// helper for sequences
|
||||
template <typename, bool> friend struct _FindFromNodeAtIndex;
|
||||
const Node *FindAtIndex(std::size_t i) const;
|
||||
|
||||
// helper for maps
|
||||
template <typename T>
|
||||
const Node& GetValue(const T& key) const;
|
||||
|
||||
template <typename T>
|
||||
const Node *FindValueForKey(const T& key) const;
|
||||
|
||||
// helper for cloning
|
||||
Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent);
|
||||
|
||||
// helpers for parsing
|
||||
void ParseHeader(Scanner *pScanner, const ParserState& state);
|
||||
void ParseTag(Scanner *pScanner, const ParserState& state);
|
||||
void ParseAnchor(Scanner *pScanner, const ParserState& state);
|
||||
void ParseAlias(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
private:
|
||||
Mark m_mark;
|
||||
std::string m_anchor, m_tag;
|
||||
Content *m_pContent;
|
||||
bool m_alias;
|
||||
const Node *m_pIdentity;
|
||||
mutable bool m_referenced;
|
||||
};
|
||||
|
||||
// comparisons with auto-conversion
|
||||
template <typename T>
|
||||
bool operator == (const T& value, const Node& node);
|
||||
|
||||
template <typename T>
|
||||
bool operator == (const Node& node, const T& value);
|
||||
|
||||
template <typename T>
|
||||
bool operator != (const T& value, const Node& node);
|
||||
|
||||
template <typename T>
|
||||
bool operator != (const Node& node, const T& value);
|
||||
|
||||
bool operator == (const char *value, const Node& node);
|
||||
bool operator == (const Node& node, const char *value);
|
||||
bool operator != (const char *value, const Node& node);
|
||||
bool operator != (const Node& node, const char *value);
|
||||
}
|
||||
|
||||
#include "nodeimpl.h"
|
||||
#include "nodereadimpl.h"
|
||||
|
||||
#endif // NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,118 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "nodeutil.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// implementation of templated things
|
||||
template <typename T>
|
||||
inline const T Node::Read() const {
|
||||
T value;
|
||||
*this >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Node::operator T() const {
|
||||
return Read<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void operator >> (const Node& node, T& value) {
|
||||
if(!ConvertScalar(node, value))
|
||||
throw InvalidScalar(node.m_mark);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValue(const T& key) const {
|
||||
switch(GetType()) {
|
||||
case CT_MAP:
|
||||
return FindValueForKey(key);
|
||||
case CT_SEQUENCE:
|
||||
return FindFromNodeAtIndex(*this, key);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node *Node::FindValueForKey(const T& key) const {
|
||||
for(Iterator it=begin();it!=end();++it) {
|
||||
T t;
|
||||
if(it.first().Read(t)) {
|
||||
if(key == t)
|
||||
return &it.second();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::GetValue(const T& key) const {
|
||||
if(!m_pContent)
|
||||
throw BadDereference();
|
||||
|
||||
const Node *pValue = FindValue(key);
|
||||
if(!pValue)
|
||||
throw MakeTypedKeyNotFound(m_mark, key);
|
||||
|
||||
return *pValue;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const Node& Node::operator [] (const T& key) const {
|
||||
return GetValue(key);
|
||||
}
|
||||
|
||||
inline const Node *Node::FindValue(const char *key) const {
|
||||
return FindValue(std::string(key));
|
||||
}
|
||||
|
||||
inline const Node& Node::operator [] (const char *key) const {
|
||||
return GetValue(std::string(key));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator == (const T& value, const Node& node) {
|
||||
return value == node.Read<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator == (const Node& node, const T& value) {
|
||||
return value == node.Read<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator != (const T& value, const Node& node) {
|
||||
return value != node.Read<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator != (const Node& node, const T& value) {
|
||||
return value != node.Read<T>();
|
||||
}
|
||||
|
||||
inline bool operator == (const char *value, const Node& node) {
|
||||
return std::string(value) == node;
|
||||
}
|
||||
|
||||
inline bool operator == (const Node& node, const char *value) {
|
||||
return std::string(value) == node;
|
||||
}
|
||||
|
||||
inline bool operator != (const char *value, const Node& node) {
|
||||
return std::string(value) != node;
|
||||
}
|
||||
|
||||
inline bool operator != (const Node& node, const char *value) {
|
||||
return std::string(value) != node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,65 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// implementation for Node::Read
|
||||
// (the goal is to call ConvertScalar if we can, and fall back to operator >> if not)
|
||||
// thanks to litb from stackoverflow.com
|
||||
// http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390
|
||||
|
||||
template<bool>
|
||||
struct read_impl;
|
||||
|
||||
// ConvertScalar available
|
||||
template<>
|
||||
struct read_impl<true> {
|
||||
template<typename T>
|
||||
static bool read(const Node& node, T& value) {
|
||||
return ConvertScalar(node, value);
|
||||
}
|
||||
};
|
||||
|
||||
// ConvertScalar not available
|
||||
template<>
|
||||
struct read_impl<false> {
|
||||
template<typename T>
|
||||
static bool read(const Node& node, T& value) {
|
||||
try {
|
||||
node >> value;
|
||||
} catch(const Exception&) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
namespace fallback {
|
||||
// sizeof > 1
|
||||
struct flag { char c[2]; };
|
||||
flag Convert(...);
|
||||
|
||||
char (& operator,(flag, flag) )[1];
|
||||
|
||||
template<typename T>
|
||||
void operator,(flag, T const&);
|
||||
|
||||
char (& operator,(char(&)[1], flag) )[1];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool Node::Read(T& value) const {
|
||||
using namespace fallback;
|
||||
|
||||
return read_impl<sizeof (fallback::flag(), Convert(std::string(), value), fallback::flag()) != 1>::read(*this, value);
|
||||
}
|
||||
|
||||
// the main conversion function
|
||||
template <typename T>
|
||||
inline bool ConvertScalar(const Node& node, T& value) {
|
||||
std::string scalar;
|
||||
if(!node.GetScalar(scalar))
|
||||
return false;
|
||||
|
||||
return Convert(scalar, value);
|
||||
}
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <typename T, typename U>
|
||||
struct is_same_type {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_same_type<T, T> {
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template <typename T, bool check>
|
||||
struct is_index_type_with_check {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template <> struct is_index_type_with_check<std::size_t, false> { enum { value = true }; };
|
||||
|
||||
#define MAKE_INDEX_TYPE(Type) \
|
||||
template <> struct is_index_type_with_check<Type, is_same_type<Type, std::size_t>::value> { enum { value = true }; }
|
||||
|
||||
MAKE_INDEX_TYPE(int);
|
||||
MAKE_INDEX_TYPE(unsigned);
|
||||
MAKE_INDEX_TYPE(short);
|
||||
MAKE_INDEX_TYPE(unsigned short);
|
||||
MAKE_INDEX_TYPE(long);
|
||||
MAKE_INDEX_TYPE(unsigned long);
|
||||
|
||||
#undef MAKE_INDEX_TYPE
|
||||
|
||||
template <typename T>
|
||||
struct is_index_type: public is_index_type_with_check<T, false> {};
|
||||
|
||||
// messing around with template stuff to get the right overload for operator [] for a sequence
|
||||
template <typename T, bool b>
|
||||
struct _FindFromNodeAtIndex {
|
||||
const Node *pRet;
|
||||
_FindFromNodeAtIndex(const Node&, const T&): pRet(0) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _FindFromNodeAtIndex<T, true> {
|
||||
const Node *pRet;
|
||||
_FindFromNodeAtIndex(const Node& node, const T& key): pRet(node.FindAtIndex(static_cast<std::size_t>(key))) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline const Node *FindFromNodeAtIndex(const Node& node, const T& key) {
|
||||
return _FindFromNodeAtIndex<T, is_index_type<T>::value>(node, key).pRet;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// this is basically boost::noncopyable
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
noncopyable() {}
|
||||
~noncopyable() {}
|
||||
|
||||
private:
|
||||
noncopyable(const noncopyable&);
|
||||
const noncopyable& operator = (const noncopyable&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
struct _Null {};
|
||||
inline bool operator == (const _Null&, const _Null&) { return true; }
|
||||
inline bool operator != (const _Null&, const _Null&) { return false; }
|
||||
|
||||
bool IsNull(const Node& node);
|
||||
|
||||
extern _Null Null;
|
||||
}
|
||||
|
||||
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class ostream
|
||||
{
|
||||
public:
|
||||
ostream();
|
||||
~ostream();
|
||||
|
||||
void reserve(unsigned size);
|
||||
void put(char ch);
|
||||
const char *str() const { return m_buffer; }
|
||||
|
||||
unsigned row() const { return m_row; }
|
||||
unsigned col() const { return m_col; }
|
||||
unsigned pos() const { return m_pos; }
|
||||
|
||||
private:
|
||||
char *m_buffer;
|
||||
unsigned m_pos;
|
||||
unsigned m_size;
|
||||
|
||||
unsigned m_row, m_col;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream& out, const char *str);
|
||||
ostream& operator << (ostream& out, const std::string& str);
|
||||
ostream& operator << (ostream& out, char ch);
|
||||
}
|
||||
|
||||
#endif // OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "node.h"
|
||||
#include "parserstate.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Scanner;
|
||||
struct Token;
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(std::istream& in);
|
||||
~Parser();
|
||||
|
||||
operator bool() const;
|
||||
|
||||
void Load(std::istream& in);
|
||||
void GetNextDocument(Node& document);
|
||||
void PrintTokens(std::ostream& out);
|
||||
|
||||
private:
|
||||
void ParseDirectives();
|
||||
void HandleDirective(Token *pToken);
|
||||
void HandleYamlDirective(Token *pToken);
|
||||
void HandleTagDirective(Token *pToken);
|
||||
|
||||
private:
|
||||
// can't copy this
|
||||
Parser(const Parser&) {}
|
||||
Parser& operator = (const Parser&) { return *this; }
|
||||
|
||||
private:
|
||||
Scanner *m_pScanner;
|
||||
ParserState m_state;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Version {
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
struct ParserState
|
||||
{
|
||||
Version version;
|
||||
std::map <std::string, std::string> tags;
|
||||
|
||||
void Reset();
|
||||
std::string TranslateTag(const std::string& handle) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, const std::vector <T>& v) {
|
||||
typedef typename std::vector <T> vec;
|
||||
emitter << BeginSeq;
|
||||
for(typename vec::const_iterator it=v.begin();it!=v.end();++it)
|
||||
emitter << *it;
|
||||
emitter << EndSeq;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, const std::list <T>& v) {
|
||||
typedef typename std::list <T> list;
|
||||
emitter << BeginSeq;
|
||||
for(typename list::const_iterator it=v.begin();it!=v.end();++it)
|
||||
emitter << *it;
|
||||
emitter << EndSeq;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline Emitter& operator << (Emitter& emitter, const std::map <K, V>& m) {
|
||||
typedef typename std::map <K, V> map;
|
||||
emitter << BeginMap;
|
||||
for(typename map::const_iterator it=m.begin();it!=m.end();++it)
|
||||
emitter << Key << it->first << Value << it->second;
|
||||
emitter << EndMap;
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
17
include/yaml-cpp/anchor.h
Normal file
17
include/yaml-cpp/anchor.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace YAML {
|
||||
typedef std::size_t anchor_t;
|
||||
const anchor_t NullAnchor = 0;
|
||||
}
|
||||
|
||||
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
71
include/yaml-cpp/binary.h
Normal file
71
include/yaml-cpp/binary.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
namespace YAML {
|
||||
YAML_CPP_API std::string EncodeBase64(const unsigned char *data,
|
||||
std::size_t size);
|
||||
YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
|
||||
|
||||
class YAML_CPP_API Binary {
|
||||
public:
|
||||
Binary(const unsigned char *data_, std::size_t size_)
|
||||
: m_data{}, m_unownedData(data_), m_unownedSize(size_) {}
|
||||
Binary() : Binary(nullptr, 0) {}
|
||||
Binary(const Binary &) = default;
|
||||
Binary(Binary &&) = default;
|
||||
Binary &operator=(const Binary &) = default;
|
||||
Binary &operator=(Binary &&) = default;
|
||||
|
||||
bool owned() const { return !m_unownedData; }
|
||||
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
|
||||
const unsigned char *data() const {
|
||||
return owned() ? &m_data[0] : m_unownedData;
|
||||
}
|
||||
|
||||
void swap(std::vector<unsigned char> &rhs) {
|
||||
if (m_unownedData) {
|
||||
m_data.swap(rhs);
|
||||
rhs.clear();
|
||||
rhs.resize(m_unownedSize);
|
||||
std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
|
||||
m_unownedData = nullptr;
|
||||
m_unownedSize = 0;
|
||||
} else {
|
||||
m_data.swap(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const Binary &rhs) const {
|
||||
const std::size_t s = size();
|
||||
if (s != rhs.size())
|
||||
return false;
|
||||
const unsigned char *d1 = data();
|
||||
const unsigned char *d2 = rhs.data();
|
||||
for (std::size_t i = 0; i < s; i++) {
|
||||
if (*d1++ != *d2++)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Binary &rhs) const { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
std::vector<unsigned char> m_data;
|
||||
const unsigned char *m_unownedData;
|
||||
std::size_t m_unownedSize;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
40
include/yaml-cpp/contrib/anchordict.h
Normal file
40
include/yaml-cpp/contrib/anchordict.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../anchor.h"
|
||||
|
||||
namespace YAML {
|
||||
/**
|
||||
* An object that stores and retrieves values correlating to {@link anchor_t}
|
||||
* values.
|
||||
*
|
||||
* <p>Efficient implementation that can make assumptions about how
|
||||
* {@code anchor_t} values are assigned by the {@link Parser} class.
|
||||
*/
|
||||
template <class T>
|
||||
class AnchorDict {
|
||||
public:
|
||||
AnchorDict() : m_data{} {}
|
||||
void Register(anchor_t anchor, T value) {
|
||||
if (anchor > m_data.size()) {
|
||||
m_data.resize(anchor);
|
||||
}
|
||||
m_data[anchor - 1] = value;
|
||||
}
|
||||
|
||||
T Get(anchor_t anchor) const { return m_data[anchor - 1]; }
|
||||
|
||||
private:
|
||||
std::vector<T> m_data;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
149
include/yaml-cpp/contrib/graphbuilder.h
Normal file
149
include/yaml-cpp/contrib/graphbuilder.h
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
class Parser;
|
||||
|
||||
// GraphBuilderInterface
|
||||
// . Abstraction of node creation
|
||||
// . pParentNode is always NULL or the return value of one of the NewXXX()
|
||||
// functions.
|
||||
class GraphBuilderInterface {
|
||||
public:
|
||||
virtual ~GraphBuilderInterface() = 0;
|
||||
|
||||
// Create and return a new node with a null value.
|
||||
virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
|
||||
|
||||
// Create and return a new node with the given tag and value.
|
||||
virtual void *NewScalar(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode, const std::string &value) = 0;
|
||||
|
||||
// Create and return a new sequence node
|
||||
virtual void *NewSequence(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode) = 0;
|
||||
|
||||
// Add pNode to pSequence. pNode was created with one of the NewXxx()
|
||||
// functions and pSequence with NewSequence().
|
||||
virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
|
||||
|
||||
// Note that no moew entries will be added to pSequence
|
||||
virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
|
||||
|
||||
// Create and return a new map node
|
||||
virtual void *NewMap(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode) = 0;
|
||||
|
||||
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
|
||||
// were created with one of the NewXxx() methods and pMap with NewMap().
|
||||
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
|
||||
|
||||
// Note that no more assignments will be made in pMap
|
||||
virtual void MapComplete(void *pMap) { (void)pMap; }
|
||||
|
||||
// Return the node that should be used in place of an alias referencing
|
||||
// pNode (pNode by default)
|
||||
virtual void *AnchorReference(const Mark &mark, void *pNode) {
|
||||
(void)mark;
|
||||
return pNode;
|
||||
}
|
||||
};
|
||||
|
||||
// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
|
||||
// Node, Sequence, and Map types. Sequence and Map must derive from Node
|
||||
// (unless Node is defined as void). Impl must also implement function with
|
||||
// all of the same names as the virtual functions in GraphBuilderInterface
|
||||
// -- including the ones with default implementations -- but with the
|
||||
// prototypes changed to accept an explicit Node*, Sequence*, or Map* where
|
||||
// appropriate.
|
||||
template <class Impl>
|
||||
class GraphBuilder : public GraphBuilderInterface {
|
||||
public:
|
||||
typedef typename Impl::Node Node;
|
||||
typedef typename Impl::Sequence Sequence;
|
||||
typedef typename Impl::Map Map;
|
||||
|
||||
GraphBuilder(Impl &impl) : m_impl(impl) {
|
||||
Map *pMap = NULL;
|
||||
Sequence *pSeq = NULL;
|
||||
Node *pNode = NULL;
|
||||
|
||||
// Type consistency checks
|
||||
pNode = pMap;
|
||||
pNode = pSeq;
|
||||
}
|
||||
|
||||
GraphBuilderInterface &AsBuilderInterface() { return *this; }
|
||||
|
||||
virtual void *NewNull(const Mark &mark, void *pParentNode) {
|
||||
return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
|
||||
}
|
||||
|
||||
virtual void *NewScalar(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode, const std::string &value) {
|
||||
return CheckType<Node>(
|
||||
m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
|
||||
}
|
||||
|
||||
virtual void *NewSequence(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode) {
|
||||
return CheckType<Sequence>(
|
||||
m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
|
||||
}
|
||||
virtual void AppendToSequence(void *pSequence, void *pNode) {
|
||||
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
|
||||
}
|
||||
virtual void SequenceComplete(void *pSequence) {
|
||||
m_impl.SequenceComplete(AsSequence(pSequence));
|
||||
}
|
||||
|
||||
virtual void *NewMap(const Mark &mark, const std::string &tag,
|
||||
void *pParentNode) {
|
||||
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
|
||||
}
|
||||
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
|
||||
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
|
||||
}
|
||||
virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
|
||||
|
||||
virtual void *AnchorReference(const Mark &mark, void *pNode) {
|
||||
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
|
||||
}
|
||||
|
||||
private:
|
||||
Impl &m_impl;
|
||||
|
||||
// Static check for pointer to T
|
||||
template <class T, class U>
|
||||
static T *CheckType(U *p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
|
||||
static Sequence *AsSequence(void *pSeq) {
|
||||
return static_cast<Sequence *>(pSeq);
|
||||
}
|
||||
static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
|
||||
};
|
||||
|
||||
void *BuildGraphOfNextDocument(Parser &parser,
|
||||
GraphBuilderInterface &graphBuilder);
|
||||
|
||||
template <class Impl>
|
||||
typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
|
||||
GraphBuilder<Impl> graphBuilder(impl);
|
||||
return static_cast<typename Impl::Node *>(
|
||||
BuildGraphOfNextDocument(parser, graphBuilder));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
33
include/yaml-cpp/dll.h
Normal file
33
include/yaml-cpp/dll.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// The following ifdef block is the standard way of creating macros which make
|
||||
// exporting from a DLL simpler. All files within this DLL are compiled with the
|
||||
// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
|
||||
// be defined on any project that uses this DLL. This way any other project
|
||||
// whose source files include this file see YAML_CPP_API functions as being
|
||||
// imported from a DLL, whereas this DLL sees symbols defined with this macro as
|
||||
// being exported.
|
||||
#undef YAML_CPP_API
|
||||
|
||||
#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
|
||||
// manually)
|
||||
#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
|
||||
// or defined manually)
|
||||
// #pragma message( "Defining YAML_CPP_API for DLL export" )
|
||||
#define YAML_CPP_API __declspec(dllexport)
|
||||
#else // yaml_cpp_EXPORTS
|
||||
// #pragma message( "Defining YAML_CPP_API for DLL import" )
|
||||
#define YAML_CPP_API __declspec(dllimport)
|
||||
#endif // yaml_cpp_EXPORTS
|
||||
#else // YAML_CPP_DLL
|
||||
#define YAML_CPP_API
|
||||
#endif // YAML_CPP_DLL
|
||||
|
||||
#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
57
include/yaml-cpp/emitfromevents.h
Normal file
57
include/yaml-cpp/emitfromevents.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class Emitter;
|
||||
|
||||
class EmitFromEvents : public EventHandler {
|
||||
public:
|
||||
EmitFromEvents(Emitter& emitter);
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark);
|
||||
virtual void OnDocumentEnd();
|
||||
|
||||
virtual void OnNull(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value);
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnSequenceEnd();
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnMapEnd();
|
||||
|
||||
private:
|
||||
void BeginNode();
|
||||
void EmitProps(const std::string& tag, anchor_t anchor);
|
||||
|
||||
private:
|
||||
Emitter& m_emitter;
|
||||
|
||||
struct State {
|
||||
enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue };
|
||||
};
|
||||
std::stack<State::value> m_stateStack;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
279
include/yaml-cpp/emitter.h
Normal file
279
include/yaml-cpp/emitter.h
Normal file
@@ -0,0 +1,279 @@
|
||||
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "yaml-cpp/binary.h"
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/emitterdef.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
#include "yaml-cpp/null.h"
|
||||
#include "yaml-cpp/ostream_wrapper.h"
|
||||
|
||||
namespace YAML {
|
||||
class Binary;
|
||||
struct _Null;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class EmitterState;
|
||||
|
||||
class YAML_CPP_API Emitter {
|
||||
public:
|
||||
Emitter();
|
||||
explicit Emitter(std::ostream& stream);
|
||||
Emitter(const Emitter&) = delete;
|
||||
Emitter& operator=(const Emitter&) = delete;
|
||||
~Emitter();
|
||||
|
||||
// output
|
||||
const char* c_str() const;
|
||||
std::size_t size() const;
|
||||
|
||||
// state checking
|
||||
bool good() const;
|
||||
const std::string GetLastError() const;
|
||||
|
||||
// global setters
|
||||
bool SetOutputCharset(EMITTER_MANIP value);
|
||||
bool SetStringFormat(EMITTER_MANIP value);
|
||||
bool SetBoolFormat(EMITTER_MANIP value);
|
||||
bool SetIntBase(EMITTER_MANIP value);
|
||||
bool SetSeqFormat(EMITTER_MANIP value);
|
||||
bool SetMapFormat(EMITTER_MANIP value);
|
||||
bool SetIndent(std::size_t n);
|
||||
bool SetPreCommentIndent(std::size_t n);
|
||||
bool SetPostCommentIndent(std::size_t n);
|
||||
bool SetFloatPrecision(std::size_t n);
|
||||
bool SetDoublePrecision(std::size_t n);
|
||||
|
||||
// local setters
|
||||
Emitter& SetLocalValue(EMITTER_MANIP value);
|
||||
Emitter& SetLocalIndent(const _Indent& indent);
|
||||
Emitter& SetLocalPrecision(const _Precision& precision);
|
||||
|
||||
// overloads of write
|
||||
Emitter& Write(const std::string& str);
|
||||
Emitter& Write(bool b);
|
||||
Emitter& Write(char ch);
|
||||
Emitter& Write(const _Alias& alias);
|
||||
Emitter& Write(const _Anchor& anchor);
|
||||
Emitter& Write(const _Tag& tag);
|
||||
Emitter& Write(const _Comment& comment);
|
||||
Emitter& Write(const _Null& n);
|
||||
Emitter& Write(const Binary& binary);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteIntegralType(T value);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteStreamable(T value);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void SetStreamablePrecision(std::stringstream&) {}
|
||||
std::size_t GetFloatPrecision() const;
|
||||
std::size_t GetDoublePrecision() const;
|
||||
|
||||
void PrepareIntegralStream(std::stringstream& stream) const;
|
||||
void StartedScalar();
|
||||
|
||||
private:
|
||||
void EmitBeginDoc();
|
||||
void EmitEndDoc();
|
||||
void EmitBeginSeq();
|
||||
void EmitEndSeq();
|
||||
void EmitBeginMap();
|
||||
void EmitEndMap();
|
||||
void EmitNewline();
|
||||
void EmitKindTag();
|
||||
void EmitTag(bool verbatim, const _Tag& tag);
|
||||
|
||||
void PrepareNode(EmitterNodeType::value child);
|
||||
void PrepareTopNode(EmitterNodeType::value child);
|
||||
void FlowSeqPrepareNode(EmitterNodeType::value child);
|
||||
void BlockSeqPrepareNode(EmitterNodeType::value child);
|
||||
|
||||
void FlowMapPrepareNode(EmitterNodeType::value child);
|
||||
|
||||
void FlowMapPrepareLongKey(EmitterNodeType::value child);
|
||||
void FlowMapPrepareLongKeyValue(EmitterNodeType::value child);
|
||||
void FlowMapPrepareSimpleKey(EmitterNodeType::value child);
|
||||
void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child);
|
||||
|
||||
void BlockMapPrepareNode(EmitterNodeType::value child);
|
||||
|
||||
void BlockMapPrepareLongKey(EmitterNodeType::value child);
|
||||
void BlockMapPrepareLongKeyValue(EmitterNodeType::value child);
|
||||
void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
|
||||
void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
|
||||
|
||||
void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
|
||||
|
||||
const char* ComputeFullBoolName(bool b) const;
|
||||
bool CanEmitNewline() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<EmitterState> m_pState;
|
||||
ostream_wrapper m_stream;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& Emitter::WriteIntegralType(T value) {
|
||||
if (!good())
|
||||
return *this;
|
||||
|
||||
PrepareNode(EmitterNodeType::Scalar);
|
||||
|
||||
std::stringstream stream;
|
||||
PrepareIntegralStream(stream);
|
||||
stream << value;
|
||||
m_stream << stream.str();
|
||||
|
||||
StartedScalar();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& Emitter::WriteStreamable(T value) {
|
||||
if (!good())
|
||||
return *this;
|
||||
|
||||
PrepareNode(EmitterNodeType::Scalar);
|
||||
|
||||
std::stringstream stream;
|
||||
SetStreamablePrecision<T>(stream);
|
||||
|
||||
bool special = false;
|
||||
if (std::is_floating_point<T>::value) {
|
||||
if ((std::numeric_limits<T>::has_quiet_NaN ||
|
||||
std::numeric_limits<T>::has_signaling_NaN) &&
|
||||
std::isnan(value)) {
|
||||
special = true;
|
||||
stream << ".nan";
|
||||
} else if (std::numeric_limits<T>::has_infinity) {
|
||||
if (value == std::numeric_limits<T>::infinity()) {
|
||||
special = true;
|
||||
stream << ".inf";
|
||||
} else if (value == -std::numeric_limits<T>::infinity()) {
|
||||
special = true;
|
||||
stream << "-.inf";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!special) {
|
||||
stream << value;
|
||||
}
|
||||
m_stream << stream.str();
|
||||
|
||||
StartedScalar();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
|
||||
stream.precision(static_cast<std::streamsize>(GetFloatPrecision()));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
|
||||
stream.precision(static_cast<std::streamsize>(GetDoublePrecision()));
|
||||
}
|
||||
|
||||
// overloads of insertion
|
||||
inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, bool v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, char v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, unsigned char v) {
|
||||
return emitter.Write(static_cast<char>(v));
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const _Alias& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const _Tag& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const _Comment& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const _Null& v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, const Binary& b) {
|
||||
return emitter.Write(b);
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, const char* v) {
|
||||
return emitter.Write(std::string(v));
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, int v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, unsigned int v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, short v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, unsigned short v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, long v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, unsigned long v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, long long v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, unsigned long long v) {
|
||||
return emitter.WriteIntegralType(v);
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, float v) {
|
||||
return emitter.WriteStreamable(v);
|
||||
}
|
||||
inline Emitter& operator<<(Emitter& emitter, double v) {
|
||||
return emitter.WriteStreamable(v);
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
|
||||
return emitter.SetLocalValue(value);
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
|
||||
return emitter.SetLocalIndent(indent);
|
||||
}
|
||||
|
||||
inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
|
||||
return emitter.SetLocalPrecision(precision);
|
||||
}
|
||||
} // namespace YAML
|
||||
|
||||
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
include/yaml-cpp/emitterdef.h
Normal file
16
include/yaml-cpp/emitterdef.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace YAML {
|
||||
struct EmitterNodeType {
|
||||
enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap };
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
137
include/yaml-cpp/emittermanip.h
Normal file
137
include/yaml-cpp/emittermanip.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
enum EMITTER_MANIP {
|
||||
// general manipulators
|
||||
Auto,
|
||||
TagByKind,
|
||||
Newline,
|
||||
|
||||
// output character set
|
||||
EmitNonAscii,
|
||||
EscapeNonAscii,
|
||||
|
||||
// string manipulators
|
||||
// Auto, // duplicate
|
||||
SingleQuoted,
|
||||
DoubleQuoted,
|
||||
Literal,
|
||||
|
||||
// bool manipulators
|
||||
YesNoBool, // yes, no
|
||||
TrueFalseBool, // true, false
|
||||
OnOffBool, // on, off
|
||||
UpperCase, // TRUE, N
|
||||
LowerCase, // f, yes
|
||||
CamelCase, // No, Off
|
||||
LongBool, // yes, On
|
||||
ShortBool, // y, t
|
||||
|
||||
// int manipulators
|
||||
Dec,
|
||||
Hex,
|
||||
Oct,
|
||||
|
||||
// document manipulators
|
||||
BeginDoc,
|
||||
EndDoc,
|
||||
|
||||
// sequence manipulators
|
||||
BeginSeq,
|
||||
EndSeq,
|
||||
Flow,
|
||||
Block,
|
||||
|
||||
// map manipulators
|
||||
BeginMap,
|
||||
EndMap,
|
||||
Key,
|
||||
Value,
|
||||
// Flow, // duplicate
|
||||
// Block, // duplicate
|
||||
// Auto, // duplicate
|
||||
LongKey
|
||||
};
|
||||
|
||||
struct _Indent {
|
||||
_Indent(int value_) : value(value_) {}
|
||||
int value;
|
||||
};
|
||||
|
||||
inline _Indent Indent(int value) { return _Indent(value); }
|
||||
|
||||
struct _Alias {
|
||||
_Alias(const std::string& content_) : content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Alias Alias(const std::string content) { return _Alias(content); }
|
||||
|
||||
struct _Anchor {
|
||||
_Anchor(const std::string& content_) : content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Anchor Anchor(const std::string content) { return _Anchor(content); }
|
||||
|
||||
struct _Tag {
|
||||
struct Type {
|
||||
enum value { Verbatim, PrimaryHandle, NamedHandle };
|
||||
};
|
||||
|
||||
explicit _Tag(const std::string& prefix_, const std::string& content_,
|
||||
Type::value type_)
|
||||
: prefix(prefix_), content(content_), type(type_) {}
|
||||
std::string prefix;
|
||||
std::string content;
|
||||
Type::value type;
|
||||
};
|
||||
|
||||
inline _Tag VerbatimTag(const std::string content) {
|
||||
return _Tag("", content, _Tag::Type::Verbatim);
|
||||
}
|
||||
|
||||
inline _Tag LocalTag(const std::string content) {
|
||||
return _Tag("", content, _Tag::Type::PrimaryHandle);
|
||||
}
|
||||
|
||||
inline _Tag LocalTag(const std::string& prefix, const std::string content) {
|
||||
return _Tag(prefix, content, _Tag::Type::NamedHandle);
|
||||
}
|
||||
|
||||
inline _Tag SecondaryTag(const std::string content) {
|
||||
return _Tag("", content, _Tag::Type::NamedHandle);
|
||||
}
|
||||
|
||||
struct _Comment {
|
||||
_Comment(const std::string& content_) : content(content_) {}
|
||||
std::string content;
|
||||
};
|
||||
|
||||
inline _Comment Comment(const std::string content) { return _Comment(content); }
|
||||
|
||||
struct _Precision {
|
||||
_Precision(int floatPrecision_, int doublePrecision_)
|
||||
: floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
|
||||
|
||||
int floatPrecision;
|
||||
int doublePrecision;
|
||||
};
|
||||
|
||||
inline _Precision FloatPrecision(int n) { return _Precision(n, -1); }
|
||||
|
||||
inline _Precision DoublePrecision(int n) { return _Precision(-1, n); }
|
||||
|
||||
inline _Precision Precision(int n) { return _Precision(n, n); }
|
||||
}
|
||||
|
||||
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
include/yaml-cpp/emitterstyle.h
Normal file
16
include/yaml-cpp/emitterstyle.h
Normal 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
|
45
include/yaml-cpp/eventhandler.h
Normal file
45
include/yaml-cpp/eventhandler.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
|
||||
class EventHandler {
|
||||
public:
|
||||
virtual ~EventHandler() {}
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark) = 0;
|
||||
virtual void OnDocumentEnd() = 0;
|
||||
|
||||
virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value) = 0;
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style) = 0;
|
||||
virtual void OnSequenceEnd() = 0;
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style) = 0;
|
||||
virtual void OnMapEnd() = 0;
|
||||
|
||||
virtual void OnAnchor(const Mark& /*mark*/,
|
||||
const std::string& /*anchor_name*/) {
|
||||
// empty default implementation for compatibility
|
||||
}
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
299
include/yaml-cpp/exceptions.h
Normal file
299
include/yaml-cpp/exceptions.h
Normal file
@@ -0,0 +1,299 @@
|
||||
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/traits.h"
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// This is here for compatibility with older versions of Visual Studio
|
||||
// which don't support noexcept
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define YAML_CPP_NOEXCEPT _NOEXCEPT
|
||||
#else
|
||||
#define YAML_CPP_NOEXCEPT noexcept
|
||||
#endif
|
||||
|
||||
namespace YAML {
|
||||
// error messages
|
||||
namespace ErrorMsg {
|
||||
const char* const YAML_DIRECTIVE_ARGS =
|
||||
"YAML directives must have exactly one argument";
|
||||
const char* const YAML_VERSION = "bad YAML version: ";
|
||||
const char* const YAML_MAJOR_VERSION = "YAML major version too large";
|
||||
const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive";
|
||||
const char* const TAG_DIRECTIVE_ARGS =
|
||||
"TAG directives must have exactly two arguments";
|
||||
const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
|
||||
const char* const CHAR_IN_TAG_HANDLE =
|
||||
"illegal character found while scanning tag handle";
|
||||
const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
|
||||
const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
|
||||
const char* const END_OF_MAP = "end of map not found";
|
||||
const char* const END_OF_MAP_FLOW = "end of map flow not found";
|
||||
const char* const END_OF_SEQ = "end of sequence not found";
|
||||
const char* const END_OF_SEQ_FLOW = "end of sequence flow not found";
|
||||
const char* const MULTIPLE_TAGS =
|
||||
"cannot assign multiple tags to the same node";
|
||||
const char* const MULTIPLE_ANCHORS =
|
||||
"cannot assign multiple anchors to the same node";
|
||||
const char* const MULTIPLE_ALIASES =
|
||||
"cannot assign multiple aliases to the same node";
|
||||
const char* const ALIAS_CONTENT =
|
||||
"aliases can't have any content, *including* tags";
|
||||
const char* const INVALID_HEX = "bad character found while scanning hex number";
|
||||
const char* const INVALID_UNICODE = "invalid unicode: ";
|
||||
const char* const INVALID_ESCAPE = "unknown escape character: ";
|
||||
const char* const UNKNOWN_TOKEN = "unknown token";
|
||||
const char* const DOC_IN_SCALAR = "illegal document indicator in scalar";
|
||||
const char* const EOF_IN_SCALAR = "illegal EOF in scalar";
|
||||
const char* const CHAR_IN_SCALAR = "illegal character in scalar";
|
||||
const char* const TAB_IN_INDENTATION =
|
||||
"illegal tab when looking for indentation";
|
||||
const char* const FLOW_END = "illegal flow end";
|
||||
const char* const BLOCK_ENTRY = "illegal block entry";
|
||||
const char* const MAP_KEY = "illegal map key";
|
||||
const char* const MAP_VALUE = "illegal map value";
|
||||
const char* const ALIAS_NOT_FOUND = "alias not found after *";
|
||||
const char* const ANCHOR_NOT_FOUND = "anchor not found after &";
|
||||
const char* const CHAR_IN_ALIAS =
|
||||
"illegal character found while scanning alias";
|
||||
const char* const CHAR_IN_ANCHOR =
|
||||
"illegal character found while scanning anchor";
|
||||
const char* const ZERO_INDENT_IN_BLOCK =
|
||||
"cannot set zero indentation for a block scalar";
|
||||
const char* const CHAR_IN_BLOCK = "unexpected character in block scalar";
|
||||
const char* const AMBIGUOUS_ANCHOR =
|
||||
"cannot assign the same alias to multiple nodes";
|
||||
const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
|
||||
|
||||
const char* const INVALID_NODE =
|
||||
"invalid node; this may result from using a map iterator as a sequence "
|
||||
"iterator, or vice-versa";
|
||||
const char* const INVALID_SCALAR = "invalid scalar";
|
||||
const char* const KEY_NOT_FOUND = "key not found";
|
||||
const char* const BAD_CONVERSION = "bad conversion";
|
||||
const char* const BAD_DEREFERENCE = "bad dereference";
|
||||
const char* const BAD_SUBSCRIPT = "operator[] call on a scalar";
|
||||
const char* const BAD_PUSHBACK = "appending to a non-sequence";
|
||||
const char* const BAD_INSERT = "inserting in a non-convertible-to-map";
|
||||
|
||||
const char* const UNMATCHED_GROUP_TAG = "unmatched group tag";
|
||||
const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token";
|
||||
const char* const UNEXPECTED_END_MAP = "unexpected end map token";
|
||||
const char* const SINGLE_QUOTED_CHAR =
|
||||
"invalid character in single-quoted string";
|
||||
const char* const INVALID_ANCHOR = "invalid anchor";
|
||||
const char* const INVALID_ALIAS = "invalid alias";
|
||||
const char* const INVALID_TAG = "invalid tag";
|
||||
const char* const BAD_FILE = "bad file";
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(
|
||||
const T&, typename disable_if<is_numeric<T>>::type* = 0) {
|
||||
return KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(
|
||||
const T& key, typename enable_if<is_numeric<T>>::type* = 0) {
|
||||
std::stringstream stream;
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
|
||||
const T&, typename disable_if<is_numeric<T>>::type* = nullptr) {
|
||||
return BAD_SUBSCRIPT;
|
||||
}
|
||||
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
|
||||
const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) {
|
||||
std::stringstream stream;
|
||||
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
if (key.empty()) {
|
||||
return INVALID_NODE;
|
||||
}
|
||||
stream << "invalid node; first invalid key: \"" << key << "\"";
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
class YAML_CPP_API Exception : public std::runtime_error {
|
||||
public:
|
||||
Exception(const Mark& mark_, const std::string& msg_)
|
||||
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
|
||||
virtual ~Exception() YAML_CPP_NOEXCEPT;
|
||||
|
||||
Exception(const Exception&) = default;
|
||||
|
||||
Mark mark;
|
||||
std::string msg;
|
||||
|
||||
private:
|
||||
static const std::string build_what(const Mark& mark,
|
||||
const std::string& msg) {
|
||||
if (mark.is_null()) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
std::stringstream output;
|
||||
output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
|
||||
<< mark.column + 1 << ": " << msg;
|
||||
return output.str();
|
||||
}
|
||||
};
|
||||
|
||||
class YAML_CPP_API ParserException : public Exception {
|
||||
public:
|
||||
ParserException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
ParserException(const ParserException&) = default;
|
||||
virtual ~ParserException() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API RepresentationException : public Exception {
|
||||
public:
|
||||
RepresentationException(const Mark& mark_, const std::string& msg_)
|
||||
: Exception(mark_, msg_) {}
|
||||
RepresentationException(const RepresentationException&) = default;
|
||||
virtual ~RepresentationException() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
// representation exceptions
|
||||
class YAML_CPP_API InvalidScalar : public RepresentationException {
|
||||
public:
|
||||
InvalidScalar(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
|
||||
InvalidScalar(const InvalidScalar&) = default;
|
||||
virtual ~InvalidScalar() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API KeyNotFound : public RepresentationException {
|
||||
public:
|
||||
template <typename T>
|
||||
KeyNotFound(const Mark& mark_, const T& key_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
|
||||
}
|
||||
KeyNotFound(const KeyNotFound&) = default;
|
||||
virtual ~KeyNotFound() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
|
||||
public:
|
||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
||||
: KeyNotFound(mark_, key_), key(key_) {}
|
||||
virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {}
|
||||
|
||||
T key;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
|
||||
const T& key) {
|
||||
return TypedKeyNotFound<T>(mark, key);
|
||||
}
|
||||
|
||||
class YAML_CPP_API InvalidNode : public RepresentationException {
|
||||
public:
|
||||
InvalidNode(std::string key)
|
||||
: RepresentationException(Mark::null_mark(),
|
||||
ErrorMsg::INVALID_NODE_WITH_KEY(key)) {}
|
||||
InvalidNode(const InvalidNode&) = default;
|
||||
virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadConversion : public RepresentationException {
|
||||
public:
|
||||
explicit BadConversion(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
|
||||
BadConversion(const BadConversion&) = default;
|
||||
virtual ~BadConversion() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypedBadConversion : public BadConversion {
|
||||
public:
|
||||
explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {}
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadDereference : public RepresentationException {
|
||||
public:
|
||||
BadDereference()
|
||||
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
|
||||
BadDereference(const BadDereference&) = default;
|
||||
virtual ~BadDereference() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadSubscript : public RepresentationException {
|
||||
public:
|
||||
template <typename Key>
|
||||
BadSubscript(const Key& key)
|
||||
: RepresentationException(Mark::null_mark(),
|
||||
ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {}
|
||||
BadSubscript(const BadSubscript&) = default;
|
||||
virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadPushback : public RepresentationException {
|
||||
public:
|
||||
BadPushback()
|
||||
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
|
||||
BadPushback(const BadPushback&) = default;
|
||||
virtual ~BadPushback() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadInsert : public RepresentationException {
|
||||
public:
|
||||
BadInsert()
|
||||
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
|
||||
BadInsert(const BadInsert&) = default;
|
||||
virtual ~BadInsert() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API EmitterException : public Exception {
|
||||
public:
|
||||
EmitterException(const std::string& msg_)
|
||||
: Exception(Mark::null_mark(), msg_) {}
|
||||
EmitterException(const EmitterException&) = default;
|
||||
virtual ~EmitterException() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
class YAML_CPP_API BadFile : public Exception {
|
||||
public:
|
||||
BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
|
||||
BadFile(const BadFile&) = default;
|
||||
virtual ~BadFile() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
}
|
||||
|
||||
#undef YAML_CPP_NOEXCEPT
|
||||
|
||||
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
29
include/yaml-cpp/mark.h
Normal file
29
include/yaml-cpp/mark.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
namespace YAML {
|
||||
struct YAML_CPP_API Mark {
|
||||
Mark() : pos(0), line(0), column(0) {}
|
||||
|
||||
static const Mark null_mark() { return Mark(-1, -1, -1); }
|
||||
|
||||
bool is_null() const { return pos == -1 && line == -1 && column == -1; }
|
||||
|
||||
int pos;
|
||||
int line, column;
|
||||
|
||||
private:
|
||||
Mark(int pos_, int line_, int column_)
|
||||
: pos(pos_), line(line_), column(column_) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
332
include/yaml-cpp/node/convert.h
Normal file
332
include/yaml-cpp/node/convert.h
Normal file
@@ -0,0 +1,332 @@
|
||||
#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/binary.h"
|
||||
#include "yaml-cpp/node/impl.h"
|
||||
#include "yaml-cpp/node/iterator.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
#include "yaml-cpp/null.h"
|
||||
|
||||
namespace YAML {
|
||||
class Binary;
|
||||
struct _Null;
|
||||
template <typename T>
|
||||
struct convert;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
namespace conversion {
|
||||
inline bool IsInfinity(const std::string& input) {
|
||||
return input == ".inf" || input == ".Inf" || input == ".INF" ||
|
||||
input == "+.inf" || input == "+.Inf" || input == "+.INF";
|
||||
}
|
||||
|
||||
inline bool IsNegativeInfinity(const std::string& input) {
|
||||
return input == "-.inf" || input == "-.Inf" || input == "-.INF";
|
||||
}
|
||||
|
||||
inline bool IsNaN(const std::string& input) {
|
||||
return input == ".nan" || input == ".NaN" || input == ".NAN";
|
||||
}
|
||||
}
|
||||
|
||||
// Node
|
||||
template <>
|
||||
struct convert<Node> {
|
||||
static Node encode(const Node& rhs) { return rhs; }
|
||||
|
||||
static bool decode(const Node& node, Node& rhs) {
|
||||
rhs.reset(node);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// std::string
|
||||
template <>
|
||||
struct convert<std::string> {
|
||||
static Node encode(const std::string& rhs) { return Node(rhs); }
|
||||
|
||||
static bool decode(const Node& node, std::string& rhs) {
|
||||
if (!node.IsScalar())
|
||||
return false;
|
||||
rhs = node.Scalar();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// C-strings can only be encoded
|
||||
template <>
|
||||
struct convert<const char*> {
|
||||
static Node encode(const char*& rhs) { return Node(rhs); }
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
struct convert<const char[N]> {
|
||||
static Node encode(const char(&rhs)[N]) { return Node(rhs); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct convert<_Null> {
|
||||
static Node encode(const _Null& /* rhs */) { return Node(); }
|
||||
|
||||
static bool decode(const Node& node, _Null& /* rhs */) {
|
||||
return node.IsNull();
|
||||
}
|
||||
};
|
||||
|
||||
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
|
||||
template <> \
|
||||
struct convert<type> { \
|
||||
static Node encode(const type& rhs) { \
|
||||
std::stringstream stream; \
|
||||
stream.precision(std::numeric_limits<type>::max_digits10); \
|
||||
stream << rhs; \
|
||||
return Node(stream.str()); \
|
||||
} \
|
||||
\
|
||||
static bool decode(const Node& node, type& rhs) { \
|
||||
if (node.Type() != NodeType::Scalar) \
|
||||
return false; \
|
||||
const std::string& input = node.Scalar(); \
|
||||
std::stringstream stream(input); \
|
||||
stream.unsetf(std::ios::dec); \
|
||||
if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
|
||||
return true; \
|
||||
if (std::numeric_limits<type>::has_infinity) { \
|
||||
if (conversion::IsInfinity(input)) { \
|
||||
rhs = std::numeric_limits<type>::infinity(); \
|
||||
return true; \
|
||||
} else if (conversion::IsNegativeInfinity(input)) { \
|
||||
rhs = negative_op std::numeric_limits<type>::infinity(); \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (std::numeric_limits<type>::has_quiet_NaN) { \
|
||||
if (conversion::IsNaN(input)) { \
|
||||
rhs = std::numeric_limits<type>::quiet_NaN(); \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
|
||||
YAML_DEFINE_CONVERT_STREAMABLE(type, -)
|
||||
|
||||
#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
|
||||
YAML_DEFINE_CONVERT_STREAMABLE(type, +)
|
||||
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
|
||||
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
|
||||
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
|
||||
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
|
||||
|
||||
#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
|
||||
#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
|
||||
#undef YAML_DEFINE_CONVERT_STREAMABLE
|
||||
|
||||
// bool
|
||||
template <>
|
||||
struct convert<bool> {
|
||||
static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
|
||||
|
||||
YAML_CPP_API static bool decode(const Node& node, bool& rhs);
|
||||
};
|
||||
|
||||
// std::map
|
||||
template <typename K, typename V>
|
||||
struct convert<std::map<K, V>> {
|
||||
static Node encode(const std::map<K, V>& rhs) {
|
||||
Node node(NodeType::Map);
|
||||
for (typename std::map<K, V>::const_iterator it = rhs.begin();
|
||||
it != rhs.end(); ++it)
|
||||
node.force_insert(it->first, it->second);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, std::map<K, V>& rhs) {
|
||||
if (!node.IsMap())
|
||||
return false;
|
||||
|
||||
rhs.clear();
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it)
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs[it->first.template as<K>()] = it->second.template as<V>();
|
||||
#else
|
||||
rhs[it->first.as<K>()] = it->second.as<V>();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// std::vector
|
||||
template <typename T>
|
||||
struct convert<std::vector<T>> {
|
||||
static Node encode(const std::vector<T>& rhs) {
|
||||
Node node(NodeType::Sequence);
|
||||
for (typename std::vector<T>::const_iterator it = rhs.begin();
|
||||
it != rhs.end(); ++it)
|
||||
node.push_back(*it);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, std::vector<T>& rhs) {
|
||||
if (!node.IsSequence())
|
||||
return false;
|
||||
|
||||
rhs.clear();
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it)
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs.push_back(it->template as<T>());
|
||||
#else
|
||||
rhs.push_back(it->as<T>());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// std::list
|
||||
template <typename T>
|
||||
struct convert<std::list<T>> {
|
||||
static Node encode(const std::list<T>& rhs) {
|
||||
Node node(NodeType::Sequence);
|
||||
for (typename std::list<T>::const_iterator it = rhs.begin();
|
||||
it != rhs.end(); ++it)
|
||||
node.push_back(*it);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, std::list<T>& rhs) {
|
||||
if (!node.IsSequence())
|
||||
return false;
|
||||
|
||||
rhs.clear();
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it)
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs.push_back(it->template as<T>());
|
||||
#else
|
||||
rhs.push_back(it->as<T>());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// std::array
|
||||
template <typename T, std::size_t N>
|
||||
struct convert<std::array<T, N>> {
|
||||
static Node encode(const std::array<T, N>& rhs) {
|
||||
Node node(NodeType::Sequence);
|
||||
for (const auto& element : rhs) {
|
||||
node.push_back(element);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, std::array<T, N>& rhs) {
|
||||
if (!isNodeValid(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < node.size(); ++i) {
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs[i] = node[i].template as<T>();
|
||||
#else
|
||||
rhs[i] = node[i].as<T>();
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool isNodeValid(const Node& node) {
|
||||
return node.IsSequence() && node.size() == N;
|
||||
}
|
||||
};
|
||||
|
||||
// std::pair
|
||||
template <typename T, typename U>
|
||||
struct convert<std::pair<T, U>> {
|
||||
static Node encode(const std::pair<T, U>& rhs) {
|
||||
Node node(NodeType::Sequence);
|
||||
node.push_back(rhs.first);
|
||||
node.push_back(rhs.second);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, std::pair<T, U>& rhs) {
|
||||
if (!node.IsSequence())
|
||||
return false;
|
||||
if (node.size() != 2)
|
||||
return false;
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs.first = node[0].template as<T>();
|
||||
#else
|
||||
rhs.first = node[0].as<T>();
|
||||
#endif
|
||||
#if defined(__GNUC__) && __GNUC__ < 4
|
||||
// workaround for GCC 3:
|
||||
rhs.second = node[1].template as<U>();
|
||||
#else
|
||||
rhs.second = node[1].as<U>();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// binary
|
||||
template <>
|
||||
struct convert<Binary> {
|
||||
static Node encode(const Binary& rhs) {
|
||||
return Node(EncodeBase64(rhs.data(), rhs.size()));
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, Binary& rhs) {
|
||||
if (!node.IsScalar())
|
||||
return false;
|
||||
|
||||
std::vector<unsigned char> data = DecodeBase64(node.Scalar());
|
||||
if (data.empty() && !node.Scalar().empty())
|
||||
return false;
|
||||
|
||||
rhs.swap(data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
26
include/yaml-cpp/node/detail/bool_type.h
Normal file
26
include/yaml-cpp/node/detail/bool_type.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
struct unspecified_bool {
|
||||
struct NOT_ALLOWED;
|
||||
static void true_value(NOT_ALLOWED*) {}
|
||||
};
|
||||
typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
|
||||
}
|
||||
}
|
||||
|
||||
#define YAML_CPP_OPERATOR_BOOL() \
|
||||
operator YAML::detail::unspecified_bool_type() const { \
|
||||
return this->operator!() ? 0 \
|
||||
: &YAML::detail::unspecified_bool::true_value; \
|
||||
}
|
||||
|
||||
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
218
include/yaml-cpp/node/detail/impl.h
Normal file
218
include/yaml-cpp/node/detail/impl.h
Normal file
@@ -0,0 +1,218 @@
|
||||
#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/node/detail/node.h"
|
||||
#include "yaml-cpp/node/detail/node_data.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
template <typename Key, typename Enable = void>
|
||||
struct get_idx {
|
||||
static node* get(const std::vector<node*>& /* sequence */,
|
||||
const Key& /* key */, shared_memory_holder /* pMemory */) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct get_idx<Key,
|
||||
typename std::enable_if<std::is_unsigned<Key>::value &&
|
||||
!std::is_same<Key, bool>::value>::type> {
|
||||
static node* get(const std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder /* pMemory */) {
|
||||
return key < sequence.size() ? sequence[key] : nullptr;
|
||||
}
|
||||
|
||||
static node* get(std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder pMemory) {
|
||||
if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
|
||||
return 0;
|
||||
if (key == sequence.size())
|
||||
sequence.push_back(&pMemory->create_node());
|
||||
return sequence[key];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
|
||||
static node* get(const std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder pMemory) {
|
||||
return key >= 0 ? get_idx<std::size_t>::get(
|
||||
sequence, static_cast<std::size_t>(key), pMemory)
|
||||
: nullptr;
|
||||
}
|
||||
static node* get(std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder pMemory) {
|
||||
return key >= 0 ? get_idx<std::size_t>::get(
|
||||
sequence, static_cast<std::size_t>(key), pMemory)
|
||||
: nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key, typename Enable = void>
|
||||
struct remove_idx {
|
||||
static bool remove(std::vector<node*>&, const Key&) { return false; }
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct remove_idx<
|
||||
Key, typename std::enable_if<std::is_unsigned<Key>::value &&
|
||||
!std::is_same<Key, bool>::value>::type> {
|
||||
|
||||
static bool remove(std::vector<node*>& sequence, const Key& key) {
|
||||
if (key >= sequence.size()) {
|
||||
return false;
|
||||
} else {
|
||||
sequence.erase(sequence.begin() + key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct remove_idx<Key,
|
||||
typename std::enable_if<std::is_signed<Key>::value>::type> {
|
||||
|
||||
static bool remove(std::vector<node*>& sequence, const Key& key) {
|
||||
return key >= 0 ? remove_idx<std::size_t>::remove(
|
||||
sequence, static_cast<std::size_t>(key))
|
||||
: false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
|
||||
T lhs;
|
||||
if (convert<T>::decode(Node(*this, pMemory), lhs)) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
|
||||
return equals<std::string>(rhs, pMemory);
|
||||
}
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
inline node* node_data::get(const Key& key,
|
||||
shared_memory_holder pMemory) const {
|
||||
switch (m_type) {
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
return nullptr;
|
||||
case NodeType::Sequence:
|
||||
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
|
||||
return pNode;
|
||||
return nullptr;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
if (it->first->equals(key, pMemory)) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
|
||||
switch (m_type) {
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
case NodeType::Sequence:
|
||||
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
|
||||
m_type = NodeType::Sequence;
|
||||
return *pNode;
|
||||
}
|
||||
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
if (it->first->equals(key, pMemory)) {
|
||||
return *it->second;
|
||||
}
|
||||
}
|
||||
|
||||
node& k = convert_to_node(key, pMemory);
|
||||
node& v = pMemory->create_node();
|
||||
insert_map_pair(k, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
|
||||
if (m_type == NodeType::Sequence) {
|
||||
return remove_idx<Key>::remove(m_sequence, key);
|
||||
} else if (m_type == NodeType::Map) {
|
||||
kv_pairs::iterator it = m_undefinedPairs.begin();
|
||||
while (it != m_undefinedPairs.end()) {
|
||||
kv_pairs::iterator jt = std::next(it);
|
||||
if (it->first->equals(key, pMemory)) {
|
||||
m_undefinedPairs.erase(it);
|
||||
}
|
||||
it = jt;
|
||||
}
|
||||
|
||||
for (node_map::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) {
|
||||
if (iter->first->equals(key, pMemory)) {
|
||||
m_map.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
inline void node_data::force_insert(const Key& key, const Value& value,
|
||||
shared_memory_holder pMemory) {
|
||||
switch (m_type) {
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
case NodeType::Sequence:
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadInsert();
|
||||
}
|
||||
|
||||
node& k = convert_to_node(key, pMemory);
|
||||
node& v = convert_to_node(value, pMemory);
|
||||
insert_map_pair(k, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline node& node_data::convert_to_node(const T& rhs,
|
||||
shared_memory_holder pMemory) {
|
||||
Node value = convert<T>::encode(rhs);
|
||||
value.EnsureNodeExists();
|
||||
pMemory->merge(*value.m_pMemory);
|
||||
return *value.m_pNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
96
include/yaml-cpp/node/detail/iterator.h
Normal file
96
include/yaml-cpp/node/detail/iterator.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/detail/node_iterator.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
struct iterator_value;
|
||||
|
||||
template <typename V>
|
||||
class iterator_base {
|
||||
|
||||
private:
|
||||
template <typename>
|
||||
friend class iterator_base;
|
||||
struct enabler {};
|
||||
typedef node_iterator base_type;
|
||||
|
||||
struct proxy {
|
||||
explicit proxy(const V& x) : m_ref(x) {}
|
||||
V* operator->() { return std::addressof(m_ref); }
|
||||
operator V*() { return std::addressof(m_ref); }
|
||||
|
||||
V m_ref;
|
||||
};
|
||||
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = V;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = V*;
|
||||
using reference = V;
|
||||
|
||||
public:
|
||||
iterator_base() : m_iterator(), m_pMemory() {}
|
||||
explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
|
||||
: m_iterator(rhs), m_pMemory(pMemory) {}
|
||||
|
||||
template <class W>
|
||||
iterator_base(const iterator_base<W>& rhs,
|
||||
typename std::enable_if<std::is_convertible<W*, V*>::value,
|
||||
enabler>::type = enabler())
|
||||
: m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {}
|
||||
|
||||
iterator_base<V>& operator++() {
|
||||
++m_iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator_base<V> operator++(int) {
|
||||
iterator_base<V> iterator_pre(*this);
|
||||
++(*this);
|
||||
return iterator_pre;
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
bool operator==(const iterator_base<W>& rhs) const {
|
||||
return m_iterator == rhs.m_iterator;
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
bool operator!=(const iterator_base<W>& rhs) const {
|
||||
return m_iterator != rhs.m_iterator;
|
||||
}
|
||||
|
||||
value_type operator*() const {
|
||||
const typename base_type::value_type& v = *m_iterator;
|
||||
if (v.pNode)
|
||||
return value_type(Node(*v, m_pMemory));
|
||||
if (v.first && v.second)
|
||||
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
|
||||
return value_type();
|
||||
}
|
||||
|
||||
proxy operator->() const { return proxy(**this); }
|
||||
|
||||
private:
|
||||
base_type m_iterator;
|
||||
shared_memory_holder m_pMemory;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
27
include/yaml-cpp/node/detail/iterator_fwd.h
Normal file
27
include/yaml-cpp/node/detail/iterator_fwd.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML {
|
||||
|
||||
namespace detail {
|
||||
struct iterator_value;
|
||||
template <typename V>
|
||||
class iterator_base;
|
||||
}
|
||||
|
||||
typedef detail::iterator_base<detail::iterator_value> iterator;
|
||||
typedef detail::iterator_base<const detail::iterator_value> const_iterator;
|
||||
}
|
||||
|
||||
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
47
include/yaml-cpp/node/detail/memory.h
Normal file
47
include/yaml-cpp/node/detail/memory.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class YAML_CPP_API memory {
|
||||
public:
|
||||
memory() : m_nodes{} {}
|
||||
node& create_node();
|
||||
void merge(const memory& rhs);
|
||||
|
||||
private:
|
||||
typedef std::set<shared_node> Nodes;
|
||||
Nodes m_nodes;
|
||||
};
|
||||
|
||||
class YAML_CPP_API memory_holder {
|
||||
public:
|
||||
memory_holder() : m_pMemory(new memory) {}
|
||||
|
||||
node& create_node() { return m_pMemory->create_node(); }
|
||||
void merge(memory_holder& rhs);
|
||||
|
||||
private:
|
||||
shared_memory m_pMemory;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
169
include/yaml-cpp/node/detail/node.h
Normal file
169
include/yaml-cpp/node/detail/node.h
Normal file
@@ -0,0 +1,169 @@
|
||||
#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/node/detail/node_ref.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
#include <set>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node {
|
||||
public:
|
||||
node() : m_pRef(new node_ref), m_dependencies{} {}
|
||||
node(const node&) = delete;
|
||||
node& operator=(const node&) = delete;
|
||||
|
||||
bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
|
||||
const node_ref* ref() const { return m_pRef.get(); }
|
||||
|
||||
bool is_defined() const { return m_pRef->is_defined(); }
|
||||
const Mark& mark() const { return m_pRef->mark(); }
|
||||
NodeType::value type() const { return m_pRef->type(); }
|
||||
|
||||
const std::string& scalar() const { return m_pRef->scalar(); }
|
||||
const std::string& tag() const { return m_pRef->tag(); }
|
||||
EmitterStyle::value style() const { return m_pRef->style(); }
|
||||
|
||||
template <typename T>
|
||||
bool equals(const T& rhs, shared_memory_holder pMemory);
|
||||
bool equals(const char* rhs, shared_memory_holder pMemory);
|
||||
|
||||
void mark_defined() {
|
||||
if (is_defined())
|
||||
return;
|
||||
|
||||
m_pRef->mark_defined();
|
||||
for (nodes::iterator it = m_dependencies.begin();
|
||||
it != m_dependencies.end(); ++it)
|
||||
(*it)->mark_defined();
|
||||
m_dependencies.clear();
|
||||
}
|
||||
|
||||
void add_dependency(node& rhs) {
|
||||
if (is_defined())
|
||||
rhs.mark_defined();
|
||||
else
|
||||
m_dependencies.insert(&rhs);
|
||||
}
|
||||
|
||||
void set_ref(const node& rhs) {
|
||||
if (rhs.is_defined())
|
||||
mark_defined();
|
||||
m_pRef = rhs.m_pRef;
|
||||
}
|
||||
void set_data(const node& rhs) {
|
||||
if (rhs.is_defined())
|
||||
mark_defined();
|
||||
m_pRef->set_data(*rhs.m_pRef);
|
||||
}
|
||||
|
||||
void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
|
||||
|
||||
void set_type(NodeType::value type) {
|
||||
if (type != NodeType::Undefined)
|
||||
mark_defined();
|
||||
m_pRef->set_type(type);
|
||||
}
|
||||
void set_null() {
|
||||
mark_defined();
|
||||
m_pRef->set_null();
|
||||
}
|
||||
void set_scalar(const std::string& scalar) {
|
||||
mark_defined();
|
||||
m_pRef->set_scalar(scalar);
|
||||
}
|
||||
void set_tag(const std::string& tag) {
|
||||
mark_defined();
|
||||
m_pRef->set_tag(tag);
|
||||
}
|
||||
|
||||
// style
|
||||
void set_style(EmitterStyle::value style) {
|
||||
mark_defined();
|
||||
m_pRef->set_style(style);
|
||||
}
|
||||
|
||||
// size/iterator
|
||||
std::size_t size() const { return m_pRef->size(); }
|
||||
|
||||
const_node_iterator begin() const {
|
||||
return static_cast<const node_ref&>(*m_pRef).begin();
|
||||
}
|
||||
node_iterator begin() { return m_pRef->begin(); }
|
||||
|
||||
const_node_iterator end() const {
|
||||
return static_cast<const node_ref&>(*m_pRef).end();
|
||||
}
|
||||
node_iterator end() { return m_pRef->end(); }
|
||||
|
||||
// sequence
|
||||
void push_back(node& input, shared_memory_holder pMemory) {
|
||||
m_pRef->push_back(input, pMemory);
|
||||
input.add_dependency(*this);
|
||||
}
|
||||
void insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||
m_pRef->insert(key, value, pMemory);
|
||||
key.add_dependency(*this);
|
||||
value.add_dependency(*this);
|
||||
}
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
node* get(const Key& key, shared_memory_holder pMemory) const {
|
||||
// NOTE: this returns a non-const node so that the top-level Node can wrap
|
||||
// it, and returns a pointer so that it can be NULL (if there is no such
|
||||
// key).
|
||||
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
|
||||
}
|
||||
template <typename Key>
|
||||
node& get(const Key& key, shared_memory_holder pMemory) {
|
||||
node& value = m_pRef->get(key, pMemory);
|
||||
value.add_dependency(*this);
|
||||
return value;
|
||||
}
|
||||
template <typename Key>
|
||||
bool remove(const Key& key, shared_memory_holder pMemory) {
|
||||
return m_pRef->remove(key, pMemory);
|
||||
}
|
||||
|
||||
node* get(node& key, shared_memory_holder pMemory) const {
|
||||
// NOTE: this returns a non-const node so that the top-level Node can wrap
|
||||
// it, and returns a pointer so that it can be NULL (if there is no such
|
||||
// key).
|
||||
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
|
||||
}
|
||||
node& get(node& key, shared_memory_holder pMemory) {
|
||||
node& value = m_pRef->get(key, pMemory);
|
||||
key.add_dependency(*this);
|
||||
value.add_dependency(*this);
|
||||
return value;
|
||||
}
|
||||
bool remove(node& key, shared_memory_holder pMemory) {
|
||||
return m_pRef->remove(key, pMemory);
|
||||
}
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
void force_insert(const Key& key, const Value& value,
|
||||
shared_memory_holder pMemory) {
|
||||
m_pRef->force_insert(key, value, pMemory);
|
||||
}
|
||||
|
||||
private:
|
||||
shared_node_ref m_pRef;
|
||||
typedef std::set<node*> nodes;
|
||||
nodes m_dependencies;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
127
include/yaml-cpp/node/detail/node_data.h
Normal file
127
include/yaml-cpp/node/detail/node_data.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/detail/node_iterator.h"
|
||||
#include "yaml-cpp/node/iterator.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class YAML_CPP_API node_data {
|
||||
public:
|
||||
node_data();
|
||||
node_data(const node_data&) = delete;
|
||||
node_data& operator=(const node_data&) = delete;
|
||||
|
||||
void mark_defined();
|
||||
void set_mark(const Mark& mark);
|
||||
void set_type(NodeType::value type);
|
||||
void set_tag(const std::string& tag);
|
||||
void set_null();
|
||||
void set_scalar(const std::string& scalar);
|
||||
void set_style(EmitterStyle::value style);
|
||||
|
||||
bool is_defined() const { return m_isDefined; }
|
||||
const Mark& mark() const { return m_mark; }
|
||||
NodeType::value type() const {
|
||||
return m_isDefined ? m_type : NodeType::Undefined;
|
||||
}
|
||||
const std::string& scalar() const { return m_scalar; }
|
||||
const std::string& tag() const { return m_tag; }
|
||||
EmitterStyle::value style() const { return m_style; }
|
||||
|
||||
// size/iterator
|
||||
std::size_t size() const;
|
||||
|
||||
const_node_iterator begin() const;
|
||||
node_iterator begin();
|
||||
|
||||
const_node_iterator end() const;
|
||||
node_iterator end();
|
||||
|
||||
// sequence
|
||||
void push_back(node& node, shared_memory_holder pMemory);
|
||||
void insert(node& key, node& value, shared_memory_holder pMemory);
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
node* get(const Key& key, shared_memory_holder pMemory) const;
|
||||
template <typename Key>
|
||||
node& get(const Key& key, shared_memory_holder pMemory);
|
||||
template <typename Key>
|
||||
bool remove(const Key& key, shared_memory_holder pMemory);
|
||||
|
||||
node* get(node& key, shared_memory_holder pMemory) const;
|
||||
node& get(node& key, shared_memory_holder pMemory);
|
||||
bool remove(node& key, shared_memory_holder pMemory);
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
void force_insert(const Key& key, const Value& value,
|
||||
shared_memory_holder pMemory);
|
||||
|
||||
public:
|
||||
static const std::string& empty_scalar();
|
||||
|
||||
private:
|
||||
void compute_seq_size() const;
|
||||
void compute_map_size() const;
|
||||
|
||||
void reset_sequence();
|
||||
void reset_map();
|
||||
|
||||
void insert_map_pair(node& key, node& value);
|
||||
void convert_to_map(shared_memory_holder pMemory);
|
||||
void convert_sequence_to_map(shared_memory_holder pMemory);
|
||||
|
||||
template <typename T>
|
||||
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
|
||||
|
||||
private:
|
||||
bool m_isDefined;
|
||||
Mark m_mark;
|
||||
NodeType::value m_type;
|
||||
std::string m_tag;
|
||||
EmitterStyle::value m_style;
|
||||
|
||||
// scalar
|
||||
std::string m_scalar;
|
||||
|
||||
// sequence
|
||||
typedef std::vector<node*> node_seq;
|
||||
node_seq m_sequence;
|
||||
|
||||
mutable std::size_t m_seqSize;
|
||||
|
||||
// map
|
||||
typedef std::vector<std::pair<node*, node*>> node_map;
|
||||
node_map m_map;
|
||||
|
||||
typedef std::pair<node*, node*> kv_pair;
|
||||
typedef std::list<kv_pair> kv_pairs;
|
||||
mutable kv_pairs m_undefinedPairs;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
180
include/yaml-cpp/node/detail/node_iterator.h
Normal file
180
include/yaml-cpp/node/detail/node_iterator.h
Normal file
@@ -0,0 +1,180 @@
|
||||
#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
struct iterator_type {
|
||||
enum value { NoneType, Sequence, Map };
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct node_iterator_value : public std::pair<V*, V*> {
|
||||
typedef std::pair<V*, V*> kv;
|
||||
|
||||
node_iterator_value() : kv(), pNode(nullptr) {}
|
||||
explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
|
||||
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
|
||||
|
||||
V& operator*() const { return *pNode; }
|
||||
V& operator->() const { return *pNode; }
|
||||
|
||||
V* pNode;
|
||||
};
|
||||
|
||||
typedef std::vector<node*> node_seq;
|
||||
typedef std::vector<std::pair<node*, node*>> node_map;
|
||||
|
||||
template <typename V>
|
||||
struct node_iterator_type {
|
||||
typedef node_seq::iterator seq;
|
||||
typedef node_map::iterator map;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct node_iterator_type<const V> {
|
||||
typedef node_seq::const_iterator seq;
|
||||
typedef node_map::const_iterator map;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
class node_iterator_base
|
||||
: public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
|
||||
std::ptrdiff_t, node_iterator_value<V>*,
|
||||
node_iterator_value<V>> {
|
||||
private:
|
||||
struct enabler {};
|
||||
|
||||
struct proxy {
|
||||
explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
|
||||
node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
|
||||
operator node_iterator_value<V>*() { return std::addressof(m_ref); }
|
||||
|
||||
node_iterator_value<V> m_ref;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef typename node_iterator_type<V>::seq SeqIter;
|
||||
typedef typename node_iterator_type<V>::map MapIter;
|
||||
typedef node_iterator_value<V> value_type;
|
||||
|
||||
node_iterator_base()
|
||||
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
|
||||
explicit node_iterator_base(SeqIter seqIt)
|
||||
: m_type(iterator_type::Sequence),
|
||||
m_seqIt(seqIt),
|
||||
m_mapIt(),
|
||||
m_mapEnd() {}
|
||||
explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
|
||||
: m_type(iterator_type::Map),
|
||||
m_seqIt(),
|
||||
m_mapIt(mapIt),
|
||||
m_mapEnd(mapEnd) {
|
||||
m_mapIt = increment_until_defined(m_mapIt);
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
node_iterator_base(const node_iterator_base<W>& rhs,
|
||||
typename std::enable_if<std::is_convertible<W*, V*>::value,
|
||||
enabler>::type = enabler())
|
||||
: m_type(rhs.m_type),
|
||||
m_seqIt(rhs.m_seqIt),
|
||||
m_mapIt(rhs.m_mapIt),
|
||||
m_mapEnd(rhs.m_mapEnd) {}
|
||||
|
||||
template <typename>
|
||||
friend class node_iterator_base;
|
||||
|
||||
template <typename W>
|
||||
bool operator==(const node_iterator_base<W>& rhs) const {
|
||||
if (m_type != rhs.m_type)
|
||||
return false;
|
||||
|
||||
switch (m_type) {
|
||||
case iterator_type::NoneType:
|
||||
return true;
|
||||
case iterator_type::Sequence:
|
||||
return m_seqIt == rhs.m_seqIt;
|
||||
case iterator_type::Map:
|
||||
return m_mapIt == rhs.m_mapIt;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
bool operator!=(const node_iterator_base<W>& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
node_iterator_base<V>& operator++() {
|
||||
switch (m_type) {
|
||||
case iterator_type::NoneType:
|
||||
break;
|
||||
case iterator_type::Sequence:
|
||||
++m_seqIt;
|
||||
break;
|
||||
case iterator_type::Map:
|
||||
++m_mapIt;
|
||||
m_mapIt = increment_until_defined(m_mapIt);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
node_iterator_base<V> operator++(int) {
|
||||
node_iterator_base<V> iterator_pre(*this);
|
||||
++(*this);
|
||||
return iterator_pre;
|
||||
}
|
||||
|
||||
value_type operator*() const {
|
||||
switch (m_type) {
|
||||
case iterator_type::NoneType:
|
||||
return value_type();
|
||||
case iterator_type::Sequence:
|
||||
return value_type(**m_seqIt);
|
||||
case iterator_type::Map:
|
||||
return value_type(*m_mapIt->first, *m_mapIt->second);
|
||||
}
|
||||
return value_type();
|
||||
}
|
||||
|
||||
proxy operator->() const { return proxy(**this); }
|
||||
|
||||
MapIter increment_until_defined(MapIter it) {
|
||||
while (it != m_mapEnd && !is_defined(it))
|
||||
++it;
|
||||
return it;
|
||||
}
|
||||
|
||||
bool is_defined(MapIter it) const {
|
||||
return it->first->is_defined() && it->second->is_defined();
|
||||
}
|
||||
|
||||
private:
|
||||
typename iterator_type::value m_type;
|
||||
|
||||
SeqIter m_seqIt;
|
||||
MapIter m_mapIt, m_mapEnd;
|
||||
};
|
||||
|
||||
typedef node_iterator_base<node> node_iterator;
|
||||
typedef node_iterator_base<const node> const_node_iterator;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
98
include/yaml-cpp/node/detail/node_ref.h
Normal file
98
include/yaml-cpp/node/detail/node_ref.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/detail/node_data.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node_ref {
|
||||
public:
|
||||
node_ref() : m_pData(new node_data) {}
|
||||
node_ref(const node_ref&) = delete;
|
||||
node_ref& operator=(const node_ref&) = delete;
|
||||
|
||||
bool is_defined() const { return m_pData->is_defined(); }
|
||||
const Mark& mark() const { return m_pData->mark(); }
|
||||
NodeType::value type() const { return m_pData->type(); }
|
||||
const std::string& scalar() const { return m_pData->scalar(); }
|
||||
const std::string& tag() const { return m_pData->tag(); }
|
||||
EmitterStyle::value style() const { return m_pData->style(); }
|
||||
|
||||
void mark_defined() { m_pData->mark_defined(); }
|
||||
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
|
||||
|
||||
void set_mark(const Mark& mark) { m_pData->set_mark(mark); }
|
||||
void set_type(NodeType::value type) { m_pData->set_type(type); }
|
||||
void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
|
||||
void set_null() { m_pData->set_null(); }
|
||||
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
|
||||
void set_style(EmitterStyle::value style) { m_pData->set_style(style); }
|
||||
|
||||
// size/iterator
|
||||
std::size_t size() const { return m_pData->size(); }
|
||||
|
||||
const_node_iterator begin() const {
|
||||
return static_cast<const node_data&>(*m_pData).begin();
|
||||
}
|
||||
node_iterator begin() { return m_pData->begin(); }
|
||||
|
||||
const_node_iterator end() const {
|
||||
return static_cast<const node_data&>(*m_pData).end();
|
||||
}
|
||||
node_iterator end() { return m_pData->end(); }
|
||||
|
||||
// sequence
|
||||
void push_back(node& node, shared_memory_holder pMemory) {
|
||||
m_pData->push_back(node, pMemory);
|
||||
}
|
||||
void insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||
m_pData->insert(key, value, pMemory);
|
||||
}
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
node* get(const Key& key, shared_memory_holder pMemory) const {
|
||||
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
|
||||
}
|
||||
template <typename Key>
|
||||
node& get(const Key& key, shared_memory_holder pMemory) {
|
||||
return m_pData->get(key, pMemory);
|
||||
}
|
||||
template <typename Key>
|
||||
bool remove(const Key& key, shared_memory_holder pMemory) {
|
||||
return m_pData->remove(key, pMemory);
|
||||
}
|
||||
|
||||
node* get(node& key, shared_memory_holder pMemory) const {
|
||||
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
|
||||
}
|
||||
node& get(node& key, shared_memory_holder pMemory) {
|
||||
return m_pData->get(key, pMemory);
|
||||
}
|
||||
bool remove(node& key, shared_memory_holder pMemory) {
|
||||
return m_pData->remove(key, pMemory);
|
||||
}
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
void force_insert(const Key& key, const Value& value,
|
||||
shared_memory_holder pMemory) {
|
||||
m_pData->force_insert(key, value, pMemory);
|
||||
}
|
||||
|
||||
private:
|
||||
shared_node_data m_pData;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
32
include/yaml-cpp/node/emit.h
Normal file
32
include/yaml-cpp/node/emit.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
namespace YAML {
|
||||
class Emitter;
|
||||
class Node;
|
||||
|
||||
/**
|
||||
* Emits the node to the given {@link Emitter}. If there is an error in writing,
|
||||
* {@link Emitter#good} will return false.
|
||||
*/
|
||||
YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node);
|
||||
|
||||
/** Emits the node to the given output stream. */
|
||||
YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node);
|
||||
|
||||
/** Converts the node to a YAML string. */
|
||||
YAML_CPP_API std::string Dump(const Node& node);
|
||||
} // namespace YAML
|
||||
|
||||
#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
463
include/yaml-cpp/node/impl.h
Normal file
463
include/yaml-cpp/node/impl.h
Normal file
@@ -0,0 +1,463 @@
|
||||
#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
#include "yaml-cpp/node/detail/node.h"
|
||||
#include "yaml-cpp/node/iterator.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
inline Node::Node()
|
||||
: m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(NodeType::value type)
|
||||
: m_isValid(true),
|
||||
m_invalidKey{},
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
m_pNode->set_type(type);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Node::Node(const T& rhs)
|
||||
: m_isValid(true),
|
||||
m_invalidKey{},
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
Assign(rhs);
|
||||
}
|
||||
|
||||
inline Node::Node(const detail::iterator_value& rhs)
|
||||
: m_isValid(rhs.m_isValid),
|
||||
m_invalidKey(rhs.m_invalidKey),
|
||||
m_pMemory(rhs.m_pMemory),
|
||||
m_pNode(rhs.m_pNode) {}
|
||||
|
||||
inline Node::Node(const Node& rhs)
|
||||
: m_isValid(rhs.m_isValid),
|
||||
m_invalidKey(rhs.m_invalidKey),
|
||||
m_pMemory(rhs.m_pMemory),
|
||||
m_pNode(rhs.m_pNode) {}
|
||||
|
||||
inline Node::Node(Zombie)
|
||||
: m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(Zombie, const std::string& key)
|
||||
: m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
|
||||
: m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
|
||||
|
||||
inline Node::~Node() {}
|
||||
|
||||
inline void Node::EnsureNodeExists() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (!m_pNode) {
|
||||
m_pMemory.reset(new detail::memory_holder);
|
||||
m_pNode = &m_pMemory->create_node();
|
||||
m_pNode->set_null();
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Node::IsDefined() const {
|
||||
if (!m_isValid) {
|
||||
return false;
|
||||
}
|
||||
return m_pNode ? m_pNode->is_defined() : true;
|
||||
}
|
||||
|
||||
inline Mark Node::Mark() const {
|
||||
if (!m_isValid) {
|
||||
throw InvalidNode(m_invalidKey);
|
||||
}
|
||||
return m_pNode ? m_pNode->mark() : Mark::null_mark();
|
||||
}
|
||||
|
||||
inline NodeType::value Node::Type() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->type() : NodeType::Null;
|
||||
}
|
||||
|
||||
// access
|
||||
|
||||
// template helpers
|
||||
template <typename T, typename S>
|
||||
struct as_if {
|
||||
explicit as_if(const Node& node_) : node(node_) {}
|
||||
const Node& node;
|
||||
|
||||
T operator()(const S& fallback) const {
|
||||
if (!node.m_pNode)
|
||||
return fallback;
|
||||
|
||||
T t;
|
||||
if (convert<T>::decode(node, t))
|
||||
return t;
|
||||
return fallback;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct as_if<std::string, S> {
|
||||
explicit as_if(const Node& node_) : node(node_) {}
|
||||
const Node& node;
|
||||
|
||||
std::string operator()(const S& fallback) const {
|
||||
if (node.Type() != NodeType::Scalar)
|
||||
return fallback;
|
||||
return node.Scalar();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct as_if<T, void> {
|
||||
explicit as_if(const Node& node_) : node(node_) {}
|
||||
const Node& node;
|
||||
|
||||
T operator()() const {
|
||||
if (!node.m_pNode)
|
||||
throw TypedBadConversion<T>(node.Mark());
|
||||
|
||||
T t;
|
||||
if (convert<T>::decode(node, t))
|
||||
return t;
|
||||
throw TypedBadConversion<T>(node.Mark());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct as_if<std::string, void> {
|
||||
explicit as_if(const Node& node_) : node(node_) {}
|
||||
const Node& node;
|
||||
|
||||
std::string operator()() const {
|
||||
if (node.Type() != NodeType::Scalar)
|
||||
throw TypedBadConversion<std::string>(node.Mark());
|
||||
return node.Scalar();
|
||||
}
|
||||
};
|
||||
|
||||
// access functions
|
||||
template <typename T>
|
||||
inline T Node::as() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return as_if<T, void>(*this)();
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
inline T Node::as(const S& fallback) const {
|
||||
if (!m_isValid)
|
||||
return fallback;
|
||||
return as_if<T, S>(*this)(fallback);
|
||||
}
|
||||
|
||||
inline const std::string& Node::Scalar() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
|
||||
}
|
||||
|
||||
inline const std::string& Node::Tag() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
|
||||
}
|
||||
|
||||
inline void Node::SetTag(const std::string& tag) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_tag(tag);
|
||||
}
|
||||
|
||||
inline EmitterStyle::value Node::Style() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
|
||||
}
|
||||
|
||||
inline void Node::SetStyle(EmitterStyle::value style) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_style(style);
|
||||
}
|
||||
|
||||
// assignment
|
||||
inline bool Node::is(const Node& rhs) const {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (!m_pNode || !rhs.m_pNode)
|
||||
return false;
|
||||
return m_pNode->is(*rhs.m_pNode);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Node& Node::operator=(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
Assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Node& Node::operator=(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (is(rhs))
|
||||
return *this;
|
||||
AssignNode(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Node::reset(const YAML::Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
m_pMemory = rhs.m_pMemory;
|
||||
m_pNode = rhs.m_pNode;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void Node::Assign(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
AssignData(convert<T>::encode(rhs));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Node::Assign(const std::string& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::Assign(const char* rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::Assign(char* rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::AssignData(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
m_pNode->set_data(*rhs.m_pNode);
|
||||
m_pMemory->merge(*rhs.m_pMemory);
|
||||
}
|
||||
|
||||
inline void Node::AssignNode(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
if (!m_pNode) {
|
||||
m_pNode = rhs.m_pNode;
|
||||
m_pMemory = rhs.m_pMemory;
|
||||
return;
|
||||
}
|
||||
|
||||
m_pNode->set_ref(*rhs.m_pNode);
|
||||
m_pMemory->merge(*rhs.m_pMemory);
|
||||
m_pNode = rhs.m_pNode;
|
||||
}
|
||||
|
||||
// size/iterator
|
||||
inline std::size_t Node::size() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->size() : 0;
|
||||
}
|
||||
|
||||
inline const_iterator Node::begin() const {
|
||||
if (!m_isValid)
|
||||
return const_iterator();
|
||||
return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
|
||||
: const_iterator();
|
||||
}
|
||||
|
||||
inline iterator Node::begin() {
|
||||
if (!m_isValid)
|
||||
return iterator();
|
||||
return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
|
||||
}
|
||||
|
||||
inline const_iterator Node::end() const {
|
||||
if (!m_isValid)
|
||||
return const_iterator();
|
||||
return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
|
||||
}
|
||||
|
||||
inline iterator Node::end() {
|
||||
if (!m_isValid)
|
||||
return iterator();
|
||||
return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
|
||||
}
|
||||
|
||||
// sequence
|
||||
template <typename T>
|
||||
inline void Node::push_back(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
push_back(Node(rhs));
|
||||
}
|
||||
|
||||
inline void Node::push_back(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
m_pNode->push_back(*rhs.m_pNode, m_pMemory);
|
||||
m_pMemory->merge(*rhs.m_pMemory);
|
||||
}
|
||||
|
||||
// helpers for indexing
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct to_value_t {
|
||||
explicit to_value_t(const T& t_) : t(t_) {}
|
||||
const T& t;
|
||||
typedef const T& return_type;
|
||||
|
||||
const T& operator()() const { return t; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct to_value_t<const char*> {
|
||||
explicit to_value_t(const char* t_) : t(t_) {}
|
||||
const char* t;
|
||||
typedef std::string return_type;
|
||||
|
||||
const std::string operator()() const { return t; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct to_value_t<char*> {
|
||||
explicit to_value_t(char* t_) : t(t_) {}
|
||||
const char* t;
|
||||
typedef std::string return_type;
|
||||
|
||||
const std::string operator()() const { return t; }
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
struct to_value_t<char[N]> {
|
||||
explicit to_value_t(const char* t_) : t(t_) {}
|
||||
const char* t;
|
||||
typedef std::string return_type;
|
||||
|
||||
const std::string operator()() const { return t; }
|
||||
};
|
||||
|
||||
// converts C-strings to std::strings so they can be copied
|
||||
template <typename T>
|
||||
inline typename to_value_t<T>::return_type to_value(const T& t) {
|
||||
return to_value_t<T>(t)();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template<typename Key>
|
||||
std::string key_to_string(const Key& key) {
|
||||
return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
|
||||
}
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
inline const Node Node::operator[](const Key& key) const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
detail::node* value = static_cast<const detail::node&>(*m_pNode).get(
|
||||
detail::to_value(key), m_pMemory);
|
||||
if (!value) {
|
||||
return Node(ZombieNode, key_to_string(key));
|
||||
}
|
||||
return Node(*value, m_pMemory);
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
inline Node Node::operator[](const Key& key) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
|
||||
return Node(value, m_pMemory);
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
inline bool Node::remove(const Key& key) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
return m_pNode->remove(detail::to_value(key), m_pMemory);
|
||||
}
|
||||
|
||||
inline const Node Node::operator[](const Node& key) const {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
m_pMemory->merge(*key.m_pMemory);
|
||||
detail::node* value =
|
||||
static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
|
||||
if (!value) {
|
||||
return Node(ZombieNode, key_to_string(key));
|
||||
}
|
||||
return Node(*value, m_pMemory);
|
||||
}
|
||||
|
||||
inline Node Node::operator[](const Node& key) {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
m_pMemory->merge(*key.m_pMemory);
|
||||
detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
|
||||
return Node(value, m_pMemory);
|
||||
}
|
||||
|
||||
inline bool Node::remove(const Node& key) {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
return m_pNode->remove(*key.m_pNode, m_pMemory);
|
||||
}
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
inline void Node::force_insert(const Key& key, const Value& value) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
|
||||
m_pMemory);
|
||||
}
|
||||
|
||||
// free functions
|
||||
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
|
||||
} // namespace YAML
|
||||
|
||||
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
31
include/yaml-cpp/node/iterator.h
Normal file
31
include/yaml-cpp/node/iterator.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/detail/iterator_fwd.h"
|
||||
#include "yaml-cpp/node/detail/iterator.h"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
struct iterator_value : public Node, std::pair<Node, Node> {
|
||||
iterator_value() {}
|
||||
explicit iterator_value(const Node& rhs)
|
||||
: Node(rhs),
|
||||
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
|
||||
explicit iterator_value(const Node& key, const Node& value)
|
||||
: Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
149
include/yaml-cpp/node/node.h
Normal file
149
include/yaml-cpp/node/node.h
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/node/detail/bool_type.h"
|
||||
#include "yaml-cpp/node/detail/iterator_fwd.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
class node_data;
|
||||
struct iterator_value;
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class YAML_CPP_API Node {
|
||||
public:
|
||||
friend class NodeBuilder;
|
||||
friend class NodeEvents;
|
||||
friend struct detail::iterator_value;
|
||||
friend class detail::node;
|
||||
friend class detail::node_data;
|
||||
template <typename>
|
||||
friend class detail::iterator_base;
|
||||
template <typename T, typename S>
|
||||
friend struct as_if;
|
||||
|
||||
typedef YAML::iterator iterator;
|
||||
typedef YAML::const_iterator const_iterator;
|
||||
|
||||
Node();
|
||||
explicit Node(NodeType::value type);
|
||||
template <typename T>
|
||||
explicit Node(const T& rhs);
|
||||
explicit Node(const detail::iterator_value& rhs);
|
||||
Node(const Node& rhs);
|
||||
~Node();
|
||||
|
||||
YAML::Mark Mark() const;
|
||||
NodeType::value Type() const;
|
||||
bool IsDefined() const;
|
||||
bool IsNull() const { return Type() == NodeType::Null; }
|
||||
bool IsScalar() const { return Type() == NodeType::Scalar; }
|
||||
bool IsSequence() const { return Type() == NodeType::Sequence; }
|
||||
bool IsMap() const { return Type() == NodeType::Map; }
|
||||
|
||||
// bool conversions
|
||||
YAML_CPP_OPERATOR_BOOL()
|
||||
bool operator!() const { return !IsDefined(); }
|
||||
|
||||
// access
|
||||
template <typename T>
|
||||
T as() const;
|
||||
template <typename T, typename S>
|
||||
T as(const S& fallback) const;
|
||||
const std::string& Scalar() const;
|
||||
|
||||
const std::string& Tag() const;
|
||||
void SetTag(const std::string& tag);
|
||||
|
||||
// style
|
||||
// WARNING: This API might change in future releases.
|
||||
EmitterStyle::value Style() const;
|
||||
void SetStyle(EmitterStyle::value style);
|
||||
|
||||
// assignment
|
||||
bool is(const Node& rhs) const;
|
||||
template <typename T>
|
||||
Node& operator=(const T& rhs);
|
||||
Node& operator=(const Node& rhs);
|
||||
void reset(const Node& rhs = Node());
|
||||
|
||||
// size/iterator
|
||||
std::size_t size() const;
|
||||
|
||||
const_iterator begin() const;
|
||||
iterator begin();
|
||||
|
||||
const_iterator end() const;
|
||||
iterator end();
|
||||
|
||||
// sequence
|
||||
template <typename T>
|
||||
void push_back(const T& rhs);
|
||||
void push_back(const Node& rhs);
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
const Node operator[](const Key& key) const;
|
||||
template <typename Key>
|
||||
Node operator[](const Key& key);
|
||||
template <typename Key>
|
||||
bool remove(const Key& key);
|
||||
|
||||
const Node operator[](const Node& key) const;
|
||||
Node operator[](const Node& key);
|
||||
bool remove(const Node& key);
|
||||
|
||||
// map
|
||||
template <typename Key, typename Value>
|
||||
void force_insert(const Key& key, const Value& value);
|
||||
|
||||
private:
|
||||
enum Zombie { ZombieNode };
|
||||
explicit Node(Zombie);
|
||||
explicit Node(Zombie, const std::string&);
|
||||
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
|
||||
|
||||
void EnsureNodeExists() const;
|
||||
|
||||
template <typename T>
|
||||
void Assign(const T& rhs);
|
||||
void Assign(const char* rhs);
|
||||
void Assign(char* rhs);
|
||||
|
||||
void AssignData(const Node& rhs);
|
||||
void AssignNode(const Node& rhs);
|
||||
|
||||
private:
|
||||
bool m_isValid;
|
||||
// String representation of invalid key, if the node is invalid.
|
||||
std::string m_invalidKey;
|
||||
mutable detail::shared_memory_holder m_pMemory;
|
||||
mutable detail::node* m_pNode;
|
||||
};
|
||||
|
||||
YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs);
|
||||
|
||||
YAML_CPP_API Node Clone(const Node& node);
|
||||
|
||||
template <typename T>
|
||||
struct convert;
|
||||
}
|
||||
|
||||
#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
78
include/yaml-cpp/node/parse.h
Normal file
78
include/yaml-cpp/node/parse.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
namespace YAML {
|
||||
class Node;
|
||||
|
||||
/**
|
||||
* Loads the input string as a single YAML document.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API Node Load(const std::string& input);
|
||||
|
||||
/**
|
||||
* Loads the input string as a single YAML document.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API Node Load(const char* input);
|
||||
|
||||
/**
|
||||
* Loads the input stream as a single YAML document.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API Node Load(std::istream& input);
|
||||
|
||||
/**
|
||||
* Loads the input file as a single YAML document.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
* @throws {@link BadFile} if the file cannot be loaded.
|
||||
*/
|
||||
YAML_CPP_API Node LoadFile(const std::string& filename);
|
||||
|
||||
/**
|
||||
* Loads the input string as a list of YAML documents.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API std::vector<Node> LoadAll(const std::string& input);
|
||||
|
||||
/**
|
||||
* Loads the input string as a list of YAML documents.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API std::vector<Node> LoadAll(const char* input);
|
||||
|
||||
/**
|
||||
* Loads the input stream as a list of YAML documents.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
*/
|
||||
YAML_CPP_API std::vector<Node> LoadAll(std::istream& input);
|
||||
|
||||
/**
|
||||
* Loads the input file as a list of YAML documents.
|
||||
*
|
||||
* @throws {@link ParserException} if it is malformed.
|
||||
* @throws {@link BadFile} if the file cannot be loaded.
|
||||
*/
|
||||
YAML_CPP_API std::vector<Node> LoadAllFromFile(const std::string& filename);
|
||||
} // namespace YAML
|
||||
|
||||
#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
29
include/yaml-cpp/node/ptr.h
Normal file
29
include/yaml-cpp/node/ptr.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include <memory>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
class node_ref;
|
||||
class node_data;
|
||||
class memory;
|
||||
class memory_holder;
|
||||
|
||||
typedef std::shared_ptr<node> shared_node;
|
||||
typedef std::shared_ptr<node_ref> shared_node_ref;
|
||||
typedef std::shared_ptr<node_data> shared_node_data;
|
||||
typedef std::shared_ptr<memory_holder> shared_memory_holder;
|
||||
typedef std::shared_ptr<memory> shared_memory;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
include/yaml-cpp/node/type.h
Normal file
16
include/yaml-cpp/node/type.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace YAML {
|
||||
struct NodeType {
|
||||
enum value { Undefined, Null, Scalar, Sequence, Map };
|
||||
};
|
||||
}
|
||||
|
||||
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
26
include/yaml-cpp/null.h
Normal file
26
include/yaml-cpp/null.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
class Node;
|
||||
|
||||
struct YAML_CPP_API _Null {};
|
||||
inline bool operator==(const _Null&, const _Null&) { return true; }
|
||||
inline bool operator!=(const _Null&, const _Null&) { return false; }
|
||||
|
||||
YAML_CPP_API bool IsNull(const Node& node); // old API only
|
||||
YAML_CPP_API bool IsNullString(const std::string& str);
|
||||
|
||||
extern YAML_CPP_API _Null Null;
|
||||
}
|
||||
|
||||
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
76
include/yaml-cpp/ostream_wrapper.h
Normal file
76
include/yaml-cpp/ostream_wrapper.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
namespace YAML {
|
||||
class YAML_CPP_API ostream_wrapper {
|
||||
public:
|
||||
ostream_wrapper();
|
||||
explicit ostream_wrapper(std::ostream& stream);
|
||||
ostream_wrapper(const ostream_wrapper&) = delete;
|
||||
ostream_wrapper(ostream_wrapper&&) = delete;
|
||||
ostream_wrapper& operator=(const ostream_wrapper&) = delete;
|
||||
ostream_wrapper& operator=(ostream_wrapper&&) = delete;
|
||||
~ostream_wrapper();
|
||||
|
||||
void write(const std::string& str);
|
||||
void write(const char* str, std::size_t size);
|
||||
|
||||
void set_comment() { m_comment = true; }
|
||||
|
||||
const char* str() const {
|
||||
if (m_pStream) {
|
||||
return nullptr;
|
||||
} else {
|
||||
m_buffer[m_pos] = '\0';
|
||||
return &m_buffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t row() const { return m_row; }
|
||||
std::size_t col() const { return m_col; }
|
||||
std::size_t pos() const { return m_pos; }
|
||||
bool comment() const { return m_comment; }
|
||||
|
||||
private:
|
||||
void update_pos(char ch);
|
||||
|
||||
private:
|
||||
mutable std::vector<char> m_buffer;
|
||||
std::ostream* const m_pStream;
|
||||
|
||||
std::size_t m_pos;
|
||||
std::size_t m_row, m_col;
|
||||
bool m_comment;
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
inline ostream_wrapper& operator<<(ostream_wrapper& stream,
|
||||
const char (&str)[N]) {
|
||||
stream.write(str, N - 1);
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline ostream_wrapper& operator<<(ostream_wrapper& stream,
|
||||
const std::string& str) {
|
||||
stream.write(str);
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
|
||||
stream.write(&ch, 1);
|
||||
return stream;
|
||||
}
|
||||
} // namespace YAML
|
||||
|
||||
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
90
include/yaml-cpp/parser.h
Normal file
90
include/yaml-cpp/parser.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
|
||||
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 {
|
||||
public:
|
||||
/** Constructs an empty parser (with no input. */
|
||||
Parser();
|
||||
|
||||
Parser(const Parser&) = delete;
|
||||
Parser(Parser&&) = delete;
|
||||
Parser& operator=(const Parser&) = delete;
|
||||
Parser& operator=(Parser&&) = delete;
|
||||
|
||||
/**
|
||||
* Constructs a parser from the given input stream. The input stream must
|
||||
* live as long as the parser.
|
||||
*/
|
||||
explicit Parser(std::istream& in);
|
||||
|
||||
~Parser();
|
||||
|
||||
/** Evaluates to true if the parser has some valid input to be read. */
|
||||
explicit operator bool() const;
|
||||
|
||||
/**
|
||||
* Resets the parser with the given input stream. Any existing state is
|
||||
* erased.
|
||||
*/
|
||||
void Load(std::istream& in);
|
||||
|
||||
/**
|
||||
* Handles the next document by calling events on the {@code eventHandler}.
|
||||
*
|
||||
* @throw a ParserException on error.
|
||||
* @return false if there are no more documents
|
||||
*/
|
||||
bool HandleNextDocument(EventHandler& eventHandler);
|
||||
|
||||
void PrintTokens(std::ostream& out);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reads any directives that are next in the queue, setting the internal
|
||||
* {@code m_pDirectives} state.
|
||||
*/
|
||||
void ParseDirectives();
|
||||
|
||||
void HandleDirective(const Token& token);
|
||||
|
||||
/**
|
||||
* Handles a "YAML" directive, which should be of the form 'major.minor' (like
|
||||
* a version number).
|
||||
*/
|
||||
void HandleYamlDirective(const Token& token);
|
||||
|
||||
/**
|
||||
* Handles a "TAG" directive, which should be of the form 'handle prefix',
|
||||
* where 'handle' is converted to 'prefix' in the file.
|
||||
*/
|
||||
void HandleTagDirective(const Token& token);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Scanner> m_pScanner;
|
||||
std::unique_ptr<Directives> m_pDirectives;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
51
include/yaml-cpp/stlemitter.h
Normal file
51
include/yaml-cpp/stlemitter.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace YAML {
|
||||
template <typename Seq>
|
||||
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
|
||||
emitter << BeginSeq;
|
||||
for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
|
||||
emitter << *it;
|
||||
emitter << EndSeq;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& operator<<(Emitter& emitter, const std::vector<T>& v) {
|
||||
return EmitSeq(emitter, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& operator<<(Emitter& emitter, const std::list<T>& v) {
|
||||
return EmitSeq(emitter, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
|
||||
return EmitSeq(emitter, v);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
|
||||
typedef typename std::map<K, V> map;
|
||||
emitter << BeginMap;
|
||||
for (typename map::const_iterator it = m.begin(); it != m.end(); ++it)
|
||||
emitter << Key << it->first << Value << it->second;
|
||||
emitter << EndMap;
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
135
include/yaml-cpp/traits.h
Normal file
135
include/yaml-cpp/traits.h
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML {
|
||||
template <typename>
|
||||
struct is_numeric {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_numeric<char> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned char> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<int> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned int> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<long int> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned long int> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<short int> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned short int> {
|
||||
enum { value = true };
|
||||
};
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1310)
|
||||
template <>
|
||||
struct is_numeric<__int64> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned __int64> {
|
||||
enum { value = true };
|
||||
};
|
||||
#else
|
||||
template <>
|
||||
struct is_numeric<long long> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<unsigned long long> {
|
||||
enum { value = true };
|
||||
};
|
||||
#endif
|
||||
template <>
|
||||
struct is_numeric<float> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<double> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_numeric<long double> {
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template <bool, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool, class T = void>
|
||||
struct disable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
}
|
||||
|
||||
template <typename S, typename T>
|
||||
struct is_streamable {
|
||||
template <typename SS, typename TT>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
|
||||
|
||||
template <typename, typename>
|
||||
static auto test(...) -> std::false_type;
|
||||
|
||||
static const bool value = decltype(test<S, T>(0))::value;
|
||||
};
|
||||
|
||||
template<typename Key, bool Streamable>
|
||||
struct streamable_to_string {
|
||||
static std::string impl(const Key& key) {
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
struct streamable_to_string<Key, false> {
|
||||
static std::string impl(const Key&) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
24
include/yaml-cpp/yaml.h
Normal file
24
include/yaml-cpp/yaml.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/parser.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/stlemitter.h"
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/impl.h"
|
||||
#include "yaml-cpp/node/convert.h"
|
||||
#include "yaml-cpp/node/iterator.h"
|
||||
#include "yaml-cpp/node/detail/impl.h"
|
||||
#include "yaml-cpp/node/parse.h"
|
||||
#include "yaml-cpp/node/emit.h"
|
||||
|
||||
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "crt.h"
|
||||
#include "parser.h"
|
||||
#include "node.h"
|
||||
#include "iterator.h"
|
||||
#include "emitter.h"
|
||||
#include "stlemitter.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -21,4 +21,4 @@ make install
|
||||
|
||||
If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary.
|
||||
|
||||
(Note: this is pretty tedious. It's sooo much easier to use CMake.)
|
||||
(Note: this is pretty tedious. It's sooo much easier to use CMake.)
|
||||
|
@@ -1,94 +0,0 @@
|
||||
#include "crt.h"
|
||||
#include "aliascontent.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
AliasContent::AliasContent(Content* pNodeContent)
|
||||
: m_pRef(pNodeContent)
|
||||
{
|
||||
}
|
||||
|
||||
Content *AliasContent::Clone() const
|
||||
{
|
||||
return 0; // TODO: how to clone an alias?
|
||||
}
|
||||
|
||||
void AliasContent::Parse(Scanner * /*pScanner*/, const ParserState& /*state*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AliasContent::Write(Emitter&) const
|
||||
{
|
||||
// no content (just an alias)
|
||||
}
|
||||
|
||||
bool AliasContent::GetBegin(std::vector <Node *>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetBegin(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetBegin(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetEnd(std::vector <Node *>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetEnd(i);
|
||||
}
|
||||
|
||||
bool AliasContent::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetEnd(i);
|
||||
}
|
||||
|
||||
Node* AliasContent::GetNode(std::size_t n) const
|
||||
{
|
||||
return m_pRef->GetNode(n);
|
||||
}
|
||||
|
||||
std::size_t AliasContent::GetSize() const
|
||||
{
|
||||
return m_pRef->GetSize();
|
||||
}
|
||||
|
||||
bool AliasContent::IsScalar() const
|
||||
{
|
||||
return m_pRef->IsScalar();
|
||||
}
|
||||
|
||||
bool AliasContent::IsMap() const
|
||||
{
|
||||
return m_pRef->IsMap();
|
||||
}
|
||||
|
||||
bool AliasContent::IsSequence() const
|
||||
{
|
||||
return m_pRef->IsSequence();
|
||||
}
|
||||
|
||||
bool AliasContent::GetScalar(std::string& scalar) const
|
||||
{
|
||||
return m_pRef->GetScalar(scalar);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Content *pContent)
|
||||
{
|
||||
return m_pRef->Compare(pContent);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Scalar *pScalar)
|
||||
{
|
||||
return m_pRef->Compare(pScalar);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Sequence *pSequence)
|
||||
{
|
||||
return m_pRef->Compare(pSequence);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Map *pMap)
|
||||
{
|
||||
return m_pRef->Compare(pMap);
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class AliasContent : public Content
|
||||
{
|
||||
public:
|
||||
AliasContent(Content *pNodeContent);
|
||||
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual void Parse(Scanner* pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter&) const;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const;
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const;
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const;
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const;
|
||||
virtual Node* GetNode(std::size_t) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
virtual bool IsScalar() const;
|
||||
virtual bool IsMap() const;
|
||||
virtual bool IsSequence() const;
|
||||
|
||||
virtual bool GetScalar(std::string& s) const;
|
||||
|
||||
virtual int Compare(Content *);
|
||||
virtual int Compare(Scalar *);
|
||||
virtual int Compare(Sequence *);
|
||||
virtual int Compare(Map *);
|
||||
|
||||
private:
|
||||
Content* m_pRef;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ALIASCONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
100
src/binary.cpp
Normal file
100
src/binary.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "yaml-cpp/binary.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace YAML {
|
||||
static const char encoding[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
std::string EncodeBase64(const unsigned char *data, std::size_t size) {
|
||||
const char PAD = '=';
|
||||
|
||||
std::string ret;
|
||||
ret.resize(4 * size / 3 + 3);
|
||||
char *out = &ret[0];
|
||||
|
||||
std::size_t chunks = size / 3;
|
||||
std::size_t remainder = size % 3;
|
||||
|
||||
for (std::size_t i = 0; i < chunks; i++, data += 3) {
|
||||
*out++ = encoding[data[0] >> 2];
|
||||
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
|
||||
*out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
|
||||
*out++ = encoding[data[2] & 0x3f];
|
||||
}
|
||||
|
||||
switch (remainder) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
*out++ = encoding[data[0] >> 2];
|
||||
*out++ = encoding[((data[0] & 0x3) << 4)];
|
||||
*out++ = PAD;
|
||||
*out++ = PAD;
|
||||
break;
|
||||
case 2:
|
||||
*out++ = encoding[data[0] >> 2];
|
||||
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
|
||||
*out++ = encoding[((data[1] & 0xf) << 2)];
|
||||
*out++ = PAD;
|
||||
break;
|
||||
}
|
||||
|
||||
ret.resize(out - &ret[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const unsigned char decoding[] = {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
|
||||
255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255,
|
||||
};
|
||||
|
||||
std::vector<unsigned char> DecodeBase64(const std::string &input) {
|
||||
typedef std::vector<unsigned char> ret_type;
|
||||
if (input.empty())
|
||||
return ret_type();
|
||||
|
||||
ret_type ret(3 * input.size() / 4 + 1);
|
||||
unsigned char *out = &ret[0];
|
||||
|
||||
unsigned value = 0;
|
||||
for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
|
||||
if (std::isspace(input[i])) {
|
||||
// skip newlines
|
||||
continue;
|
||||
}
|
||||
unsigned char d = decoding[static_cast<unsigned>(input[i])];
|
||||
if (d == 255)
|
||||
return ret_type();
|
||||
|
||||
value = (value << 6) | d;
|
||||
if (cnt % 4 == 3) {
|
||||
*out++ = value >> 16;
|
||||
if (i > 0 && input[i - 1] != '=')
|
||||
*out++ = value >> 8;
|
||||
if (input[i] != '=')
|
||||
*out++ = value;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
|
||||
ret.resize(out - &ret[0]);
|
||||
return ret;
|
||||
}
|
||||
}
|
41
src/collectionstack.h
Normal file
41
src/collectionstack.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <stack>
|
||||
|
||||
namespace YAML {
|
||||
struct CollectionType {
|
||||
enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
|
||||
};
|
||||
|
||||
class CollectionStack {
|
||||
public:
|
||||
CollectionStack() : collectionStack{} {}
|
||||
CollectionType::value GetCurCollectionType() const {
|
||||
if (collectionStack.empty())
|
||||
return CollectionType::NoCollection;
|
||||
return collectionStack.top();
|
||||
}
|
||||
|
||||
void PushCollectionType(CollectionType::value type) {
|
||||
collectionStack.push(type);
|
||||
}
|
||||
void PopCollectionType(CollectionType::value type) {
|
||||
assert(type == GetCurCollectionType());
|
||||
(void)type;
|
||||
collectionStack.pop();
|
||||
}
|
||||
|
||||
private:
|
||||
std::stack<CollectionType::value> collectionStack;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
@@ -1,13 +0,0 @@
|
||||
#include "crt.h"
|
||||
#include "content.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Content::Content()
|
||||
{
|
||||
}
|
||||
|
||||
Content::~Content()
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "parserstate.h"
|
||||
#include "exceptions.h"
|
||||
#include "ltnode.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Scanner;
|
||||
class Parser;
|
||||
class Node;
|
||||
class Scalar;
|
||||
class Sequence;
|
||||
class Map;
|
||||
class Emitter;
|
||||
|
||||
class Content
|
||||
{
|
||||
public:
|
||||
Content();
|
||||
virtual ~Content();
|
||||
|
||||
virtual Content *Clone() const = 0;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
|
||||
virtual void Write(Emitter& out) const = 0;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const { return false; }
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; }
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
|
||||
virtual Node *GetNode(std::size_t) const { return 0; }
|
||||
virtual std::size_t GetSize() const { return 0; }
|
||||
virtual bool IsScalar() const { return false; }
|
||||
virtual bool IsMap() const { return false; }
|
||||
virtual bool IsSequence() const { return false; }
|
||||
|
||||
// extraction
|
||||
virtual bool GetScalar(std::string&) const { return false; }
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *) { return 0; }
|
||||
virtual int Compare(Scalar *) { return 0; }
|
||||
virtual int Compare(Sequence *) { return 0; }
|
||||
virtual int Compare(Map *) { return 0; }
|
||||
|
||||
protected:
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
17
src/contrib/graphbuilder.cpp
Normal file
17
src/contrib/graphbuilder.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "graphbuilderadapter.h"
|
||||
|
||||
#include "yaml-cpp/parser.h" // IWYU pragma: keep
|
||||
|
||||
namespace YAML {
|
||||
class GraphBuilderInterface;
|
||||
|
||||
void* BuildGraphOfNextDocument(Parser& parser,
|
||||
GraphBuilderInterface& graphBuilder) {
|
||||
GraphBuilderAdapter eventHandler(graphBuilder);
|
||||
if (parser.HandleNextDocument(eventHandler)) {
|
||||
return eventHandler.RootNode();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
94
src/contrib/graphbuilderadapter.cpp
Normal file
94
src/contrib/graphbuilderadapter.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "graphbuilderadapter.h"
|
||||
#include "yaml-cpp/contrib/graphbuilder.h"
|
||||
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
|
||||
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
|
||||
|
||||
void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) {
|
||||
void *pParent = GetCurrentParent();
|
||||
void *pNode = m_builder.NewNull(mark, pParent);
|
||||
RegisterAnchor(anchor, pNode);
|
||||
|
||||
DispositionNode(pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) {
|
||||
void *pReffedNode = m_anchors.Get(anchor);
|
||||
DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
|
||||
anchor_t anchor, const std::string &value) {
|
||||
void *pParent = GetCurrentParent();
|
||||
void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
|
||||
RegisterAnchor(anchor, pNode);
|
||||
|
||||
DispositionNode(pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
|
||||
const std::string &tag,
|
||||
anchor_t anchor,
|
||||
EmitterStyle::value /* style */) {
|
||||
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
|
||||
m_containers.push(ContainerFrame(pNode));
|
||||
RegisterAnchor(anchor, pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnSequenceEnd() {
|
||||
void *pSequence = m_containers.top().pContainer;
|
||||
m_containers.pop();
|
||||
|
||||
DispositionNode(pSequence);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
|
||||
anchor_t anchor,
|
||||
EmitterStyle::value /* style */) {
|
||||
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
|
||||
m_containers.push(ContainerFrame(pNode, m_pKeyNode));
|
||||
m_pKeyNode = nullptr;
|
||||
RegisterAnchor(anchor, pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnMapEnd() {
|
||||
void *pMap = m_containers.top().pContainer;
|
||||
m_pKeyNode = m_containers.top().pPrevKeyNode;
|
||||
m_containers.pop();
|
||||
DispositionNode(pMap);
|
||||
}
|
||||
|
||||
void *GraphBuilderAdapter::GetCurrentParent() const {
|
||||
if (m_containers.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_containers.top().pContainer;
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) {
|
||||
if (anchor) {
|
||||
m_anchors.Register(anchor, pNode);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::DispositionNode(void *pNode) {
|
||||
if (m_containers.empty()) {
|
||||
m_pRootNode = pNode;
|
||||
return;
|
||||
}
|
||||
|
||||
void *pContainer = m_containers.top().pContainer;
|
||||
if (m_containers.top().isMap()) {
|
||||
if (m_pKeyNode) {
|
||||
m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
|
||||
m_pKeyNode = nullptr;
|
||||
} else {
|
||||
m_pKeyNode = pNode;
|
||||
}
|
||||
} else {
|
||||
m_builder.AppendToSequence(pContainer, pNode);
|
||||
}
|
||||
}
|
||||
}
|
87
src/contrib/graphbuilderadapter.h
Normal file
87
src/contrib/graphbuilderadapter.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/contrib/anchordict.h"
|
||||
#include "yaml-cpp/contrib/graphbuilder.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
|
||||
namespace YAML {
|
||||
class GraphBuilderInterface;
|
||||
struct Mark;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class GraphBuilderAdapter : public EventHandler {
|
||||
public:
|
||||
GraphBuilderAdapter(GraphBuilderInterface& builder)
|
||||
: m_builder(builder),
|
||||
m_containers{},
|
||||
m_anchors{},
|
||||
m_pRootNode(nullptr),
|
||||
m_pKeyNode(nullptr) {}
|
||||
GraphBuilderAdapter(const GraphBuilderAdapter&) = delete;
|
||||
GraphBuilderAdapter(GraphBuilderAdapter&&) = delete;
|
||||
GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete;
|
||||
GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete;
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
|
||||
virtual void OnDocumentEnd() {}
|
||||
|
||||
virtual void OnNull(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value);
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnSequenceEnd();
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnMapEnd();
|
||||
|
||||
void* RootNode() const { return m_pRootNode; }
|
||||
|
||||
private:
|
||||
struct ContainerFrame {
|
||||
ContainerFrame(void* pSequence)
|
||||
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
|
||||
ContainerFrame(void* pMap, void* pPreviousKeyNode)
|
||||
: pContainer(pMap), pPrevKeyNode(pPreviousKeyNode) {}
|
||||
|
||||
void* pContainer;
|
||||
void* pPrevKeyNode;
|
||||
|
||||
bool isMap() const { return pPrevKeyNode != &sequenceMarker; }
|
||||
|
||||
private:
|
||||
static int sequenceMarker;
|
||||
};
|
||||
typedef std::stack<ContainerFrame> ContainerStack;
|
||||
typedef AnchorDict<void*> AnchorMap;
|
||||
|
||||
GraphBuilderInterface& m_builder;
|
||||
ContainerStack m_containers;
|
||||
AnchorMap m_anchors;
|
||||
void* m_pRootNode;
|
||||
void* m_pKeyNode;
|
||||
|
||||
void* GetCurrentParent() const;
|
||||
void RegisterAnchor(anchor_t anchor, void* pNode);
|
||||
void DispositionNode(void* pNode);
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
32
src/contrib/yaml-cpp.natvis
Normal file
32
src/contrib/yaml-cpp.natvis
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- MSVC Debugger visualization hints for YAML::Node and YAML::detail::node -->
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="YAML::Node">
|
||||
<DisplayString Condition="!m_isValid">{{invalid}}</DisplayString>
|
||||
<DisplayString Condition="!m_pNode">{{pNode==nullptr}}</DisplayString>
|
||||
<DisplayString>{{ {*m_pNode} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
|
||||
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
|
||||
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_map</Item>
|
||||
<Item Name="[details]" >m_pNode->m_pRef._Ptr->m_pData._Ptr</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="YAML::detail::node">
|
||||
<DisplayString Condition="!m_pRef._Ptr">{{node:pRef==nullptr}}</DisplayString>
|
||||
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr">{{node:pRef->pData==nullptr}}</DisplayString>
|
||||
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr->m_isDefined">{{undefined}}</DisplayString>
|
||||
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar">{{{m_pRef._Ptr->m_pData._Ptr->m_scalar}}}</DisplayString>
|
||||
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map">{{ Map {m_pRef._Ptr->m_pData._Ptr->m_map}}}</DisplayString>
|
||||
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence">{{ Seq {m_pRef._Ptr->m_pData._Ptr->m_sequence}}}</DisplayString>
|
||||
<DisplayString>{{{m_pRef._Ptr->m_pData._Ptr->m_type}}}</DisplayString>
|
||||
<Expand>
|
||||
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
|
||||
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
|
||||
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pRef._Ptr->m_pData._Ptr->m_map</Item>
|
||||
<Item Name="[details]" >m_pRef._Ptr->m_pData._Ptr</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
9
src/contrib/yaml-cpp.natvis.md
Normal file
9
src/contrib/yaml-cpp.natvis.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# MSVC debugger visualizer for YAML::Node
|
||||
|
||||
## How to use
|
||||
Add yaml-cpp.natvis to your Visual C++ project like any other source file. It will be included in the debug information, and improve debugger display on YAML::Node and contained types.
|
||||
|
||||
## Compatibility and Troubleshooting
|
||||
|
||||
This has been tested for MSVC 2017. It is expected to be compatible with VS 2015 and VS 2019. If you have any problems, you can open an issue here: https://github.com/peterchen-cp/yaml-cpp-natvis
|
||||
|
@@ -1,89 +0,0 @@
|
||||
#include "conversion.h"
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Specializations for converting a string to specific types
|
||||
|
||||
namespace
|
||||
{
|
||||
// we're not gonna mess with the mess that is all the isupper/etc. functions
|
||||
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
|
||||
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
|
||||
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
|
||||
|
||||
std::string tolower(const std::string& str)
|
||||
{
|
||||
std::string s(str);
|
||||
std::transform(s.begin(), s.end(), s.begin(), ToLower);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool IsEntirely(const std::string& str, T func)
|
||||
{
|
||||
for(std::size_t i=0;i<str.size();i++)
|
||||
if(!func(str[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// IsFlexibleCase
|
||||
// . Returns true if 'str' is:
|
||||
// . UPPERCASE
|
||||
// . lowercase
|
||||
// . Capitalized
|
||||
bool IsFlexibleCase(const std::string& str)
|
||||
{
|
||||
if(str.empty())
|
||||
return true;
|
||||
|
||||
if(IsEntirely(str, IsLower))
|
||||
return true;
|
||||
|
||||
bool firstcaps = IsUpper(str[0]);
|
||||
std::string rest = str.substr(1);
|
||||
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
bool Convert(const std::string& input, bool& b)
|
||||
{
|
||||
// we can't use iostream bool extraction operators as they don't
|
||||
// recognize all possible values in the table below (taken from
|
||||
// http://yaml.org/type/bool.html)
|
||||
static const struct {
|
||||
std::string truename, falsename;
|
||||
} names[] = {
|
||||
{ "y", "n" },
|
||||
{ "yes", "no" },
|
||||
{ "true", "false" },
|
||||
{ "on", "off" },
|
||||
};
|
||||
|
||||
if(!IsFlexibleCase(input))
|
||||
return false;
|
||||
|
||||
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
|
||||
if(names[i].truename == tolower(input)) {
|
||||
b = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(names[i].falsename == tolower(input)) {
|
||||
b = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Convert(const std::string& input, _Null& /*output*/)
|
||||
{
|
||||
return input.empty() || input == "~" || input == "null" || input == "Null" || input == "NULL";
|
||||
}
|
||||
}
|
||||
|
75
src/convert.cpp
Normal file
75
src/convert.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "yaml-cpp/node/convert.h"
|
||||
|
||||
namespace {
|
||||
// we're not gonna mess with the mess that is all the isupper/etc. functions
|
||||
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
|
||||
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
|
||||
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
|
||||
|
||||
std::string tolower(const std::string& str) {
|
||||
std::string s(str);
|
||||
std::transform(s.begin(), s.end(), s.begin(), ToLower);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool IsEntirely(const std::string& str, T func) {
|
||||
for (std::size_t i = 0; i < str.size(); i++)
|
||||
if (!func(str[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// IsFlexibleCase
|
||||
// . Returns true if 'str' is:
|
||||
// . UPPERCASE
|
||||
// . lowercase
|
||||
// . Capitalized
|
||||
bool IsFlexibleCase(const std::string& str) {
|
||||
if (str.empty())
|
||||
return true;
|
||||
|
||||
if (IsEntirely(str, IsLower))
|
||||
return true;
|
||||
|
||||
bool firstcaps = IsUpper(str[0]);
|
||||
std::string rest = str.substr(1);
|
||||
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
bool convert<bool>::decode(const Node& node, bool& rhs) {
|
||||
if (!node.IsScalar())
|
||||
return false;
|
||||
|
||||
// we can't use iostream bool extraction operators as they don't
|
||||
// recognize all possible values in the table below (taken from
|
||||
// http://yaml.org/type/bool.html)
|
||||
static const struct {
|
||||
std::string truename, falsename;
|
||||
} names[] = {
|
||||
{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
|
||||
};
|
||||
|
||||
if (!IsFlexibleCase(node.Scalar()))
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
|
||||
if (names[i].truename == tolower(node.Scalar())) {
|
||||
rhs = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (names[i].falsename == tolower(node.Scalar())) {
|
||||
rhs = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
17
src/directives.cpp
Normal file
17
src/directives.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "directives.h"
|
||||
|
||||
namespace YAML {
|
||||
Directives::Directives() : version{true, 1, 2}, tags{} {}
|
||||
|
||||
const std::string Directives::TranslateTagHandle(
|
||||
const std::string& handle) const {
|
||||
std::map<std::string, std::string>::const_iterator it = tags.find(handle);
|
||||
if (it == tags.end()) {
|
||||
if (handle == "!!")
|
||||
return "tag:yaml.org,2002:";
|
||||
return handle;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
} // namespace YAML
|
29
src/directives.h
Normal file
29
src/directives.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace YAML {
|
||||
struct Version {
|
||||
bool isDefault;
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
struct Directives {
|
||||
Directives();
|
||||
|
||||
const std::string TranslateTagHandle(const std::string& handle) const;
|
||||
|
||||
Version version;
|
||||
std::map<std::string, std::string> tags;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
25
src/emit.cpp
Normal file
25
src/emit.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "yaml-cpp/node/emit.h"
|
||||
#include "yaml-cpp/emitfromevents.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "nodeevents.h"
|
||||
|
||||
namespace YAML {
|
||||
Emitter& operator<<(Emitter& out, const Node& node) {
|
||||
EmitFromEvents emitFromEvents(out);
|
||||
NodeEvents events(node);
|
||||
events.Emit(emitFromEvents);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Node& node) {
|
||||
Emitter emitter(out);
|
||||
emitter << node;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string Dump(const Node& node) {
|
||||
Emitter emitter;
|
||||
emitter << node;
|
||||
return emitter.c_str();
|
||||
}
|
||||
} // namespace YAML
|
120
src/emitfromevents.cpp
Normal file
120
src/emitfromevents.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
#include "yaml-cpp/emitfromevents.h"
|
||||
#include "yaml-cpp/emitter.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
#include "yaml-cpp/null.h"
|
||||
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
} // namespace YAML
|
||||
|
||||
namespace {
|
||||
std::string ToString(YAML::anchor_t anchor) {
|
||||
std::stringstream stream;
|
||||
stream << anchor;
|
||||
return stream.str();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace YAML {
|
||||
EmitFromEvents::EmitFromEvents(Emitter& emitter)
|
||||
: m_emitter(emitter), m_stateStack{} {}
|
||||
|
||||
void EmitFromEvents::OnDocumentStart(const Mark&) {}
|
||||
|
||||
void EmitFromEvents::OnDocumentEnd() {}
|
||||
|
||||
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
|
||||
BeginNode();
|
||||
EmitProps("", anchor);
|
||||
m_emitter << Null;
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) {
|
||||
BeginNode();
|
||||
m_emitter << Alias(ToString(anchor));
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value) {
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
m_emitter << value;
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
|
||||
anchor_t anchor,
|
||||
EmitterStyle::value style) {
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
switch (style) {
|
||||
case EmitterStyle::Block:
|
||||
m_emitter << Block;
|
||||
break;
|
||||
case EmitterStyle::Flow:
|
||||
m_emitter << Flow;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_emitter << BeginSeq;
|
||||
m_stateStack.push(State::WaitingForSequenceEntry);
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnSequenceEnd() {
|
||||
m_emitter << EndSeq;
|
||||
assert(m_stateStack.top() == State::WaitingForSequenceEntry);
|
||||
m_stateStack.pop();
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style) {
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
switch (style) {
|
||||
case EmitterStyle::Block:
|
||||
m_emitter << Block;
|
||||
break;
|
||||
case EmitterStyle::Flow:
|
||||
m_emitter << Flow;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_emitter << BeginMap;
|
||||
m_stateStack.push(State::WaitingForKey);
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnMapEnd() {
|
||||
m_emitter << EndMap;
|
||||
assert(m_stateStack.top() == State::WaitingForKey);
|
||||
m_stateStack.pop();
|
||||
}
|
||||
|
||||
void EmitFromEvents::BeginNode() {
|
||||
if (m_stateStack.empty())
|
||||
return;
|
||||
|
||||
switch (m_stateStack.top()) {
|
||||
case State::WaitingForKey:
|
||||
m_emitter << Key;
|
||||
m_stateStack.top() = State::WaitingForValue;
|
||||
break;
|
||||
case State::WaitingForValue:
|
||||
m_emitter << Value;
|
||||
m_stateStack.top() = State::WaitingForKey;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
|
||||
if (!tag.empty() && tag != "?" && tag != "!")
|
||||
m_emitter << VerbatimTag(tag);
|
||||
if (anchor)
|
||||
m_emitter << Anchor(ToString(anchor));
|
||||
}
|
||||
} // namespace YAML
|
1568
src/emitter.cpp
1568
src/emitter.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,263 +1,369 @@
|
||||
#include <limits>
|
||||
|
||||
#include "emitterstate.h"
|
||||
#include "exceptions.h"
|
||||
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSeparation(false)
|
||||
{
|
||||
// start up
|
||||
m_stateStack.push(ES_WAITING_FOR_DOC);
|
||||
|
||||
// set default global manipulators
|
||||
m_strFmt.set(Auto);
|
||||
m_boolFmt.set(TrueFalseBool);
|
||||
m_boolLengthFmt.set(LongBool);
|
||||
m_boolCaseFmt.set(LowerCase);
|
||||
m_intFmt.set(Dec);
|
||||
m_indent.set(2);
|
||||
m_preCommentIndent.set(2);
|
||||
m_postCommentIndent.set(1);
|
||||
m_seqFmt.set(Block);
|
||||
m_mapFmt.set(Block);
|
||||
m_mapKeyFmt.set(Auto);
|
||||
}
|
||||
|
||||
EmitterState::~EmitterState()
|
||||
{
|
||||
while(!m_groups.empty())
|
||||
_PopGroup();
|
||||
}
|
||||
|
||||
std::auto_ptr <EmitterState::Group> EmitterState::_PopGroup()
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return std::auto_ptr <Group> (0);
|
||||
|
||||
std::auto_ptr <Group> pGroup(m_groups.top());
|
||||
m_groups.pop();
|
||||
return pGroup;
|
||||
}
|
||||
namespace YAML {
|
||||
EmitterState::EmitterState()
|
||||
: m_isGood(true),
|
||||
m_lastError{},
|
||||
// default global manipulators
|
||||
m_charset(EmitNonAscii),
|
||||
m_strFmt(Auto),
|
||||
m_boolFmt(TrueFalseBool),
|
||||
m_boolLengthFmt(LongBool),
|
||||
m_boolCaseFmt(LowerCase),
|
||||
m_intFmt(Dec),
|
||||
m_indent(2),
|
||||
m_preCommentIndent(2),
|
||||
m_postCommentIndent(1),
|
||||
m_seqFmt(Block),
|
||||
m_mapFmt(Block),
|
||||
m_mapKeyFmt(Auto),
|
||||
m_floatPrecision(std::numeric_limits<float>::max_digits10),
|
||||
m_doublePrecision(std::numeric_limits<double>::max_digits10),
|
||||
//
|
||||
m_modifiedSettings{},
|
||||
m_globalModifiedSettings{},
|
||||
m_groups{},
|
||||
m_curIndent(0),
|
||||
m_hasAnchor(false),
|
||||
m_hasTag(false),
|
||||
m_hasNonContent(false),
|
||||
m_docCount(0) {}
|
||||
|
||||
// SetLocalValue
|
||||
// . We blindly tries to set all possible formatters to this value
|
||||
// . Only the ones that make sense will be accepted
|
||||
void EmitterState::SetLocalValue(EMITTER_MANIP value)
|
||||
{
|
||||
SetStringFormat(value, LOCAL);
|
||||
SetBoolFormat(value, LOCAL);
|
||||
SetBoolCaseFormat(value, LOCAL);
|
||||
SetBoolLengthFormat(value, LOCAL);
|
||||
SetIntFormat(value, LOCAL);
|
||||
SetFlowType(GT_SEQ, value, LOCAL);
|
||||
SetFlowType(GT_MAP, value, LOCAL);
|
||||
SetMapKeyFormat(value, LOCAL);
|
||||
}
|
||||
|
||||
void EmitterState::BeginGroup(GROUP_TYPE type)
|
||||
{
|
||||
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top()->indent);
|
||||
m_curIndent += lastIndent;
|
||||
|
||||
std::auto_ptr <Group> pGroup(new Group(type));
|
||||
|
||||
// transfer settings (which last until this group is done)
|
||||
pGroup->modifiedSettings = m_modifiedSettings;
|
||||
EmitterState::~EmitterState() {}
|
||||
|
||||
// set up group
|
||||
pGroup->flow = GetFlowType(type);
|
||||
pGroup->indent = GetIndent();
|
||||
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
|
||||
|
||||
m_groups.push(pGroup.release());
|
||||
}
|
||||
|
||||
void EmitterState::EndGroup(GROUP_TYPE type)
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
|
||||
|
||||
// get rid of the current group
|
||||
{
|
||||
std::auto_ptr <Group> pFinishedGroup = _PopGroup();
|
||||
if(pFinishedGroup->type != type)
|
||||
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
|
||||
}
|
||||
|
||||
// reset old settings
|
||||
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top()->indent);
|
||||
assert(m_curIndent >= lastIndent);
|
||||
m_curIndent -= lastIndent;
|
||||
|
||||
// some global settings that we changed may have been overridden
|
||||
// by a local setting we just popped, so we need to restore them
|
||||
m_globalModifiedSettings.restore();
|
||||
}
|
||||
|
||||
GROUP_TYPE EmitterState::GetCurGroupType() const
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return GT_NONE;
|
||||
|
||||
return m_groups.top()->type;
|
||||
}
|
||||
|
||||
FLOW_TYPE EmitterState::GetCurGroupFlowType() const
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return FT_NONE;
|
||||
|
||||
return (m_groups.top()->flow == Flow ? FT_FLOW : FT_BLOCK);
|
||||
}
|
||||
|
||||
bool EmitterState::CurrentlyInLongKey()
|
||||
{
|
||||
if(m_groups.empty())
|
||||
return false;
|
||||
return m_groups.top()->usingLongKey;
|
||||
}
|
||||
|
||||
void EmitterState::StartLongKey()
|
||||
{
|
||||
if(!m_groups.empty())
|
||||
m_groups.top()->usingLongKey = true;
|
||||
}
|
||||
|
||||
void EmitterState::StartSimpleKey()
|
||||
{
|
||||
if(!m_groups.empty())
|
||||
m_groups.top()->usingLongKey = false;
|
||||
}
|
||||
|
||||
void EmitterState::ClearModifiedSettings()
|
||||
{
|
||||
m_modifiedSettings.clear();
|
||||
}
|
||||
|
||||
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case Auto:
|
||||
case SingleQuoted:
|
||||
case DoubleQuoted:
|
||||
case Literal:
|
||||
_Set(m_strFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case OnOffBool:
|
||||
case TrueFalseBool:
|
||||
case YesNoBool:
|
||||
_Set(m_boolFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case LongBool:
|
||||
case ShortBool:
|
||||
_Set(m_boolLengthFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case UpperCase:
|
||||
case LowerCase:
|
||||
case CamelCase:
|
||||
_Set(m_boolCaseFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case Dec:
|
||||
case Hex:
|
||||
case Oct:
|
||||
_Set(m_intFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
|
||||
{
|
||||
if(value == 0)
|
||||
return false;
|
||||
|
||||
_Set(m_indent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetPreCommentIndent(unsigned value, FMT_SCOPE scope)
|
||||
{
|
||||
if(value == 0)
|
||||
return false;
|
||||
|
||||
_Set(m_preCommentIndent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetPostCommentIndent(unsigned value, FMT_SCOPE scope)
|
||||
{
|
||||
if(value == 0)
|
||||
return false;
|
||||
|
||||
_Set(m_postCommentIndent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case Block:
|
||||
case Flow:
|
||||
_Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EMITTER_MANIP EmitterState::GetFlowType(GROUP_TYPE groupType) const
|
||||
{
|
||||
// force flow style if we're currently in a flow
|
||||
FLOW_TYPE flowType = GetCurGroupFlowType();
|
||||
if(flowType == FT_FLOW)
|
||||
return Flow;
|
||||
|
||||
// otherwise, go with what's asked of use
|
||||
return (groupType == GT_SEQ ? m_seqFmt.get() : m_mapFmt.get());
|
||||
}
|
||||
|
||||
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope)
|
||||
{
|
||||
switch(value) {
|
||||
case Auto:
|
||||
case LongKey:
|
||||
_Set(m_mapKeyFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// SetLocalValue
|
||||
// . We blindly tries to set all possible formatters to this value
|
||||
// . Only the ones that make sense will be accepted
|
||||
void EmitterState::SetLocalValue(EMITTER_MANIP value) {
|
||||
SetOutputCharset(value, FmtScope::Local);
|
||||
SetStringFormat(value, FmtScope::Local);
|
||||
SetBoolFormat(value, FmtScope::Local);
|
||||
SetBoolCaseFormat(value, FmtScope::Local);
|
||||
SetBoolLengthFormat(value, FmtScope::Local);
|
||||
SetIntFormat(value, FmtScope::Local);
|
||||
SetFlowType(GroupType::Seq, value, FmtScope::Local);
|
||||
SetFlowType(GroupType::Map, value, FmtScope::Local);
|
||||
SetMapKeyFormat(value, FmtScope::Local);
|
||||
}
|
||||
|
||||
void EmitterState::SetAnchor() { m_hasAnchor = true; }
|
||||
|
||||
void EmitterState::SetTag() { m_hasTag = true; }
|
||||
|
||||
void EmitterState::SetNonContent() { m_hasNonContent = true; }
|
||||
|
||||
void EmitterState::SetLongKey() {
|
||||
assert(!m_groups.empty());
|
||||
if (m_groups.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_groups.back()->type == GroupType::Map);
|
||||
m_groups.back()->longKey = true;
|
||||
}
|
||||
|
||||
void EmitterState::ForceFlow() {
|
||||
assert(!m_groups.empty());
|
||||
if (m_groups.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_groups.back()->flowType = FlowType::Flow;
|
||||
}
|
||||
|
||||
void EmitterState::StartedNode() {
|
||||
if (m_groups.empty()) {
|
||||
m_docCount++;
|
||||
} else {
|
||||
m_groups.back()->childCount++;
|
||||
if (m_groups.back()->childCount % 2 == 0) {
|
||||
m_groups.back()->longKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_hasAnchor = false;
|
||||
m_hasTag = false;
|
||||
m_hasNonContent = false;
|
||||
}
|
||||
|
||||
EmitterNodeType::value EmitterState::NextGroupType(
|
||||
GroupType::value type) const {
|
||||
if (type == GroupType::Seq) {
|
||||
if (GetFlowType(type) == Block)
|
||||
return EmitterNodeType::BlockSeq;
|
||||
else
|
||||
return EmitterNodeType::FlowSeq;
|
||||
} else {
|
||||
if (GetFlowType(type) == Block)
|
||||
return EmitterNodeType::BlockMap;
|
||||
else
|
||||
return EmitterNodeType::FlowMap;
|
||||
}
|
||||
|
||||
// can't happen
|
||||
assert(false);
|
||||
return EmitterNodeType::NoType;
|
||||
}
|
||||
|
||||
void EmitterState::StartedDoc() {
|
||||
m_hasAnchor = false;
|
||||
m_hasTag = false;
|
||||
m_hasNonContent = false;
|
||||
}
|
||||
|
||||
void EmitterState::EndedDoc() {
|
||||
m_hasAnchor = false;
|
||||
m_hasTag = false;
|
||||
m_hasNonContent = false;
|
||||
}
|
||||
|
||||
void EmitterState::StartedScalar() {
|
||||
StartedNode();
|
||||
ClearModifiedSettings();
|
||||
}
|
||||
|
||||
void EmitterState::StartedGroup(GroupType::value type) {
|
||||
StartedNode();
|
||||
|
||||
const std::size_t lastGroupIndent =
|
||||
(m_groups.empty() ? 0 : m_groups.back()->indent);
|
||||
m_curIndent += lastGroupIndent;
|
||||
|
||||
// TODO: Create move constructors for settings types to simplify transfer
|
||||
std::unique_ptr<Group> pGroup(new Group(type));
|
||||
|
||||
// transfer settings (which last until this group is done)
|
||||
//
|
||||
// NB: if pGroup->modifiedSettings == m_modifiedSettings,
|
||||
// m_modifiedSettings is not changed!
|
||||
pGroup->modifiedSettings = std::move(m_modifiedSettings);
|
||||
|
||||
// set up group
|
||||
if (GetFlowType(type) == Block) {
|
||||
pGroup->flowType = FlowType::Block;
|
||||
} else {
|
||||
pGroup->flowType = FlowType::Flow;
|
||||
}
|
||||
pGroup->indent = GetIndent();
|
||||
|
||||
m_groups.push_back(std::move(pGroup));
|
||||
}
|
||||
|
||||
void EmitterState::EndedGroup(GroupType::value type) {
|
||||
if (m_groups.empty()) {
|
||||
if (type == GroupType::Seq) {
|
||||
return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
|
||||
} else {
|
||||
return SetError(ErrorMsg::UNEXPECTED_END_MAP);
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of the current group
|
||||
{
|
||||
std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
|
||||
m_groups.pop_back();
|
||||
if (pFinishedGroup->type != type) {
|
||||
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
// reset old settings
|
||||
std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
|
||||
assert(m_curIndent >= lastIndent);
|
||||
m_curIndent -= lastIndent;
|
||||
|
||||
// some global settings that we changed may have been overridden
|
||||
// by a local setting we just popped, so we need to restore them
|
||||
m_globalModifiedSettings.restore();
|
||||
|
||||
ClearModifiedSettings();
|
||||
}
|
||||
|
||||
EmitterNodeType::value EmitterState::CurGroupNodeType() const {
|
||||
if (m_groups.empty()) {
|
||||
return EmitterNodeType::NoType;
|
||||
}
|
||||
|
||||
return m_groups.back()->NodeType();
|
||||
}
|
||||
|
||||
GroupType::value EmitterState::CurGroupType() const {
|
||||
return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
|
||||
}
|
||||
|
||||
FlowType::value EmitterState::CurGroupFlowType() const {
|
||||
return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
|
||||
}
|
||||
|
||||
std::size_t EmitterState::CurGroupIndent() const {
|
||||
return m_groups.empty() ? 0 : m_groups.back()->indent;
|
||||
}
|
||||
|
||||
std::size_t EmitterState::CurGroupChildCount() const {
|
||||
return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
|
||||
}
|
||||
|
||||
bool EmitterState::CurGroupLongKey() const {
|
||||
return m_groups.empty() ? false : m_groups.back()->longKey;
|
||||
}
|
||||
|
||||
std::size_t EmitterState::LastIndent() const {
|
||||
if (m_groups.size() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_curIndent - m_groups[m_groups.size() - 2]->indent;
|
||||
}
|
||||
|
||||
void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
|
||||
|
||||
bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
|
||||
FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case EmitNonAscii:
|
||||
case EscapeNonAscii:
|
||||
_Set(m_charset, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case Auto:
|
||||
case SingleQuoted:
|
||||
case DoubleQuoted:
|
||||
case Literal:
|
||||
_Set(m_strFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case OnOffBool:
|
||||
case TrueFalseBool:
|
||||
case YesNoBool:
|
||||
_Set(m_boolFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
|
||||
FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case LongBool:
|
||||
case ShortBool:
|
||||
_Set(m_boolLengthFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
|
||||
FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case UpperCase:
|
||||
case LowerCase:
|
||||
case CamelCase:
|
||||
_Set(m_boolCaseFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case Dec:
|
||||
case Hex:
|
||||
case Oct:
|
||||
_Set(m_intFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
|
||||
if (value <= 1)
|
||||
return false;
|
||||
|
||||
_Set(m_indent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetPreCommentIndent(std::size_t value,
|
||||
FmtScope::value scope) {
|
||||
if (value == 0)
|
||||
return false;
|
||||
|
||||
_Set(m_preCommentIndent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetPostCommentIndent(std::size_t value,
|
||||
FmtScope::value scope) {
|
||||
if (value == 0)
|
||||
return false;
|
||||
|
||||
_Set(m_postCommentIndent, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
|
||||
FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case Block:
|
||||
case Flow:
|
||||
_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
|
||||
// force flow style if we're currently in a flow
|
||||
if (CurGroupFlowType() == FlowType::Flow)
|
||||
return Flow;
|
||||
|
||||
// otherwise, go with what's asked of us
|
||||
return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
|
||||
}
|
||||
|
||||
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
|
||||
switch (value) {
|
||||
case Auto:
|
||||
case LongKey:
|
||||
_Set(m_mapKeyFmt, value, scope);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
|
||||
if (value > std::numeric_limits<float>::max_digits10)
|
||||
return false;
|
||||
_Set(m_floatPrecision, value, scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitterState::SetDoublePrecision(std::size_t value,
|
||||
FmtScope::value scope) {
|
||||
if (value > std::numeric_limits<double>::max_digits10)
|
||||
return false;
|
||||
_Set(m_doublePrecision, value, scope);
|
||||
return true;
|
||||
}
|
||||
} // namespace YAML
|
||||
|
@@ -1,201 +1,208 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "setting.h"
|
||||
#include "emittermanip.h"
|
||||
#include "yaml-cpp/emitterdef.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
enum FMT_SCOPE {
|
||||
LOCAL,
|
||||
GLOBAL
|
||||
};
|
||||
|
||||
enum GROUP_TYPE {
|
||||
GT_NONE,
|
||||
GT_SEQ,
|
||||
GT_MAP
|
||||
};
|
||||
|
||||
enum FLOW_TYPE {
|
||||
FT_NONE,
|
||||
FT_FLOW,
|
||||
FT_BLOCK
|
||||
};
|
||||
|
||||
enum NODE_STATE {
|
||||
NS_START,
|
||||
NS_READY_FOR_ATOM,
|
||||
NS_END
|
||||
};
|
||||
|
||||
enum EMITTER_STATE {
|
||||
ES_WAITING_FOR_DOC,
|
||||
ES_WRITING_DOC,
|
||||
ES_DONE_WITH_DOC,
|
||||
|
||||
// block seq
|
||||
ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
|
||||
ES_WRITING_BLOCK_SEQ_ENTRY,
|
||||
ES_DONE_WITH_BLOCK_SEQ_ENTRY,
|
||||
|
||||
// flow seq
|
||||
ES_WAITING_FOR_FLOW_SEQ_ENTRY,
|
||||
ES_WRITING_FLOW_SEQ_ENTRY,
|
||||
ES_DONE_WITH_FLOW_SEQ_ENTRY,
|
||||
|
||||
// block map
|
||||
ES_WAITING_FOR_BLOCK_MAP_ENTRY,
|
||||
ES_WAITING_FOR_BLOCK_MAP_KEY,
|
||||
ES_WRITING_BLOCK_MAP_KEY,
|
||||
ES_DONE_WITH_BLOCK_MAP_KEY,
|
||||
ES_WAITING_FOR_BLOCK_MAP_VALUE,
|
||||
ES_WRITING_BLOCK_MAP_VALUE,
|
||||
ES_DONE_WITH_BLOCK_MAP_VALUE,
|
||||
|
||||
// flow map
|
||||
ES_WAITING_FOR_FLOW_MAP_ENTRY,
|
||||
ES_WAITING_FOR_FLOW_MAP_KEY,
|
||||
ES_WRITING_FLOW_MAP_KEY,
|
||||
ES_DONE_WITH_FLOW_MAP_KEY,
|
||||
ES_WAITING_FOR_FLOW_MAP_VALUE,
|
||||
ES_WRITING_FLOW_MAP_VALUE,
|
||||
ES_DONE_WITH_FLOW_MAP_VALUE
|
||||
};
|
||||
|
||||
class EmitterState
|
||||
{
|
||||
public:
|
||||
EmitterState();
|
||||
~EmitterState();
|
||||
|
||||
// basic state checking
|
||||
bool good() const { return m_isGood; }
|
||||
const std::string GetLastError() const { return m_lastError; }
|
||||
void SetError(const std::string& error) { m_isGood = false; m_lastError = error; }
|
||||
|
||||
// main state of the machine
|
||||
EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
|
||||
void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
|
||||
void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
|
||||
void PopState() { m_stateStack.pop(); }
|
||||
|
||||
void SetLocalValue(EMITTER_MANIP value);
|
||||
|
||||
// group handling
|
||||
void BeginGroup(GROUP_TYPE type);
|
||||
void EndGroup(GROUP_TYPE type);
|
||||
|
||||
GROUP_TYPE GetCurGroupType() const;
|
||||
FLOW_TYPE GetCurGroupFlowType() const;
|
||||
int GetCurIndent() const { return m_curIndent; }
|
||||
|
||||
bool CurrentlyInLongKey();
|
||||
void StartLongKey();
|
||||
void StartSimpleKey();
|
||||
namespace YAML {
|
||||
struct FmtScope {
|
||||
enum value { Local, Global };
|
||||
};
|
||||
struct GroupType {
|
||||
enum value { NoType, Seq, Map };
|
||||
};
|
||||
struct FlowType {
|
||||
enum value { NoType, Flow, Block };
|
||||
};
|
||||
|
||||
bool RequiresSeparation() const { return m_requiresSeparation; }
|
||||
void RequireSeparation() { m_requiresSeparation = true; }
|
||||
void UnsetSeparation() { m_requiresSeparation = false; }
|
||||
class EmitterState {
|
||||
public:
|
||||
EmitterState();
|
||||
~EmitterState();
|
||||
|
||||
void ClearModifiedSettings();
|
||||
// basic state checking
|
||||
bool good() const { return m_isGood; }
|
||||
const std::string GetLastError() const { return m_lastError; }
|
||||
void SetError(const std::string& error) {
|
||||
m_isGood = false;
|
||||
m_lastError = error;
|
||||
}
|
||||
|
||||
// formatters
|
||||
bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
|
||||
|
||||
bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
|
||||
// node handling
|
||||
void SetAnchor();
|
||||
void SetTag();
|
||||
void SetNonContent();
|
||||
void SetLongKey();
|
||||
void ForceFlow();
|
||||
void StartedDoc();
|
||||
void EndedDoc();
|
||||
void StartedScalar();
|
||||
void StartedGroup(GroupType::value type);
|
||||
void EndedGroup(GroupType::value type);
|
||||
|
||||
bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
|
||||
EmitterNodeType::value NextGroupType(GroupType::value type) const;
|
||||
EmitterNodeType::value CurGroupNodeType() const;
|
||||
|
||||
bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
|
||||
GroupType::value CurGroupType() const;
|
||||
FlowType::value CurGroupFlowType() const;
|
||||
std::size_t CurGroupIndent() const;
|
||||
std::size_t CurGroupChildCount() const;
|
||||
bool CurGroupLongKey() const;
|
||||
|
||||
bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
|
||||
std::size_t LastIndent() const;
|
||||
std::size_t CurIndent() const { return m_curIndent; }
|
||||
bool HasAnchor() const { return m_hasAnchor; }
|
||||
bool HasTag() const { return m_hasTag; }
|
||||
bool HasBegunNode() const {
|
||||
return m_hasAnchor || m_hasTag || m_hasNonContent;
|
||||
}
|
||||
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
|
||||
|
||||
bool SetIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetIndent() const { return m_indent.get(); }
|
||||
|
||||
bool SetPreCommentIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
|
||||
bool SetPostCommentIndent(unsigned value, FMT_SCOPE scope);
|
||||
int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
|
||||
|
||||
bool SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetFlowType(GROUP_TYPE groupType) const;
|
||||
|
||||
bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
|
||||
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
|
||||
|
||||
private:
|
||||
// basic state ok?
|
||||
bool m_isGood;
|
||||
std::string m_lastError;
|
||||
|
||||
// other state
|
||||
std::stack <EMITTER_STATE> m_stateStack;
|
||||
|
||||
Setting <EMITTER_MANIP> m_strFmt;
|
||||
Setting <EMITTER_MANIP> m_boolFmt;
|
||||
Setting <EMITTER_MANIP> m_boolLengthFmt;
|
||||
Setting <EMITTER_MANIP> m_boolCaseFmt;
|
||||
Setting <EMITTER_MANIP> m_intFmt;
|
||||
Setting <unsigned> m_indent;
|
||||
Setting <unsigned> m_preCommentIndent, m_postCommentIndent;
|
||||
Setting <EMITTER_MANIP> m_seqFmt;
|
||||
Setting <EMITTER_MANIP> m_mapFmt;
|
||||
Setting <EMITTER_MANIP> m_mapKeyFmt;
|
||||
|
||||
SettingChanges m_modifiedSettings;
|
||||
SettingChanges m_globalModifiedSettings;
|
||||
|
||||
struct Group {
|
||||
Group(GROUP_TYPE type_): type(type_), usingLongKey(false), indent(0) {}
|
||||
|
||||
GROUP_TYPE type;
|
||||
EMITTER_MANIP flow;
|
||||
bool usingLongKey;
|
||||
int indent;
|
||||
|
||||
SettingChanges modifiedSettings;
|
||||
};
|
||||
|
||||
std::auto_ptr <Group> _PopGroup();
|
||||
|
||||
std::stack <Group *> m_groups;
|
||||
unsigned m_curIndent;
|
||||
bool m_requiresSeparation;
|
||||
};
|
||||
void ClearModifiedSettings();
|
||||
|
||||
template <typename T>
|
||||
void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
|
||||
switch(scope) {
|
||||
case LOCAL:
|
||||
m_modifiedSettings.push(fmt.set(value));
|
||||
break;
|
||||
case GLOBAL:
|
||||
fmt.set(value);
|
||||
m_globalModifiedSettings.push(fmt.set(value)); // this pushes an identity set, so when we restore,
|
||||
// it restores to the value here, and not the previous one
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
// formatters
|
||||
void SetLocalValue(EMITTER_MANIP value);
|
||||
|
||||
bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
|
||||
|
||||
bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
|
||||
|
||||
bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
|
||||
|
||||
bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
|
||||
|
||||
bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
|
||||
|
||||
bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
|
||||
|
||||
bool SetIndent(std::size_t value, FmtScope::value scope);
|
||||
std::size_t GetIndent() const { return m_indent.get(); }
|
||||
|
||||
bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
|
||||
std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
|
||||
bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
|
||||
std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
|
||||
|
||||
bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
|
||||
FmtScope::value scope);
|
||||
EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
|
||||
|
||||
bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
|
||||
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
|
||||
|
||||
bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
|
||||
std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
|
||||
bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
|
||||
std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
|
||||
|
||||
void StartedNode();
|
||||
|
||||
private:
|
||||
// basic state ok?
|
||||
bool m_isGood;
|
||||
std::string m_lastError;
|
||||
|
||||
// other state
|
||||
Setting<EMITTER_MANIP> m_charset;
|
||||
Setting<EMITTER_MANIP> m_strFmt;
|
||||
Setting<EMITTER_MANIP> m_boolFmt;
|
||||
Setting<EMITTER_MANIP> m_boolLengthFmt;
|
||||
Setting<EMITTER_MANIP> m_boolCaseFmt;
|
||||
Setting<EMITTER_MANIP> m_intFmt;
|
||||
Setting<std::size_t> m_indent;
|
||||
Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
|
||||
Setting<EMITTER_MANIP> m_seqFmt;
|
||||
Setting<EMITTER_MANIP> m_mapFmt;
|
||||
Setting<EMITTER_MANIP> m_mapKeyFmt;
|
||||
Setting<std::size_t> m_floatPrecision;
|
||||
Setting<std::size_t> m_doublePrecision;
|
||||
|
||||
SettingChanges m_modifiedSettings;
|
||||
SettingChanges m_globalModifiedSettings;
|
||||
|
||||
struct Group {
|
||||
explicit Group(GroupType::value type_)
|
||||
: type(type_),
|
||||
flowType{},
|
||||
indent(0),
|
||||
childCount(0),
|
||||
longKey(false),
|
||||
modifiedSettings{} {}
|
||||
|
||||
GroupType::value type;
|
||||
FlowType::value flowType;
|
||||
std::size_t indent;
|
||||
std::size_t childCount;
|
||||
bool longKey;
|
||||
|
||||
SettingChanges modifiedSettings;
|
||||
|
||||
EmitterNodeType::value NodeType() const {
|
||||
if (type == GroupType::Seq) {
|
||||
if (flowType == FlowType::Flow)
|
||||
return EmitterNodeType::FlowSeq;
|
||||
else
|
||||
return EmitterNodeType::BlockSeq;
|
||||
} else {
|
||||
if (flowType == FlowType::Flow)
|
||||
return EmitterNodeType::FlowMap;
|
||||
else
|
||||
return EmitterNodeType::BlockMap;
|
||||
}
|
||||
|
||||
// can't get here
|
||||
assert(false);
|
||||
return EmitterNodeType::NoType;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<Group>> m_groups;
|
||||
std::size_t m_curIndent;
|
||||
bool m_hasAnchor;
|
||||
bool m_hasTag;
|
||||
bool m_hasNonContent;
|
||||
std::size_t m_docCount;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
|
||||
switch (scope) {
|
||||
case FmtScope::Local:
|
||||
m_modifiedSettings.push(fmt.set(value));
|
||||
break;
|
||||
case FmtScope::Global:
|
||||
fmt.set(value);
|
||||
m_globalModifiedSettings.push(
|
||||
fmt.set(value)); // this pushes an identity set, so when we restore,
|
||||
// it restores to the value here, and not the previous one
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
} // namespace YAML
|
||||
|
||||
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
@@ -1,145 +1,483 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "emitterutils.h"
|
||||
#include "exp.h"
|
||||
#include "indentation.h"
|
||||
#include "exceptions.h"
|
||||
#include "regex_yaml.h"
|
||||
#include "regeximpl.h"
|
||||
#include "stringsource.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "yaml-cpp/binary.h" // IWYU pragma: keep
|
||||
#include "yaml-cpp/null.h"
|
||||
#include "yaml-cpp/ostream_wrapper.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
namespace {
|
||||
bool IsPrintable(char ch) {
|
||||
return (0x20 <= ch && ch <= 0x7E);
|
||||
}
|
||||
|
||||
bool IsValidPlainScalar(const std::string& str, bool inFlow) {
|
||||
// first check the start
|
||||
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow : Exp::PlainScalar);
|
||||
if(!start.Matches(str))
|
||||
return false;
|
||||
|
||||
// and check the end for plain whitespace (which can't be faithfully kept in a plain scalar)
|
||||
if(!str.empty() && *str.rbegin() == ' ')
|
||||
return false;
|
||||
namespace YAML {
|
||||
namespace Utils {
|
||||
namespace {
|
||||
enum { REPLACEMENT_CHARACTER = 0xFFFD };
|
||||
|
||||
// then check until something is disallowed
|
||||
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow : Exp::EndScalar)
|
||||
|| (Exp::BlankOrBreak + Exp::Comment)
|
||||
|| (!Exp::Printable)
|
||||
|| Exp::Break
|
||||
|| Exp::Tab;
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
while(buffer) {
|
||||
if(disallowed.Matches(buffer))
|
||||
return false;
|
||||
++buffer;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool WriteString(ostream& out, const std::string& str, bool inFlow)
|
||||
{
|
||||
if(IsValidPlainScalar(str, inFlow)) {
|
||||
out << str;
|
||||
return true;
|
||||
} else
|
||||
return WriteDoubleQuotedString(out, str);
|
||||
}
|
||||
|
||||
bool WriteSingleQuotedString(ostream& out, const std::string& str)
|
||||
{
|
||||
out << "'";
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
char ch = str[i];
|
||||
if(!IsPrintable(ch))
|
||||
return false;
|
||||
|
||||
if(ch == '\'')
|
||||
out << "''";
|
||||
else
|
||||
out << ch;
|
||||
}
|
||||
out << "'";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteDoubleQuotedString(ostream& out, const std::string& str)
|
||||
{
|
||||
out << "\"";
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
char ch = str[i];
|
||||
if(IsPrintable(ch)) {
|
||||
if(ch == '\"')
|
||||
out << "\\\"";
|
||||
else if(ch == '\\')
|
||||
out << "\\\\";
|
||||
else
|
||||
out << ch;
|
||||
} else {
|
||||
// TODO: for the common escaped characters, give their usual symbol
|
||||
std::stringstream str;
|
||||
str << "\\x" << std::hex << std::setfill('0') << std::setw(2) << static_cast <int>(ch);
|
||||
out << str.str();
|
||||
}
|
||||
}
|
||||
out << "\"";
|
||||
return true;
|
||||
}
|
||||
bool IsAnchorChar(int ch) { // test for ns-anchor-char
|
||||
switch (ch) {
|
||||
case ',':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}': // c-flow-indicator
|
||||
case ' ':
|
||||
case '\t': // s-white
|
||||
case 0xFEFF: // c-byte-order-mark
|
||||
case 0xA:
|
||||
case 0xD: // b-char
|
||||
return false;
|
||||
case 0x85:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteLiteralString(ostream& out, const std::string& str, int indent)
|
||||
{
|
||||
out << "|\n";
|
||||
out << IndentTo(indent);
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
if(str[i] == '\n')
|
||||
out << "\n" << IndentTo(indent);
|
||||
else
|
||||
out << str[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
|
||||
{
|
||||
unsigned curIndent = out.col();
|
||||
out << "#" << Indentation(postCommentIndent);
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
if(str[i] == '\n')
|
||||
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
|
||||
else
|
||||
out << str[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (ch < 0x20) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WriteAlias(ostream& out, const std::string& str)
|
||||
{
|
||||
out << "*";
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
|
||||
return false;
|
||||
|
||||
out << str[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteAnchor(ostream& out, const std::string& str)
|
||||
{
|
||||
out << "&";
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
|
||||
return false;
|
||||
|
||||
out << str[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ch < 0x7E) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ch < 0xA0) {
|
||||
return false;
|
||||
}
|
||||
if (ch >= 0xD800 && ch <= 0xDFFF) {
|
||||
return false;
|
||||
}
|
||||
if ((ch & 0xFFFE) == 0xFFFE) {
|
||||
return false;
|
||||
}
|
||||
if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) {
|
||||
return false;
|
||||
}
|
||||
if (ch > 0x10FFFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Utf8BytesIndicated(char ch) {
|
||||
int byteVal = static_cast<unsigned char>(ch);
|
||||
switch (byteVal >> 4) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return 1;
|
||||
case 12:
|
||||
case 13:
|
||||
return 2;
|
||||
case 14:
|
||||
return 3;
|
||||
case 15:
|
||||
return 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
|
||||
|
||||
bool GetNextCodePointAndAdvance(int& codePoint,
|
||||
std::string::const_iterator& first,
|
||||
std::string::const_iterator last) {
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
int nBytes = Utf8BytesIndicated(*first);
|
||||
if (nBytes < 1) {
|
||||
// Bad lead byte
|
||||
++first;
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nBytes == 1) {
|
||||
codePoint = *first++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gather bits from trailing bytes
|
||||
codePoint = static_cast<unsigned char>(*first) & ~(0xFF << (7 - nBytes));
|
||||
++first;
|
||||
--nBytes;
|
||||
for (; nBytes > 0; ++first, --nBytes) {
|
||||
if ((first == last) || !IsTrailingByte(*first)) {
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
break;
|
||||
}
|
||||
codePoint <<= 6;
|
||||
codePoint |= *first & 0x3F;
|
||||
}
|
||||
|
||||
// Check for illegal code points
|
||||
if (codePoint > 0x10FFFF)
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
else if (codePoint >= 0xD800 && codePoint <= 0xDFFF)
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
else if ((codePoint & 0xFFFE) == 0xFFFE)
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WriteCodePoint(ostream_wrapper& out, int codePoint) {
|
||||
if (codePoint < 0 || codePoint > 0x10FFFF) {
|
||||
codePoint = REPLACEMENT_CHARACTER;
|
||||
}
|
||||
if (codePoint <= 0x7F) {
|
||||
out << static_cast<char>(codePoint);
|
||||
} else if (codePoint <= 0x7FF) {
|
||||
out << static_cast<char>(0xC0 | (codePoint >> 6))
|
||||
<< static_cast<char>(0x80 | (codePoint & 0x3F));
|
||||
} else if (codePoint <= 0xFFFF) {
|
||||
out << static_cast<char>(0xE0 | (codePoint >> 12))
|
||||
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
|
||||
<< static_cast<char>(0x80 | (codePoint & 0x3F));
|
||||
} else {
|
||||
out << static_cast<char>(0xF0 | (codePoint >> 18))
|
||||
<< static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F))
|
||||
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
|
||||
<< static_cast<char>(0x80 | (codePoint & 0x3F));
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
|
||||
bool allowOnlyAscii) {
|
||||
// check against null
|
||||
if (IsNullString(str)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check the start
|
||||
const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
|
||||
: Exp::PlainScalar());
|
||||
if (!start.Matches(str)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// and check the end for plain whitespace (which can't be faithfully kept in a
|
||||
// plain scalar)
|
||||
if (!str.empty() && *str.rbegin() == ' ') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// then check until something is disallowed
|
||||
static const RegEx& disallowed_flow =
|
||||
Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
|
||||
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
|
||||
Exp::Tab();
|
||||
static const RegEx& disallowed_block =
|
||||
Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
|
||||
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
|
||||
Exp::Tab();
|
||||
const RegEx& disallowed =
|
||||
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
|
||||
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
while (buffer) {
|
||||
if (disallowed.Matches(buffer)) {
|
||||
return false;
|
||||
}
|
||||
if (allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) {
|
||||
return false;
|
||||
}
|
||||
++buffer;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
|
||||
// TODO: check for non-printable characters?
|
||||
for (std::size_t i = 0; i < str.size(); i++) {
|
||||
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
|
||||
return false;
|
||||
}
|
||||
if (str[i] == '\n') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
|
||||
bool escapeNonAscii) {
|
||||
if (flowType == FlowType::Flow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: check for non-printable characters?
|
||||
for (std::size_t i = 0; i < str.size(); i++) {
|
||||
if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
|
||||
static const char hexDigits[] = "0123456789abcdef";
|
||||
|
||||
out << "\\";
|
||||
int digits = 8;
|
||||
if (codePoint < 0xFF) {
|
||||
out << "x";
|
||||
digits = 2;
|
||||
} else if (codePoint < 0xFFFF) {
|
||||
out << "u";
|
||||
digits = 4;
|
||||
} else {
|
||||
out << "U";
|
||||
digits = 8;
|
||||
}
|
||||
|
||||
// Write digits into the escape sequence
|
||||
for (; digits > 0; --digits)
|
||||
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
|
||||
}
|
||||
|
||||
bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
|
||||
int codePoint;
|
||||
for (std::string::const_iterator i = str.begin();
|
||||
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
|
||||
if (!IsAnchorChar(codePoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteCodePoint(out, codePoint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
StringFormat::value ComputeStringFormat(const std::string& str,
|
||||
EMITTER_MANIP strFormat,
|
||||
FlowType::value flowType,
|
||||
bool escapeNonAscii) {
|
||||
switch (strFormat) {
|
||||
case Auto:
|
||||
if (IsValidPlainScalar(str, flowType, escapeNonAscii)) {
|
||||
return StringFormat::Plain;
|
||||
}
|
||||
return StringFormat::DoubleQuoted;
|
||||
case SingleQuoted:
|
||||
if (IsValidSingleQuotedScalar(str, escapeNonAscii)) {
|
||||
return StringFormat::SingleQuoted;
|
||||
}
|
||||
return StringFormat::DoubleQuoted;
|
||||
case DoubleQuoted:
|
||||
return StringFormat::DoubleQuoted;
|
||||
case Literal:
|
||||
if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) {
|
||||
return StringFormat::Literal;
|
||||
}
|
||||
return StringFormat::DoubleQuoted;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return StringFormat::DoubleQuoted;
|
||||
}
|
||||
|
||||
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
|
||||
out << "'";
|
||||
int codePoint;
|
||||
for (std::string::const_iterator i = str.begin();
|
||||
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
|
||||
if (codePoint == '\n') {
|
||||
return false; // We can't handle a new line and the attendant indentation
|
||||
// yet
|
||||
}
|
||||
|
||||
if (codePoint == '\'') {
|
||||
out << "''";
|
||||
} else {
|
||||
WriteCodePoint(out, codePoint);
|
||||
}
|
||||
}
|
||||
out << "'";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
|
||||
bool escapeNonAscii) {
|
||||
out << "\"";
|
||||
int codePoint;
|
||||
for (std::string::const_iterator i = str.begin();
|
||||
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
|
||||
switch (codePoint) {
|
||||
case '\"':
|
||||
out << "\\\"";
|
||||
break;
|
||||
case '\\':
|
||||
out << "\\\\";
|
||||
break;
|
||||
case '\n':
|
||||
out << "\\n";
|
||||
break;
|
||||
case '\t':
|
||||
out << "\\t";
|
||||
break;
|
||||
case '\r':
|
||||
out << "\\r";
|
||||
break;
|
||||
case '\b':
|
||||
out << "\\b";
|
||||
break;
|
||||
default:
|
||||
if (codePoint < 0x20 ||
|
||||
(codePoint >= 0x80 &&
|
||||
codePoint <= 0xA0)) { // Control characters and non-breaking space
|
||||
WriteDoubleQuoteEscapeSequence(out, codePoint);
|
||||
} else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be
|
||||
// escaped (YAML 1.2, sec. 5.2)
|
||||
WriteDoubleQuoteEscapeSequence(out, codePoint);
|
||||
} else if (escapeNonAscii && codePoint > 0x7E) {
|
||||
WriteDoubleQuoteEscapeSequence(out, codePoint);
|
||||
} else {
|
||||
WriteCodePoint(out, codePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
out << "\"";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
|
||||
std::size_t indent) {
|
||||
out << "|\n";
|
||||
out << IndentTo(indent);
|
||||
int codePoint;
|
||||
for (std::string::const_iterator i = str.begin();
|
||||
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
|
||||
if (codePoint == '\n') {
|
||||
out << "\n" << IndentTo(indent);
|
||||
} else {
|
||||
WriteCodePoint(out, codePoint);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteChar(ostream_wrapper& out, char ch) {
|
||||
if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
|
||||
out << ch;
|
||||
} else if (ch == '\"') {
|
||||
out << "\"\\\"\"";
|
||||
} else if (ch == '\t') {
|
||||
out << "\"\\t\"";
|
||||
} else if (ch == '\n') {
|
||||
out << "\"\\n\"";
|
||||
} else if (ch == '\b') {
|
||||
out << "\"\\b\"";
|
||||
} else if (ch == '\\') {
|
||||
out << "\"\\\\\"";
|
||||
} else if (0x20 <= ch && ch <= 0x7e) {
|
||||
out << "\"" << ch << "\"";
|
||||
} else {
|
||||
out << "\"";
|
||||
WriteDoubleQuoteEscapeSequence(out, ch);
|
||||
out << "\"";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteComment(ostream_wrapper& out, const std::string& str,
|
||||
std::size_t postCommentIndent) {
|
||||
const std::size_t curIndent = out.col();
|
||||
out << "#" << Indentation(postCommentIndent);
|
||||
out.set_comment();
|
||||
int codePoint;
|
||||
for (std::string::const_iterator i = str.begin();
|
||||
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
|
||||
if (codePoint == '\n') {
|
||||
out << "\n"
|
||||
<< IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
|
||||
out.set_comment();
|
||||
} else {
|
||||
WriteCodePoint(out, codePoint);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteAlias(ostream_wrapper& out, const std::string& str) {
|
||||
out << "*";
|
||||
return WriteAliasName(out, str);
|
||||
}
|
||||
|
||||
bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
|
||||
out << "&";
|
||||
return WriteAliasName(out, str);
|
||||
}
|
||||
|
||||
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
|
||||
out << (verbatim ? "!<" : "!");
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
|
||||
while (buffer) {
|
||||
int n = reValid.Match(buffer);
|
||||
if (n <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (--n >= 0) {
|
||||
out << buffer[0];
|
||||
++buffer;
|
||||
}
|
||||
}
|
||||
if (verbatim) {
|
||||
out << ">";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
|
||||
const std::string& tag) {
|
||||
out << "!";
|
||||
StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
|
||||
while (prefixBuffer) {
|
||||
int n = Exp::URI().Match(prefixBuffer);
|
||||
if (n <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (--n >= 0) {
|
||||
out << prefixBuffer[0];
|
||||
++prefixBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
out << "!";
|
||||
StringCharSource tagBuffer(tag.c_str(), tag.size());
|
||||
while (tagBuffer) {
|
||||
int n = Exp::Tag().Match(tagBuffer);
|
||||
if (n <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (--n >= 0) {
|
||||
out << tagBuffer[0];
|
||||
++tagBuffer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
|
||||
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
|
||||
false);
|
||||
return true;
|
||||
}
|
||||
} // namespace Utils
|
||||
} // namespace YAML
|
||||
|
@@ -1,24 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ostream.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
bool WriteString(ostream& out, const std::string& str, bool inFlow);
|
||||
bool WriteSingleQuotedString(ostream& out, const std::string& str);
|
||||
bool WriteDoubleQuotedString(ostream& out, const std::string& str);
|
||||
bool WriteLiteralString(ostream& out, const std::string& str, int indent);
|
||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
|
||||
bool WriteAlias(ostream& out, const std::string& str);
|
||||
bool WriteAnchor(ostream& out, const std::string& str);
|
||||
}
|
||||
#include "emitterstate.h"
|
||||
#include "yaml-cpp/emittermanip.h"
|
||||
#include "yaml-cpp/ostream_wrapper.h"
|
||||
|
||||
namespace YAML {
|
||||
class ostream_wrapper;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class Binary;
|
||||
|
||||
struct StringFormat {
|
||||
enum value { Plain, SingleQuoted, DoubleQuoted, Literal };
|
||||
};
|
||||
|
||||
namespace Utils {
|
||||
StringFormat::value ComputeStringFormat(const std::string& str,
|
||||
EMITTER_MANIP strFormat,
|
||||
FlowType::value flowType,
|
||||
bool escapeNonAscii);
|
||||
|
||||
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
|
||||
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
|
||||
bool escapeNonAscii);
|
||||
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
|
||||
std::size_t indent);
|
||||
bool WriteChar(ostream_wrapper& out, char ch);
|
||||
bool WriteComment(ostream_wrapper& out, const std::string& str,
|
||||
std::size_t postCommentIndent);
|
||||
bool WriteAlias(ostream_wrapper& out, const std::string& str);
|
||||
bool WriteAnchor(ostream_wrapper& out, const std::string& str);
|
||||
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim);
|
||||
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
|
||||
const std::string& tag);
|
||||
bool WriteBinary(ostream_wrapper& out, const Binary& binary);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
31
src/exceptions.cpp
Normal file
31
src/exceptions.cpp
Normal 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
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#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
|
||||
|
||||
|
235
src/exp.cpp
235
src/exp.cpp
@@ -1,113 +1,136 @@
|
||||
#include "crt.h"
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
namespace Exp
|
||||
{
|
||||
unsigned ParseHex(const std::string& str, const Mark& mark)
|
||||
{
|
||||
unsigned value = 0;
|
||||
for(std::size_t i=0;i<str.size();i++) {
|
||||
char ch = str[i];
|
||||
int digit = 0;
|
||||
if('a' <= ch && ch <= 'f')
|
||||
digit = ch - 'a' + 10;
|
||||
else if('A' <= ch && ch <= 'F')
|
||||
digit = ch - 'A' + 10;
|
||||
else if('0' <= ch && ch <= '9')
|
||||
digit = ch - '0';
|
||||
else
|
||||
throw ParserException(mark, ErrorMsg::INVALID_HEX);
|
||||
#include "exp.h"
|
||||
#include "stream.h"
|
||||
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
|
||||
|
||||
value = (value << 4) + digit;
|
||||
}
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
} // namespace YAML
|
||||
|
||||
return value;
|
||||
}
|
||||
namespace YAML {
|
||||
namespace Exp {
|
||||
unsigned ParseHex(const std::string& str, const Mark& mark) {
|
||||
unsigned value = 0;
|
||||
for (std::size_t i = 0; i < str.size(); i++) {
|
||||
char ch = str[i];
|
||||
int digit = 0;
|
||||
if ('a' <= ch && ch <= 'f')
|
||||
digit = ch - 'a' + 10;
|
||||
else if ('A' <= ch && ch <= 'F')
|
||||
digit = ch - 'A' + 10;
|
||||
else if ('0' <= ch && ch <= '9')
|
||||
digit = ch - '0';
|
||||
else
|
||||
throw ParserException(mark, ErrorMsg::INVALID_HEX);
|
||||
|
||||
std::string Str(char ch)
|
||||
{
|
||||
return std::string("") + ch;
|
||||
}
|
||||
value = (value << 4) + digit;
|
||||
}
|
||||
|
||||
// Escape
|
||||
// . Translates the next 'codeLength' characters into a hex number and returns the result.
|
||||
// . Throws if it's not actually hex.
|
||||
std::string Escape(Stream& in, int codeLength)
|
||||
{
|
||||
// grab string
|
||||
std::string str;
|
||||
for(int i=0;i<codeLength;i++)
|
||||
str += in.get();
|
||||
|
||||
// get the value
|
||||
unsigned value = ParseHex(str, in.mark());
|
||||
|
||||
// legal unicode?
|
||||
if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
|
||||
std::stringstream msg;
|
||||
msg << ErrorMsg::INVALID_UNICODE << value;
|
||||
throw ParserException(in.mark(), msg.str());
|
||||
}
|
||||
|
||||
// now break it up into chars
|
||||
if(value <= 0x7F)
|
||||
return Str(value);
|
||||
else if(value <= 0x7FF)
|
||||
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
|
||||
else if(value <= 0xFFFF)
|
||||
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
|
||||
else
|
||||
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
|
||||
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
|
||||
}
|
||||
|
||||
// Escape
|
||||
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
|
||||
// and returns the result.
|
||||
// . Throws if it's an unknown escape character.
|
||||
std::string Escape(Stream& in)
|
||||
{
|
||||
// eat slash
|
||||
char escape = in.get();
|
||||
|
||||
// switch on escape character
|
||||
char ch = in.get();
|
||||
|
||||
// first do single quote, since it's easier
|
||||
if(escape == '\'' && ch == '\'')
|
||||
return "\'";
|
||||
|
||||
// now do the slash (we're not gonna check if it's a slash - you better pass one!)
|
||||
switch(ch) {
|
||||
case '0': return "\0";
|
||||
case 'a': return "\x07";
|
||||
case 'b': return "\x08";
|
||||
case 't':
|
||||
case '\t': return "\x09";
|
||||
case 'n': return "\x0A";
|
||||
case 'v': return "\x0B";
|
||||
case 'f': return "\x0C";
|
||||
case 'r': return "\x0D";
|
||||
case 'e': return "\x1B";
|
||||
case ' ': return "\x20";
|
||||
case '\"': return "\"";
|
||||
case '\'': return "\'";
|
||||
case '\\': return "\\";
|
||||
case 'N': return "\xC2\x85"; // NEL (#x85)
|
||||
case '_': return "\xC2\xA0"; // #xA0
|
||||
case 'L': return "\xE2\x80\xA8"; // LS (#x2028)
|
||||
case 'P': return "\xE2\x80\xA9"; // PS (#x2029)
|
||||
case 'x': return Escape(in, 2);
|
||||
case 'u': return Escape(in, 4);
|
||||
case 'U': return Escape(in, 8);
|
||||
}
|
||||
|
||||
std::stringstream msg;
|
||||
throw ParserException(in.mark(), ErrorMsg::INVALID_ESCAPE + ch);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string Str(unsigned ch) { return std::string(1, static_cast<char>(ch)); }
|
||||
|
||||
// Escape
|
||||
// . Translates the next 'codeLength' characters into a hex number and returns
|
||||
// the result.
|
||||
// . Throws if it's not actually hex.
|
||||
std::string Escape(Stream& in, int codeLength) {
|
||||
// grab string
|
||||
std::string str;
|
||||
for (int i = 0; i < codeLength; i++)
|
||||
str += in.get();
|
||||
|
||||
// get the value
|
||||
unsigned value = ParseHex(str, in.mark());
|
||||
|
||||
// legal unicode?
|
||||
if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
|
||||
std::stringstream msg;
|
||||
msg << ErrorMsg::INVALID_UNICODE << value;
|
||||
throw ParserException(in.mark(), msg.str());
|
||||
}
|
||||
|
||||
// now break it up into chars
|
||||
if (value <= 0x7F)
|
||||
return Str(value);
|
||||
else if (value <= 0x7FF)
|
||||
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
|
||||
else if (value <= 0xFFFF)
|
||||
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
|
||||
Str(0x80 + (value & 0x3F));
|
||||
else
|
||||
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
|
||||
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
|
||||
}
|
||||
|
||||
// Escape
|
||||
// . Escapes the sequence starting 'in' (it must begin with a '\' or single
|
||||
// quote)
|
||||
// and returns the result.
|
||||
// . Throws if it's an unknown escape character.
|
||||
std::string Escape(Stream& in) {
|
||||
// eat slash
|
||||
char escape = in.get();
|
||||
|
||||
// switch on escape character
|
||||
char ch = in.get();
|
||||
|
||||
// first do single quote, since it's easier
|
||||
if (escape == '\'' && ch == '\'')
|
||||
return "\'";
|
||||
|
||||
// now do the slash (we're not gonna check if it's a slash - you better pass
|
||||
// one!)
|
||||
switch (ch) {
|
||||
case '0':
|
||||
return std::string(1, '\x00');
|
||||
case 'a':
|
||||
return "\x07";
|
||||
case 'b':
|
||||
return "\x08";
|
||||
case 't':
|
||||
case '\t':
|
||||
return "\x09";
|
||||
case 'n':
|
||||
return "\x0A";
|
||||
case 'v':
|
||||
return "\x0B";
|
||||
case 'f':
|
||||
return "\x0C";
|
||||
case 'r':
|
||||
return "\x0D";
|
||||
case 'e':
|
||||
return "\x1B";
|
||||
case ' ':
|
||||
return "\x20";
|
||||
case '\"':
|
||||
return "\"";
|
||||
case '\'':
|
||||
return "\'";
|
||||
case '\\':
|
||||
return "\\";
|
||||
case '/':
|
||||
return "/";
|
||||
case 'N':
|
||||
return "\x85";
|
||||
case '_':
|
||||
return "\xA0";
|
||||
case 'L':
|
||||
return "\xE2\x80\xA8"; // LS (#x2028)
|
||||
case 'P':
|
||||
return "\xE2\x80\xA9"; // PS (#x2029)
|
||||
case 'x':
|
||||
return Escape(in, 2);
|
||||
case 'u':
|
||||
return Escape(in, 4);
|
||||
case 'U':
|
||||
return Escape(in, 8);
|
||||
}
|
||||
|
||||
std::stringstream msg;
|
||||
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
282
src/exp.h
282
src/exp.h
@@ -1,80 +1,222 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "regex.h"
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
|
||||
#include "regex_yaml.h"
|
||||
#include "stream.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Here we store a bunch of expressions for matching different parts of the file.
|
||||
namespace YAML {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Here we store a bunch of expressions for matching different parts of the
|
||||
// file.
|
||||
|
||||
namespace Exp
|
||||
{
|
||||
// misc
|
||||
const RegEx Space = RegEx(' ');
|
||||
const RegEx Tab = RegEx('\t');
|
||||
const RegEx Blank = Space || Tab;
|
||||
const RegEx Break = RegEx('\n') || RegEx("\r\n");
|
||||
const RegEx BlankOrBreak = Blank || Break;
|
||||
const RegEx Digit = RegEx('0', '9');
|
||||
const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z');
|
||||
const RegEx AlphaNumeric = Alpha || Digit;
|
||||
const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f');
|
||||
const RegEx Printable = RegEx(0x20, 0x7E);
|
||||
|
||||
// actual tags
|
||||
|
||||
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx());
|
||||
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx());
|
||||
const RegEx DocIndicator = DocStart || DocEnd;
|
||||
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx());
|
||||
const RegEx Key = RegEx('?'),
|
||||
KeyInFlow = RegEx('?') + BlankOrBreak;
|
||||
const RegEx Value = RegEx(':') + (BlankOrBreak || RegEx()),
|
||||
ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR));
|
||||
const RegEx Comment = RegEx('#');
|
||||
const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak;
|
||||
|
||||
// Plain scalar rules:
|
||||
// . Cannot start with a blank.
|
||||
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
|
||||
// . In the block context - ? : must be not be followed with a space.
|
||||
// . In the flow context ? is illegal and : and - must not be followed with a space.
|
||||
const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)),
|
||||
PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank));
|
||||
const RegEx EndScalar = RegEx(':') + (BlankOrBreak || RegEx()),
|
||||
EndScalarInFlow = (RegEx(':') + (BlankOrBreak || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
|
||||
|
||||
const RegEx EscSingleQuote = RegEx("\'\'");
|
||||
const RegEx EscBreak = RegEx('\\') + Break;
|
||||
|
||||
const RegEx ChompIndicator = RegEx("+-", REGEX_OR);
|
||||
const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit;
|
||||
|
||||
// and some functions
|
||||
std::string Escape(Stream& in);
|
||||
}
|
||||
|
||||
namespace Keys
|
||||
{
|
||||
const char Directive = '%';
|
||||
const char FlowSeqStart = '[';
|
||||
const char FlowSeqEnd = ']';
|
||||
const char FlowMapStart = '{';
|
||||
const char FlowMapEnd = '}';
|
||||
const char FlowEntry = ',';
|
||||
const char Alias = '*';
|
||||
const char Anchor = '&';
|
||||
const char Tag = '!';
|
||||
const char LiteralScalar = '|';
|
||||
const char FoldedScalar = '>';
|
||||
}
|
||||
namespace Exp {
|
||||
// misc
|
||||
inline const RegEx& Empty() {
|
||||
static const RegEx e;
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Space() {
|
||||
static const RegEx e = RegEx(' ');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Tab() {
|
||||
static const RegEx e = RegEx('\t');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Blank() {
|
||||
static const RegEx e = Space() | Tab();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Break() {
|
||||
static const RegEx e = RegEx('\n') | RegEx("\r\n");
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& BlankOrBreak() {
|
||||
static const RegEx e = Blank() | Break();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Digit() {
|
||||
static const RegEx e = RegEx('0', '9');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Alpha() {
|
||||
static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& AlphaNumeric() {
|
||||
static const RegEx e = Alpha() | Digit();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Word() {
|
||||
static const RegEx e = AlphaNumeric() | RegEx('-');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Hex() {
|
||||
static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f');
|
||||
return e;
|
||||
}
|
||||
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
|
||||
// 5.1)
|
||||
inline const RegEx& NotPrintable() {
|
||||
static const RegEx e =
|
||||
RegEx(0) |
|
||||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) |
|
||||
RegEx(0x0E, 0x1F) |
|
||||
(RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F')));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Utf8_ByteOrderMark() {
|
||||
static const RegEx e = RegEx("\xEF\xBB\xBF");
|
||||
return e;
|
||||
}
|
||||
|
||||
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
// actual tags
|
||||
|
||||
inline const RegEx& DocStart() {
|
||||
static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& DocEnd() {
|
||||
static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& DocIndicator() {
|
||||
static const RegEx e = DocStart() | DocEnd();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& BlockEntry() {
|
||||
static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Key() {
|
||||
static const RegEx e = RegEx('?') + BlankOrBreak();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& KeyInFlow() {
|
||||
static const RegEx e = RegEx('?') + BlankOrBreak();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Value() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& ValueInFlow() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",}", REGEX_OR));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& ValueInJSONFlow() {
|
||||
static const RegEx e = RegEx(':');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx Comment() {
|
||||
static const RegEx e = RegEx('#');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Anchor() {
|
||||
static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& AnchorEnd() {
|
||||
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& URI() {
|
||||
static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
|
||||
(RegEx('%') + Hex() + Hex());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Tag() {
|
||||
static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
|
||||
(RegEx('%') + Hex() + Hex());
|
||||
return e;
|
||||
}
|
||||
|
||||
// Plain scalar rules:
|
||||
// . Cannot start with a blank.
|
||||
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
|
||||
// . In the block context - ? : must be not be followed with a space.
|
||||
// . In the flow context ? is illegal and : and - must not be followed with a
|
||||
// space.
|
||||
inline const RegEx& PlainScalar() {
|
||||
static const RegEx e =
|
||||
!(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
|
||||
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& PlainScalarInFlow() {
|
||||
static const RegEx e =
|
||||
!(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
|
||||
(RegEx("-:", REGEX_OR) + Blank()));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EndScalar() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EndScalarInFlow() {
|
||||
static const RegEx e =
|
||||
(RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
|
||||
RegEx(",?[]{}", REGEX_OR);
|
||||
return e;
|
||||
}
|
||||
|
||||
inline const RegEx& ScanScalarEndInFlow() {
|
||||
static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
|
||||
return e;
|
||||
}
|
||||
|
||||
inline const RegEx& ScanScalarEnd() {
|
||||
static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EscSingleQuote() {
|
||||
static const RegEx e = RegEx("\'\'");
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EscBreak() {
|
||||
static const RegEx e = RegEx('\\') + Break();
|
||||
return e;
|
||||
}
|
||||
|
||||
inline const RegEx& ChompIndicator() {
|
||||
static const RegEx e = RegEx("+-", REGEX_OR);
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Chomp() {
|
||||
static const RegEx e = (ChompIndicator() + Digit()) |
|
||||
(Digit() + ChompIndicator()) | ChompIndicator() |
|
||||
Digit();
|
||||
return e;
|
||||
}
|
||||
|
||||
// and some functions
|
||||
std::string Escape(Stream& in);
|
||||
} // namespace Exp
|
||||
|
||||
namespace Keys {
|
||||
const char Directive = '%';
|
||||
const char FlowSeqStart = '[';
|
||||
const char FlowSeqEnd = ']';
|
||||
const char FlowMapStart = '{';
|
||||
const char FlowMapEnd = '}';
|
||||
const char FlowEntry = ',';
|
||||
const char Alias = '*';
|
||||
const char Anchor = '&';
|
||||
const char Tag = '!';
|
||||
const char LiteralScalar = '|';
|
||||
const char FoldedScalar = '>';
|
||||
const char VerbatimTagStart = '<';
|
||||
const char VerbatimTagEnd = '>';
|
||||
} // namespace Keys
|
||||
} // namespace YAML
|
||||
|
||||
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
@@ -1,36 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ostream.h"
|
||||
#include <iostream>
|
||||
#include <cstddef>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Indentation {
|
||||
Indentation(unsigned n_): n(n_) {}
|
||||
unsigned n;
|
||||
};
|
||||
|
||||
inline ostream& operator << (ostream& out, const Indentation& indent) {
|
||||
for(unsigned i=0;i<indent.n;i++)
|
||||
out << ' ';
|
||||
return out;
|
||||
}
|
||||
#include "yaml-cpp/ostream_wrapper.h"
|
||||
|
||||
struct IndentTo {
|
||||
IndentTo(unsigned n_): n(n_) {}
|
||||
unsigned n;
|
||||
};
|
||||
|
||||
inline ostream& operator << (ostream& out, const IndentTo& indent) {
|
||||
while(out.col() < indent.n)
|
||||
out << ' ';
|
||||
return out;
|
||||
}
|
||||
namespace YAML {
|
||||
struct Indentation {
|
||||
Indentation(std::size_t n_) : n(n_) {}
|
||||
std::size_t n;
|
||||
};
|
||||
|
||||
inline ostream_wrapper& operator<<(ostream_wrapper& out,
|
||||
const Indentation& indent) {
|
||||
for (std::size_t i = 0; i < indent.n; i++)
|
||||
out << ' ';
|
||||
return out;
|
||||
}
|
||||
|
||||
struct IndentTo {
|
||||
IndentTo(std::size_t n_) : n(n_) {}
|
||||
std::size_t n;
|
||||
};
|
||||
|
||||
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
inline ostream_wrapper& operator<<(ostream_wrapper& out,
|
||||
const IndentTo& indent) {
|
||||
while (out.col() < indent.n)
|
||||
out << ' ';
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
108
src/iterator.cpp
108
src/iterator.cpp
@@ -1,108 +0,0 @@
|
||||
#include "crt.h"
|
||||
#include "node.h"
|
||||
#include "exceptions.h"
|
||||
#include "iterpriv.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Iterator::Iterator(): m_pData(0)
|
||||
{
|
||||
m_pData = new IterPriv;
|
||||
}
|
||||
|
||||
Iterator::Iterator(IterPriv *pData): m_pData(pData)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator::Iterator(const Iterator& rhs): m_pData(0)
|
||||
{
|
||||
m_pData = new IterPriv(*rhs.m_pData);
|
||||
}
|
||||
|
||||
Iterator& Iterator::operator = (const Iterator& rhs)
|
||||
{
|
||||
if(this == &rhs)
|
||||
return *this;
|
||||
|
||||
delete m_pData;
|
||||
m_pData = new IterPriv(*rhs.m_pData);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator::~Iterator()
|
||||
{
|
||||
delete m_pData;
|
||||
}
|
||||
|
||||
Iterator& Iterator::operator ++ ()
|
||||
{
|
||||
if(m_pData->type == IterPriv::IT_SEQ)
|
||||
++m_pData->seqIter;
|
||||
else if(m_pData->type == IterPriv::IT_MAP)
|
||||
++m_pData->mapIter;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator Iterator::operator ++ (int)
|
||||
{
|
||||
Iterator temp = *this;
|
||||
|
||||
if(m_pData->type == IterPriv::IT_SEQ)
|
||||
++m_pData->seqIter;
|
||||
else if(m_pData->type == IterPriv::IT_MAP)
|
||||
++m_pData->mapIter;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
const Node& Iterator::operator * () const
|
||||
{
|
||||
if(m_pData->type == IterPriv::IT_SEQ)
|
||||
return **m_pData->seqIter;
|
||||
|
||||
throw BadDereference();
|
||||
}
|
||||
|
||||
const Node *Iterator::operator -> () const
|
||||
{
|
||||
if(m_pData->type == IterPriv::IT_SEQ)
|
||||
return *m_pData->seqIter;
|
||||
|
||||
throw BadDereference();
|
||||
}
|
||||
|
||||
const Node& Iterator::first() const
|
||||
{
|
||||
if(m_pData->type == IterPriv::IT_MAP)
|
||||
return *m_pData->mapIter->first;
|
||||
|
||||
throw BadDereference();
|
||||
}
|
||||
|
||||
const Node& Iterator::second() const
|
||||
{
|
||||
if(m_pData->type == IterPriv::IT_MAP)
|
||||
return *m_pData->mapIter->second;
|
||||
|
||||
throw BadDereference();
|
||||
}
|
||||
|
||||
bool operator == (const Iterator& it, const Iterator& jt)
|
||||
{
|
||||
if(it.m_pData->type != jt.m_pData->type)
|
||||
return false;
|
||||
|
||||
if(it.m_pData->type == IterPriv::IT_SEQ)
|
||||
return it.m_pData->seqIter == jt.m_pData->seqIter;
|
||||
else if(it.m_pData->type == IterPriv::IT_MAP)
|
||||
return it.m_pData->mapIter == jt.m_pData->mapIter;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator != (const Iterator& it, const Iterator& jt)
|
||||
{
|
||||
return !(it == jt);
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "ltnode.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
// IterPriv
|
||||
// . The implementation for iterators - essentially a union of sequence and map iterators.
|
||||
struct IterPriv
|
||||
{
|
||||
IterPriv(): type(IT_NONE) {}
|
||||
IterPriv(std::vector <Node *>::const_iterator it): type(IT_SEQ), seqIter(it) {}
|
||||
IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): type(IT_MAP), mapIter(it) {}
|
||||
|
||||
enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
|
||||
ITER_TYPE type;
|
||||
|
||||
std::vector <Node *>::const_iterator seqIter;
|
||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ITERPRIV_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
16
src/ltnode.h
16
src/ltnode.h
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
struct ltnode {
|
||||
bool operator()(const Node *pNode1, const Node *pNode2) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LTNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
189
src/map.cpp
189
src/map.cpp
@@ -1,189 +0,0 @@
|
||||
#include "crt.h"
|
||||
#include "map.h"
|
||||
#include "node.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "emitter.h"
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Map::Map()
|
||||
{
|
||||
}
|
||||
|
||||
Map::Map(const node_map& data)
|
||||
{
|
||||
for(node_map::const_iterator it=data.begin();it!=data.end();++it) {
|
||||
std::auto_ptr<Node> pKey = it->first->Clone();
|
||||
std::auto_ptr<Node> pValue = it->second->Clone();
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
}
|
||||
|
||||
Map::~Map()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Map::Clear()
|
||||
{
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
|
||||
delete it->first;
|
||||
delete it->second;
|
||||
}
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Content *Map::Clone() const
|
||||
{
|
||||
return new Map(m_data);
|
||||
}
|
||||
|
||||
bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.begin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.end();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t Map::GetSize() const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Map::Parse(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// split based on start token
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
||||
case Token::FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
||||
|
||||
Token token = pScanner->peek();
|
||||
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
|
||||
|
||||
if(token.type == Token::BLOCK_MAP_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// assign the map with the actual pointers
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
Token& token = pScanner->peek();
|
||||
// first check for end
|
||||
if(token.type == Token::FLOW_MAP_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& nextToken = pScanner->peek();
|
||||
if(nextToken.type == Token::FLOW_ENTRY)
|
||||
pScanner->pop();
|
||||
else if(nextToken.type != Token::FLOW_MAP_END)
|
||||
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
// assign the map with the actual pointers
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::Write(Emitter& out) const
|
||||
{
|
||||
out << BeginMap;
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it)
|
||||
out << Key << *it->first << Value << *it->second;
|
||||
out << EndMap;
|
||||
}
|
||||
|
||||
int Map::Compare(Content *pContent)
|
||||
{
|
||||
return -pContent->Compare(this);
|
||||
}
|
||||
|
||||
int Map::Compare(Map *pMap)
|
||||
{
|
||||
node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin();
|
||||
while(1) {
|
||||
if(it == m_data.end()) {
|
||||
if(jt == pMap->m_data.end())
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if(jt == pMap->m_data.end())
|
||||
return 1;
|
||||
|
||||
int cmp = it->first->Compare(*jt->first);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
|
||||
cmp = it->second->Compare(*jt->second);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
50
src/map.h
50
src/map.h
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "content.h"
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class Map: public Content
|
||||
{
|
||||
private:
|
||||
typedef std::map <Node *, Node *, ltnode> node_map;
|
||||
|
||||
public:
|
||||
Map();
|
||||
Map(const node_map& data);
|
||||
virtual ~Map();
|
||||
|
||||
void Clear();
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsMap() const { return true; }
|
||||
|
||||
// ordering
|
||||
virtual int Compare(Content *pContent);
|
||||
virtual int Compare(Scalar *) { return 1; }
|
||||
virtual int Compare(Sequence *) { return 1; }
|
||||
virtual int Compare(Map *pMap);
|
||||
|
||||
private:
|
||||
void ParseBlock(Scanner *pScanner, const ParserState& state);
|
||||
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
private:
|
||||
node_map m_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
26
src/memory.cpp
Normal file
26
src/memory.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
|
||||
void memory_holder::merge(memory_holder& rhs) {
|
||||
if (m_pMemory == rhs.m_pMemory)
|
||||
return;
|
||||
|
||||
m_pMemory->merge(*rhs.m_pMemory);
|
||||
rhs.m_pMemory = m_pMemory;
|
||||
}
|
||||
|
||||
node& memory::create_node() {
|
||||
shared_node pNode(new node);
|
||||
m_nodes.insert(pNode);
|
||||
return *pNode;
|
||||
}
|
||||
|
||||
void memory::merge(const memory& rhs) {
|
||||
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
|
||||
}
|
||||
}
|
||||
}
|
300
src/node.cpp
300
src/node.cpp
@@ -1,292 +1,12 @@
|
||||
#include "crt.h"
|
||||
#include "node.h"
|
||||
#include "token.h"
|
||||
#include "scanner.h"
|
||||
#include "content.h"
|
||||
#include "parser.h"
|
||||
#include "scalar.h"
|
||||
#include "sequence.h"
|
||||
#include "map.h"
|
||||
#include "aliascontent.h"
|
||||
#include "iterpriv.h"
|
||||
#include "emitter.h"
|
||||
#include <stdexcept>
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "nodebuilder.h"
|
||||
#include "nodeevents.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
// the ordering!
|
||||
bool ltnode::operator ()(const Node *pNode1, const Node *pNode2) const
|
||||
{
|
||||
return *pNode1 < *pNode2;
|
||||
}
|
||||
|
||||
Node::Node(): m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(true)
|
||||
{
|
||||
}
|
||||
|
||||
Node::Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent)
|
||||
: m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
|
||||
{
|
||||
if(m_pContent)
|
||||
m_pContent = pContent->Clone();
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Node::Clear()
|
||||
{
|
||||
delete m_pContent;
|
||||
m_pContent = 0;
|
||||
m_alias = false;
|
||||
m_referenced = false;
|
||||
m_anchor.clear();
|
||||
m_tag.clear();
|
||||
}
|
||||
|
||||
std::auto_ptr<Node> Node::Clone() const
|
||||
{
|
||||
if(m_alias)
|
||||
throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases?
|
||||
|
||||
return std::auto_ptr<Node> (new Node(m_mark, m_anchor, m_tag, m_pContent));
|
||||
}
|
||||
|
||||
void Node::Parse(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// an empty node *is* a possibility
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
// save location
|
||||
m_mark = pScanner->peek().mark;
|
||||
|
||||
ParseHeader(pScanner, state);
|
||||
|
||||
// is this an alias? if so, its contents are an alias to
|
||||
// a previously defined anchor
|
||||
if(m_alias) {
|
||||
// the scanner throws an exception if it doesn't know this anchor name
|
||||
const Node *pReferencedNode = pScanner->Retrieve(m_anchor);
|
||||
m_pIdentity = pReferencedNode;
|
||||
|
||||
// mark the referenced node for the sake of the client code
|
||||
pReferencedNode->m_referenced = true;
|
||||
|
||||
// use of an Alias object keeps the referenced content from
|
||||
// being deleted twice
|
||||
Content *pAliasedContent = pReferencedNode->m_pContent;
|
||||
if(pAliasedContent)
|
||||
m_pContent = new AliasContent(pAliasedContent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// now split based on what kind of node we should be
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::SCALAR:
|
||||
m_pContent = new Scalar;
|
||||
break;
|
||||
case Token::FLOW_SEQ_START:
|
||||
case Token::BLOCK_SEQ_START:
|
||||
m_pContent = new Sequence;
|
||||
break;
|
||||
case Token::FLOW_MAP_START:
|
||||
case Token::BLOCK_MAP_START:
|
||||
m_pContent = new Map;
|
||||
break;
|
||||
default:
|
||||
// std::stringstream str;
|
||||
// str << TokenNames[pScanner->peek().type];
|
||||
// throw std::runtime_error(str.str());
|
||||
break;
|
||||
}
|
||||
|
||||
// Have to save anchor before parsing to allow for aliases as
|
||||
// contained node (recursive structure)
|
||||
if(!m_anchor.empty())
|
||||
pScanner->Save(m_anchor, this);
|
||||
|
||||
if(m_pContent)
|
||||
m_pContent->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// ParseHeader
|
||||
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
||||
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::TAG: ParseTag(pScanner, state); break;
|
||||
case Token::ANCHOR: ParseAnchor(pScanner, state); break;
|
||||
case Token::ALIAS: ParseAlias(pScanner, state); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
||||
|
||||
m_tag = state.TranslateTag(token.value);
|
||||
|
||||
for(std::size_t i=0;i<token.params.size();i++)
|
||||
m_tag += token.params[i];
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Node::ParseAnchor(Scanner *pScanner, const ParserState& /*state*/)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = false;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Node::ParseAlias(Scanner *pScanner, const ParserState& /*state*/)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ALIASES);
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::ALIAS_CONTENT);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = true;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
CONTENT_TYPE Node::GetType() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return CT_NONE;
|
||||
|
||||
if(m_pContent->IsScalar())
|
||||
return CT_SCALAR;
|
||||
else if(m_pContent->IsSequence())
|
||||
return CT_SEQUENCE;
|
||||
else if(m_pContent->IsMap())
|
||||
return CT_MAP;
|
||||
|
||||
return CT_NONE;
|
||||
}
|
||||
|
||||
// begin
|
||||
// Returns an iterator to the beginning of this (sequence or map).
|
||||
Iterator Node::begin() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return Iterator();
|
||||
|
||||
std::vector <Node *>::const_iterator seqIter;
|
||||
if(m_pContent->GetBegin(seqIter))
|
||||
return Iterator(new IterPriv(seqIter));
|
||||
|
||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
||||
if(m_pContent->GetBegin(mapIter))
|
||||
return Iterator(new IterPriv(mapIter));
|
||||
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
// end
|
||||
// . Returns an iterator to the end of this (sequence or map).
|
||||
Iterator Node::end() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return Iterator();
|
||||
|
||||
std::vector <Node *>::const_iterator seqIter;
|
||||
if(m_pContent->GetEnd(seqIter))
|
||||
return Iterator(new IterPriv(seqIter));
|
||||
|
||||
std::map <Node *, Node *, ltnode>::const_iterator mapIter;
|
||||
if(m_pContent->GetEnd(mapIter))
|
||||
return Iterator(new IterPriv(mapIter));
|
||||
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
// size
|
||||
// . Returns the size of this node, if it's a sequence node.
|
||||
// . Otherwise, returns zero.
|
||||
std::size_t Node::size() const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return 0;
|
||||
|
||||
return m_pContent->GetSize();
|
||||
}
|
||||
|
||||
const Node *Node::FindAtIndex(std::size_t i) const
|
||||
{
|
||||
if(!m_pContent)
|
||||
return 0;
|
||||
|
||||
return m_pContent->GetNode(i);
|
||||
}
|
||||
|
||||
bool Node::GetScalar(std::string& s) const
|
||||
{
|
||||
if(!m_pContent) {
|
||||
s = "~";
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pContent->GetScalar(s);
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const Node& node)
|
||||
{
|
||||
// write anchor/alias
|
||||
if(node.m_anchor != "") {
|
||||
if(node.m_alias)
|
||||
out << Alias(node.m_anchor);
|
||||
else
|
||||
out << Anchor(node.m_anchor);
|
||||
}
|
||||
|
||||
// TODO: write tag
|
||||
|
||||
// write content
|
||||
if(node.m_pContent)
|
||||
node.m_pContent->Write(out);
|
||||
else if(!node.m_alias)
|
||||
out << Null;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int Node::Compare(const Node& rhs) const
|
||||
{
|
||||
// Step 1: no content is the smallest
|
||||
if(!m_pContent) {
|
||||
if(rhs.m_pContent)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if(!rhs.m_pContent)
|
||||
return 1;
|
||||
|
||||
return m_pContent->Compare(rhs.m_pContent);
|
||||
}
|
||||
|
||||
bool operator < (const Node& n1, const Node& n2)
|
||||
{
|
||||
return n1.Compare(n2) < 0;
|
||||
}
|
||||
namespace YAML {
|
||||
Node Clone(const Node& node) {
|
||||
NodeEvents events(node);
|
||||
NodeBuilder builder;
|
||||
events.Emit(builder);
|
||||
return builder.Root();
|
||||
}
|
||||
}
|
||||
|
316
src/node_data.cpp
Normal file
316
src/node_data.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
#include <assert.h>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include "yaml-cpp/exceptions.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
|
||||
#include "yaml-cpp/node/detail/node_data.h"
|
||||
#include "yaml-cpp/node/detail/node_iterator.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
|
||||
const std::string& node_data::empty_scalar() {
|
||||
static const std::string svalue;
|
||||
return svalue;
|
||||
}
|
||||
|
||||
node_data::node_data()
|
||||
: m_isDefined(false),
|
||||
m_mark(Mark::null_mark()),
|
||||
m_type(NodeType::Null),
|
||||
m_tag{},
|
||||
m_style(EmitterStyle::Default),
|
||||
m_scalar{},
|
||||
m_sequence{},
|
||||
m_seqSize(0),
|
||||
m_map{},
|
||||
m_undefinedPairs{} {}
|
||||
|
||||
void node_data::mark_defined() {
|
||||
if (m_type == NodeType::Undefined)
|
||||
m_type = NodeType::Null;
|
||||
m_isDefined = true;
|
||||
}
|
||||
|
||||
void node_data::set_mark(const Mark& mark) { m_mark = mark; }
|
||||
|
||||
void node_data::set_type(NodeType::value type) {
|
||||
if (type == NodeType::Undefined) {
|
||||
m_type = type;
|
||||
m_isDefined = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDefined = true;
|
||||
if (type == m_type)
|
||||
return;
|
||||
|
||||
m_type = type;
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Null:
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
m_scalar.clear();
|
||||
break;
|
||||
case NodeType::Sequence:
|
||||
reset_sequence();
|
||||
break;
|
||||
case NodeType::Map:
|
||||
reset_map();
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void node_data::set_tag(const std::string& tag) { m_tag = tag; }
|
||||
|
||||
void node_data::set_style(EmitterStyle::value style) { m_style = style; }
|
||||
|
||||
void node_data::set_null() {
|
||||
m_isDefined = true;
|
||||
m_type = NodeType::Null;
|
||||
}
|
||||
|
||||
void node_data::set_scalar(const std::string& scalar) {
|
||||
m_isDefined = true;
|
||||
m_type = NodeType::Scalar;
|
||||
m_scalar = scalar;
|
||||
}
|
||||
|
||||
// size/iterator
|
||||
std::size_t node_data::size() const {
|
||||
if (!m_isDefined)
|
||||
return 0;
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Sequence:
|
||||
compute_seq_size();
|
||||
return m_seqSize;
|
||||
case NodeType::Map:
|
||||
compute_map_size();
|
||||
return m_map.size() - m_undefinedPairs.size();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void node_data::compute_seq_size() const {
|
||||
while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
|
||||
m_seqSize++;
|
||||
}
|
||||
|
||||
void node_data::compute_map_size() const {
|
||||
kv_pairs::iterator it = m_undefinedPairs.begin();
|
||||
while (it != m_undefinedPairs.end()) {
|
||||
kv_pairs::iterator jt = std::next(it);
|
||||
if (it->first->is_defined() && it->second->is_defined())
|
||||
m_undefinedPairs.erase(it);
|
||||
it = jt;
|
||||
}
|
||||
}
|
||||
|
||||
const_node_iterator node_data::begin() const {
|
||||
if (!m_isDefined)
|
||||
return const_node_iterator();
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Sequence:
|
||||
return const_node_iterator(m_sequence.begin());
|
||||
case NodeType::Map:
|
||||
return const_node_iterator(m_map.begin(), m_map.end());
|
||||
default:
|
||||
return const_node_iterator();
|
||||
}
|
||||
}
|
||||
|
||||
node_iterator node_data::begin() {
|
||||
if (!m_isDefined)
|
||||
return node_iterator();
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Sequence:
|
||||
return node_iterator(m_sequence.begin());
|
||||
case NodeType::Map:
|
||||
return node_iterator(m_map.begin(), m_map.end());
|
||||
default:
|
||||
return node_iterator();
|
||||
}
|
||||
}
|
||||
|
||||
const_node_iterator node_data::end() const {
|
||||
if (!m_isDefined)
|
||||
return const_node_iterator();
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Sequence:
|
||||
return const_node_iterator(m_sequence.end());
|
||||
case NodeType::Map:
|
||||
return const_node_iterator(m_map.end(), m_map.end());
|
||||
default:
|
||||
return const_node_iterator();
|
||||
}
|
||||
}
|
||||
|
||||
node_iterator node_data::end() {
|
||||
if (!m_isDefined)
|
||||
return node_iterator();
|
||||
|
||||
switch (m_type) {
|
||||
case NodeType::Sequence:
|
||||
return node_iterator(m_sequence.end());
|
||||
case NodeType::Map:
|
||||
return node_iterator(m_map.end(), m_map.end());
|
||||
default:
|
||||
return node_iterator();
|
||||
}
|
||||
}
|
||||
|
||||
// sequence
|
||||
void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
|
||||
if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
|
||||
m_type = NodeType::Sequence;
|
||||
reset_sequence();
|
||||
}
|
||||
|
||||
if (m_type != NodeType::Sequence)
|
||||
throw BadPushback();
|
||||
|
||||
m_sequence.push_back(&node);
|
||||
}
|
||||
|
||||
void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||
switch (m_type) {
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
case NodeType::Sequence:
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
insert_map_pair(key, value);
|
||||
}
|
||||
|
||||
// indexing
|
||||
node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
|
||||
if (m_type != NodeType::Map) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
if (it->first->is(key))
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node& node_data::get(node& key, shared_memory_holder pMemory) {
|
||||
switch (m_type) {
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
case NodeType::Sequence:
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
if (it->first->is(key))
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
node& value = pMemory->create_node();
|
||||
insert_map_pair(key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
|
||||
if (m_type != NodeType::Map)
|
||||
return false;
|
||||
|
||||
for (kv_pairs::iterator it = m_undefinedPairs.begin();
|
||||
it != m_undefinedPairs.end();) {
|
||||
kv_pairs::iterator jt = std::next(it);
|
||||
if (it->first->is(key))
|
||||
m_undefinedPairs.erase(it);
|
||||
it = jt;
|
||||
}
|
||||
|
||||
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
if (it->first->is(key)) {
|
||||
m_map.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void node_data::reset_sequence() {
|
||||
m_sequence.clear();
|
||||
m_seqSize = 0;
|
||||
}
|
||||
|
||||
void node_data::reset_map() {
|
||||
m_map.clear();
|
||||
m_undefinedPairs.clear();
|
||||
}
|
||||
|
||||
void node_data::insert_map_pair(node& key, node& value) {
|
||||
m_map.emplace_back(&key, &value);
|
||||
|
||||
if (!key.is_defined() || !value.is_defined())
|
||||
m_undefinedPairs.emplace_back(&key, &value);
|
||||
}
|
||||
|
||||
void node_data::convert_to_map(shared_memory_holder pMemory) {
|
||||
switch (m_type) {
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
reset_map();
|
||||
m_type = NodeType::Map;
|
||||
break;
|
||||
case NodeType::Sequence:
|
||||
convert_sequence_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Map:
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
|
||||
assert(m_type == NodeType::Sequence);
|
||||
|
||||
reset_map();
|
||||
for (std::size_t i = 0; i < m_sequence.size(); i++) {
|
||||
std::stringstream stream;
|
||||
stream << i;
|
||||
|
||||
node& key = pMemory->create_node();
|
||||
key.set_scalar(stream.str());
|
||||
insert_map_pair(key, *m_sequence[i]);
|
||||
}
|
||||
|
||||
reset_sequence();
|
||||
m_type = NodeType::Map;
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
135
src/nodebuilder.cpp
Normal file
135
src/nodebuilder.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <assert.h>
|
||||
#include <cassert>
|
||||
|
||||
#include "nodebuilder.h"
|
||||
#include "yaml-cpp/node/detail/node.h"
|
||||
#include "yaml-cpp/node/impl.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
struct Mark;
|
||||
|
||||
NodeBuilder::NodeBuilder()
|
||||
: m_pMemory(new detail::memory_holder),
|
||||
m_pRoot(nullptr),
|
||||
m_stack{},
|
||||
m_anchors{},
|
||||
m_keys{},
|
||||
m_mapDepth(0) {
|
||||
m_anchors.push_back(nullptr); // since the anchors start at 1
|
||||
}
|
||||
|
||||
NodeBuilder::~NodeBuilder() {}
|
||||
|
||||
Node NodeBuilder::Root() {
|
||||
if (!m_pRoot)
|
||||
return Node();
|
||||
|
||||
return Node(*m_pRoot, m_pMemory);
|
||||
}
|
||||
|
||||
void NodeBuilder::OnDocumentStart(const Mark&) {}
|
||||
|
||||
void NodeBuilder::OnDocumentEnd() {}
|
||||
|
||||
void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
|
||||
detail::node& node = Push(mark, anchor);
|
||||
node.set_null();
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
|
||||
detail::node& node = *m_anchors[anchor];
|
||||
Push(node);
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value) {
|
||||
detail::node& node = Push(mark, anchor);
|
||||
node.set_scalar(value);
|
||||
node.set_tag(tag);
|
||||
Pop();
|
||||
}
|
||||
|
||||
void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style) {
|
||||
detail::node& node = Push(mark, anchor);
|
||||
node.set_tag(tag);
|
||||
node.set_type(NodeType::Sequence);
|
||||
node.set_style(style);
|
||||
}
|
||||
|
||||
void NodeBuilder::OnSequenceEnd() { Pop(); }
|
||||
|
||||
void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style) {
|
||||
detail::node& node = Push(mark, anchor);
|
||||
node.set_type(NodeType::Map);
|
||||
node.set_tag(tag);
|
||||
node.set_style(style);
|
||||
m_mapDepth++;
|
||||
}
|
||||
|
||||
void NodeBuilder::OnMapEnd() {
|
||||
assert(m_mapDepth > 0);
|
||||
m_mapDepth--;
|
||||
Pop();
|
||||
}
|
||||
|
||||
detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
|
||||
detail::node& node = m_pMemory->create_node();
|
||||
node.set_mark(mark);
|
||||
RegisterAnchor(anchor, node);
|
||||
Push(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
void NodeBuilder::Push(detail::node& node) {
|
||||
const bool needsKey =
|
||||
(!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
|
||||
m_keys.size() < m_mapDepth);
|
||||
|
||||
m_stack.push_back(&node);
|
||||
if (needsKey)
|
||||
m_keys.push_back(PushedKey(&node, false));
|
||||
}
|
||||
|
||||
void NodeBuilder::Pop() {
|
||||
assert(!m_stack.empty());
|
||||
if (m_stack.size() == 1) {
|
||||
m_pRoot = m_stack[0];
|
||||
m_stack.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
detail::node& node = *m_stack.back();
|
||||
m_stack.pop_back();
|
||||
|
||||
detail::node& collection = *m_stack.back();
|
||||
|
||||
if (collection.type() == NodeType::Sequence) {
|
||||
collection.push_back(node, m_pMemory);
|
||||
} else if (collection.type() == NodeType::Map) {
|
||||
assert(!m_keys.empty());
|
||||
PushedKey& key = m_keys.back();
|
||||
if (key.second) {
|
||||
collection.insert(*key.first, node, m_pMemory);
|
||||
m_keys.pop_back();
|
||||
} else {
|
||||
key.second = true;
|
||||
}
|
||||
} else {
|
||||
assert(false);
|
||||
m_stack.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
|
||||
if (anchor) {
|
||||
assert(anchor == m_anchors.size());
|
||||
m_anchors.push_back(&node);
|
||||
}
|
||||
}
|
||||
} // namespace YAML
|
74
src/nodebuilder.h
Normal file
74
src/nodebuilder.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
|
||||
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
} // namespace detail
|
||||
struct Mark;
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
class Node;
|
||||
|
||||
class NodeBuilder : public EventHandler {
|
||||
public:
|
||||
NodeBuilder();
|
||||
NodeBuilder(const NodeBuilder&) = delete;
|
||||
NodeBuilder(NodeBuilder&&) = delete;
|
||||
NodeBuilder& operator=(const NodeBuilder&) = delete;
|
||||
NodeBuilder& operator=(NodeBuilder&&) = delete;
|
||||
virtual ~NodeBuilder();
|
||||
|
||||
Node Root();
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark);
|
||||
virtual void OnDocumentEnd();
|
||||
|
||||
virtual void OnNull(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor);
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, const std::string& value);
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnSequenceEnd();
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag,
|
||||
anchor_t anchor, EmitterStyle::value style);
|
||||
virtual void OnMapEnd();
|
||||
|
||||
private:
|
||||
detail::node& Push(const Mark& mark, anchor_t anchor);
|
||||
void Push(detail::node& node);
|
||||
void Pop();
|
||||
void RegisterAnchor(anchor_t anchor, detail::node& node);
|
||||
|
||||
private:
|
||||
detail::shared_memory_holder m_pMemory;
|
||||
detail::node* m_pRoot;
|
||||
|
||||
typedef std::vector<detail::node*> Nodes;
|
||||
Nodes m_stack;
|
||||
Nodes m_anchors;
|
||||
|
||||
typedef std::pair<detail::node*, bool> PushedKey;
|
||||
std::vector<PushedKey> m_keys;
|
||||
std::size_t m_mapDepth;
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
101
src/nodeevents.cpp
Normal file
101
src/nodeevents.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "nodeevents.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/node/detail/node.h"
|
||||
#include "yaml-cpp/node/detail/node_iterator.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
|
||||
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
|
||||
}
|
||||
|
||||
anchor_t NodeEvents::AliasManager::LookupAnchor(
|
||||
const detail::node& node) const {
|
||||
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
|
||||
if (it == m_anchorByIdentity.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
NodeEvents::NodeEvents(const Node& node)
|
||||
: m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
|
||||
if (m_root)
|
||||
Setup(*m_root);
|
||||
}
|
||||
|
||||
void NodeEvents::Setup(const detail::node& node) {
|
||||
int& refCount = m_refCount[node.ref()];
|
||||
refCount++;
|
||||
if (refCount > 1)
|
||||
return;
|
||||
|
||||
if (node.type() == NodeType::Sequence) {
|
||||
for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
|
||||
Setup(**it);
|
||||
} else if (node.type() == NodeType::Map) {
|
||||
for (detail::const_node_iterator it = node.begin(); it != node.end();
|
||||
++it) {
|
||||
Setup(*it->first);
|
||||
Setup(*it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeEvents::Emit(EventHandler& handler) {
|
||||
AliasManager am;
|
||||
|
||||
handler.OnDocumentStart(Mark());
|
||||
if (m_root)
|
||||
Emit(*m_root, handler, am);
|
||||
handler.OnDocumentEnd();
|
||||
}
|
||||
|
||||
void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
|
||||
AliasManager& am) const {
|
||||
anchor_t anchor = NullAnchor;
|
||||
if (IsAliased(node)) {
|
||||
anchor = am.LookupAnchor(node);
|
||||
if (anchor) {
|
||||
handler.OnAlias(Mark(), anchor);
|
||||
return;
|
||||
}
|
||||
|
||||
am.RegisterReference(node);
|
||||
anchor = am.LookupAnchor(node);
|
||||
}
|
||||
|
||||
switch (node.type()) {
|
||||
case NodeType::Undefined:
|
||||
break;
|
||||
case NodeType::Null:
|
||||
handler.OnNull(Mark(), anchor);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
|
||||
break;
|
||||
case NodeType::Sequence:
|
||||
handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
|
||||
for (detail::const_node_iterator it = node.begin(); it != node.end();
|
||||
++it)
|
||||
Emit(**it, handler, am);
|
||||
handler.OnSequenceEnd();
|
||||
break;
|
||||
case NodeType::Map:
|
||||
handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
|
||||
for (detail::const_node_iterator it = node.begin(); it != node.end();
|
||||
++it) {
|
||||
Emit(*it->first, handler, am);
|
||||
Emit(*it->second, handler, am);
|
||||
}
|
||||
handler.OnMapEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool NodeEvents::IsAliased(const detail::node& node) const {
|
||||
RefCount::const_iterator it = m_refCount.find(node.ref());
|
||||
return it != m_refCount.end() && it->second > 1;
|
||||
}
|
||||
} // namespace YAML
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user