Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:tinita:perlmodules
perl-YAML-PP
_service:obs_scm:perl-YAML-PP-3.14.1712772794.3...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:perl-YAML-PP-3.14.1712772794.39ac610.obscpio of Package perl-YAML-PP
07070100000000000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000002A00000000perl-YAML-PP-3.14.1712772794.39ac610/.obs07070100000001000081A40000000000000000000000016616D6BA000000C6000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/.obs/workflows.ymlpr: steps: - branch_package: source_project: home:tinita:perlmodules source_package: perl-YAML-PP target_project: home:tinita:perlmodules:CI filters: event: pull_request 07070100000002000081A40000000000000000000000016616D6BA0000059E000000000000000000000000000000000000003500000000perl-YAML-PP-3.14.1712772794.39ac610/CONTRIBUTING.md# How to contribute This module uses Dist::Zilla for creating releases, but you should be able to develop and test it without Dist::Zilla. ## Commits I try to follow these guidelines: * Git commits * Short commit message headline (if possible, up to 60 characters) * Blank line before message body * Message should be like: "Add foo ...", "Fix ..." * If you need to do formatting changes like indentation, put them into their own commit * Git workflow * Rebase every branch before merging it with --no-ff. Rebasing your pull request to current master helps me merging it. * No merging master into branches - try to rebase always * User branches might be heavily rebased/reordered/squashed because I like a clean history ## Code * No Tabs please * No trailing whitespace please * 4 spaces indentation * Look at existing code for formatting ;-) ## Testing prove -lr t To include the tests from the yaml-test-suite, checkout the test-suite branch like this: git branch test-suite --track origin/test-suite git worktree add test-suite test-suite There is also a Makefile.dev and a utility script dev.sh source dev.sh dmake testp # parallel testing You can check test coverage with make -f Makefile.dev cover # or dmake cover ## Contact Email: tinita at cpan.org IRC: tinita on freenode and irc.perl.org Chances are good that contacting me on IRC is the fastest way. 07070100000003000081A40000000000000000000000016616D6BA0000319A000000000000000000000000000000000000002D00000000perl-YAML-PP-3.14.1712772794.39ac610/ChangesRevision history for Perl module YAML::PP v0.37.1 2024-01-28 18:59:40+01:00 - Add support for builtin booleans by default - Add FAQ - Add --cyclic option to yamlpp-load(-dump) v0.37.0 2023-11-09 16:46:43+01:00 - Breaking change: Make cyclic_refs fatal by default for safety, like announced (avoid memory leaks) - Add support for plain scalars ending with colons (Issue #48, ingy++) 0.036 2023-05-10 17:09:48+02:00 - Add option -dumpcode to turn of dumping coderefs in YAML::PP::Schema::Perl - ci updates 0.035 2022-09-30 21:16:16+02:00 - Fix parsing alias as mapping key - Support emitting folded block scalars. Now any input should be able to output as a folded block scalar correctly. Preserving scalar styles will now also preserve those 0.034 2022-06-30 10:31:56+02:00 - Fix parsing empty folded block scalars with trailing linebreaks - Fix error handling (remaining tokens on invalid input) - Support experimental v5.36 booleans - Allow to specify multiple boolean classes (issue #37) 0.033 2022-06-27 16:31:32+02:00 - Fix add_mapping_resolver + on_create (tie existing data) 0.032 2022-03-08 19:02:00+01:00 - Add missing '~' to allowed chars in tags - Restructure directive parsing a bit - Support YAML::PP::Ref in yamlpp-* utility scripts - Add -P to yaml-load-dump --preserve - Add --dump option to yamlpp-parse-emit - yamlpp-load-dump -D JSON::PP: don't output space before colon - Add export tags to YAML::PP::Common - Update yaml-test-suite to 2022-01-17 0.031 2021-12-25 23:43:19+01:00 - Fix several rare test cases: - Support literal escaped tabs - Allow only one digit for block scalar indent indicator - Allow comments at the end of directives - Match word boundary after '%YAML' - Allow tabs and multiple spaces between directive elements - Forbid lines starting with tabs in block mode - After tabs no further indentation elements allowed 0.030 2021-11-07 21:57:28+01:00 - preserve: Keep existing data (issue #44) - Forbid directive without directive end marker - Support explicit empty key/value pairs in flow mappings - Enforce EOL after end of flow context - Forbid multiple question marks in flow mappings 0.029 2021-10-25 00:02:53+02:00 - Fix basic implicit mappings in flow sequences, e.g. [a, b: c, d] 0.028 2021-10-21 22:00:36+02:00 - Fix empty values with properties in flow mappings and sequences (`[ &foo , bar]`, `{ &foo , k: v }`) - Fix: Allow comment lines with tabs in flow - Fix: parsing of explicit block indenting (issue #46) - Automatically tie new hashes inside tied hashes (issue #44) - yamlpp-load-dump: Add options --dump-module and --include* - docs: Add mising constants (issue #45) 0.027 2021-04-09 11:13:28+02:00 - Forbid duplicate keys by default like announced in 0.026 - Add possibility to preserve alias names (see 'preserve' option) - Highlighter: Add option to expand tabs in ansi color mode - yamlpp-events: Add option --module - Improve error message when trying to load an undefined alias - Fix a test for perl 5.8.8 0.026 2020-09-11 00:39:09+02:00 - Add option 'duplicate_keys'. The default allows it for now and will change to forbid in the next release. 0.025 2020-09-06 22:14:07+02:00 - Emitter: Fix indentation issues for non-default indents - Emitter: Add option 'width' for maximum columns - Improve error message for unhandled reftypes 0.024 2020-08-17 12:07:01+02:00 - Parser: fix flow mappings on one line - Improve utility tools yamlpp-load(-dump) (add new options --merge, --perl and --module) #35 - Minor improvements to emitter scalar style output - Emitter supports flow style - Support for preserving flow style in Loader/Dumper - Create preserved nodes from scratch with preserved_* methods - Minor fixes for the Perl schema and globs - Update testsuite to data-2020-08-01 0.023 2020-07-09 22:09:50+02:00 - Support loading and dumping typeglobs. Issue #15 - Dumper: Don't use aliases for JSON::PP/boolean.pm booleans, because they alwas use the same reference. Issue #32 - Fix float comparison in test. Issue #33 - Make aliases in custom tags work - YAML::PP::Highlight: colorize mapping keys 0.022 2020-05-04 17:40:36+02:00 - Emitter: Also quote if string starts with '...' - Emitter: Fix bug when emitting complex keys - Preserve also quoting style of hash keys - Schema: Fix YAML 1.1 integers (no keading zeros) - Scripts: Rename yamlpp5- to yamlpp- and symlink - Scripts: Add options to yamlpp-load-dump - Tests: Support reporting flow style in testsuite event output - Tests: Restructure schema tests and outsource test data - Events: Make version_directive compatible to libyaml - Docs: Restructure 0.021 2020-02-27 19:04:58+01:00 - Add option 'preserve' for preserving hash key order and quoting style when loading and dumping 0.020 2020-02-17 15:35:44+01:00 - Change default schema from JSON to Core (this change was supposed to go in 0.019 but wasn't completely done) - Add option version_directive (print %YAML 1.2) - Add option yaml_version - Add support for detecting the right schema depending on the YAML version directive - Support both %YAML and %TAG directive for a document - Improve emitter (output footer ... after open-ended block scalars) - Improve emitter (quote strings starting with `---` to reduce ambiguity for the reader) 0.019 2020-02-13 16:06:56+01:00 - Important (and possibly breaking) changes: - Change default schema from JSON to Core. Reason: This is the recommended Schema for YAML 1.2, and what people would expect to be the default. - load* in scalar context returns first document. Reason: I think this is the most reasonable behaviour, and it will continue to work the same if you later add documents to a file. - Empty nodes in YAML 1.2 JSON Schema resolve to '' by default like before, but now it can be configured - Fix some control character escaping and encoding issues (issue#16, issue#17) YAML::PP will now just assume all input data are unicode characters and won't do an explicit utf8::upgrade - Fix Core schema resolver for inf: add +.inf, +.Inf, +.INF - Improve emitter regarding empty lists/hashes (no newline before []/{}) - Spelling and grammar fixes (PR#23 @gregoa) - Fix YAML::PP::Grammar pod (PR#22 @gregoa) - Fix yamlpp5-load-dump - Fix error tokens output - Update yaml-test-suite to data-2020-02-11 0.018 2019-07-06 19:40:10+02:00 - Turn scalar style constants into numbers - Deprecate YAML_QUOTED_SCALAR_STYLE 0.017 2019-06-29 14:34:17+02:00 - Add Include plugin - Allow to only bless specific classes for Perl Schema - YAML::PP accepts existing schema in constructor - subschema can be an object - Switch the order of 'equals' and regex tag resolvers 0.016 2019-05-20 12:37:01+02:00 - Change load methods to return the last document in scalar context for compatibility with other YAML loaders - Fix Lexer/Emitter (allowing/forbidding special characters in plain scalars) - Custom representer must fill $node->{data} - Dump: uptf8::upgrade input value (so it can store binary data) 0.015 2019-05-14 21:00:59+02:00 - Support Mac \r and Win \r\n line endings - Add options header and footer - Add support for merge keys 0.014 2019-05-07 21:46:56+02:00 - Change tagtype option in Perl Schema (e.g. tag=!perl+!!perl) - Change on_data handler to pass a reference 0.013 2019-04-30 16:02:52+02:00 - Add option "indent" for dumping - Support both !perl/ and !!perl/ tags - Change default schema from Core to JSON - Add YAML::PP::Schema::Binary for representing binary data 0.012 2019-04-14 14:02:36+02:00 - Fix bug in emitter (strings starting with % must be quoted) - Implement loading of schema classes not prefixed with YAML::PP::Schema (PR#8 @pplu) - Implement loading of perl objects - Fix line number of multiline tokens - Refactor parser/lexer. All tokens (except indentation) are now parsed by the grammar. - Change arguments of resolver callback - Add a catchall resolver for scalars 0.011 2019-03-23 12:03:12+01:00 - Add YAML::PP::Common; use constants for YAML styles - Add YAML::PP::Schema::Perl - Dump perl objects, coderefs etc. - Add YAML::PP::Schema::Tie::IxHash - keep order of hashes - Add YAML::PP::Schema::YAML1_1 - Add class_isa representer (PR#7 @pplu) - Add exceptions in tests for broken inf - Refactor schema testing - Fix indent bugs in emitter (aliases, empty lists/mappings) - Fix bug in emitter for values starting with '? ' or '- ' - Add missing resolvers to Core and YAML1_1 Schema 0.010 2018-11-02 12:53:41+01:00 - Fix regex for start of plain scalars - Large refactoring of lexer/parser. - Adjacent flow mapping values are now supported (JSON compat: `{"foo":23}`) - Empty flow mapping values are now supported - Fix nested flow collections 0.009 2018-09-30 14:10:15+02:00 - Fix yamlpp5-highlight bug from v0.008 - load_file(), LoadFile(), dump_file() and DumpFile() can take filehandles 0.008 2018-09-24 21:49:42+02:00 - Support perl 5.8 - Fix bug in folded block scalar parsing - Support multiple document end markers without content - Allow tabs at the beginning of line for flow nodes - Optimize reading input with many lines - Some internal changes - Refactor test suite - Add YAML::PP::Highlight::Dump() 0.007 2018-06-20 21:36:26+02:00 - Support .inf/.nan - Always output decimal point when dumping floats - YAML directive needs space - Improve emitter - Output multiline strings as literal block scalars - Fix regex for integers in Core Schema - Fix dumping of dualvars - Fix emitting of empty strings - Improve emitter scalar styles - Allow zero indented sequences for complex mapping keys/values - Fix parsing empty quoted strings 0.006 2018-04-01 22:59:31+02:00 - Support YAML Failsafe, JSON and Core Schema - Add dump_file, DumpFile - Add YAML::PP::Writer - Add YAML::PP::Representer - Detect cyclic references when loading - perl boolean false is now the empty string instead of 0 - Add column numbers to error messages - Fixed various bugs in Emitter - Can now emit empty collections like [], {} 0.005 2017-11-23 17:09:55+01:00 - Support reading files - Replace load() with load_string(), dump() with dump_string() - Support legacy interface functions Load, LoadFile, Dump - ... and --- are now correctly invalid in quoted scalars - Improve block scalar handling, passing two more tests - Improve multiline plain handling, passing another test - Partial implementation of flow style collections - Allow unicode in alias/anchor names - Document header at the end is now recognized - Support all valid escapes in double quotes - ...and forbid invalid ones - Multiline quoted strings must be indented - Forbid sequence or mapping as a mapping value on the same line - Forbit sequence after an anchor/tag on the same line 0.004 2017-09-15 13:30:50+02:00 - Improve regex for plain scalars - Support literal unicode characters - Reject undefined tag shorthand handles - Fix JSON test - Update yaml-test-suite 0.003_002 2017-09-09 16:27:28+02:00 - Lots of refactoring - Lots of little bugfixes - Split Loader into Constructor - Add yaml-test-suite to release tarball - Add a Lexer - Better error messages - Add a highlighter for HTML and ANSI colors - Dumper can dump aliases/anchors now 0.003_001 2017-08-07 23:29:51+02:00 - Fix some parsing bugs for quoted strings - Add Dumper and Emitter 0.003 2017-05-31 23:35:44+02:00 - Changes for new Loader API 0.002 2017-04-30 19:07:48+02:00 - Loader: Support stringification of complex mapping keys - Improve regexes for mapping keys, tags, anchors/aliases - Improve number support (int, float, oct, hex) - Reserved directives generate a warning now - Support Carriage Return as line break - Support missing final line break - Make JSON::PP optional in test - Fix bug for perl <= 5.22 0.001 Thu Apr 20 20:46:43 2017 +0200 - First Release 07070100000004000081A40000000000000000000000016616D6BA0000006F000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/MANIFEST.SKIP^dev ^test-suite/.git ^cover_db ^local ^dev.sh ^nytprof ^nytprof.out ^pod2htmd.tmp ^new_tests ^gh-pages ^bench 07070100000005000081A40000000000000000000000016616D6BA00000884000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/Makefile.PL# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.030. use strict; use warnings; use 5.008000; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "YAML 1.2 Processor", "AUTHOR" => "Tina M\x{fc}ller <tinita\@cpan.org>", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "YAML-PP", "EXE_FILES" => [ "bin/yamlpp-events", "bin/yamlpp-highlight", "bin/yamlpp-load", "bin/yamlpp-load-dump", "bin/yamlpp-parse-emit" ], "LICENSE" => "perl", "MIN_PERL_VERSION" => "5.008000", "NAME" => "YAML::PP", "PREREQ_PM" => { "B" => 0, "B::Deparse" => 0, "Carp" => 0, "Data::Dumper" => 0, "Encode" => 0, "Exporter" => 0, "File::Basename" => 0, "Getopt::Long" => 0, "MIME::Base64" => 0, "Module::Load" => 0, "Scalar::Util" => "1.07", "Tie::Array" => 0, "Tie::Hash" => 0, "base" => 0, "constant" => 0, "overload" => 0, "strict" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "File::Spec" => 0, "FindBin" => 0, "IO::File" => 0, "IO::Handle" => 0, "IPC::Open3" => 0, "Test::More" => "0.98", "Test::Warn" => 0, "lib" => 0 }, "VERSION" => "v0.37.1", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "B" => 0, "B::Deparse" => 0, "Carp" => 0, "Data::Dumper" => 0, "Encode" => 0, "Exporter" => 0, "File::Basename" => 0, "File::Spec" => 0, "FindBin" => 0, "Getopt::Long" => 0, "IO::File" => 0, "IO::Handle" => 0, "IPC::Open3" => 0, "MIME::Base64" => 0, "Module::Load" => 0, "Scalar::Util" => "1.07", "Test::More" => "0.98", "Test::Warn" => 0, "Tie::Array" => 0, "Tie::Hash" => 0, "base" => 0, "constant" => 0, "lib" => 0, "overload" => 0, "strict" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); 07070100000006000081A40000000000000000000000016616D6BA000003D7000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/Makefile.devtest-suite: git branch test-suite --track origin/test-suite git worktree add test-suite test-suite cover: HARNESS_PERL_SWITCHES="-MDevel::Cover=+ignore,local,+ignore,^t/,+ignore,^xt/" prove -lr t cover test-all: TEST_ALL=1 prove -lr t test-all-verbose: TEST_ALL=1 prove -lrv t test-valid-all: TEST_ALL=1 prove -lrv t/10.parse-valid.t test-invalid-all: TEST_ALL=1 prove -lrv t/11.parse-invalid.t test: prove -lr t testp: prove -lr -j9 t testv: prove -lrv t # YAML_PP_TRACE=1 YAML_TEST_DIR=M9B4 prove -lrv t gh-pages: git worktree add gh-pages gh-pages gh-pages-status: gh-pages cd gh-pages && git status gh-pages-diff: gh-pages cd gh-pages && git diff gh-pages-commit: gh-pages cd gh-pages && git add . && git commit -m "Generate HTML" gh-pages-push: gh-pages cd gh-pages && git push test-suite-html: gh-pages perl etc/test-suite-html.pl > gh-pages/test-suite.html grammar: perl etc/generate-grammar.pl gen_examples: perl etc/generate-examples.pl 07070100000007000081A40000000000000000000000016616D6BA0000005C000000000000000000000000000000000000002F00000000perl-YAML-PP-3.14.1712772794.39ac610/README.mdJust a copy of https://github.com/perlpunk/YAML-PP-p5 for demo purposes Adding a new line. 07070100000008000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000002900000000perl-YAML-PP-3.14.1712772794.39ac610/bin07070100000009000081ED0000000000000000000000016616D6BA000004FC000000000000000000000000000000000000003700000000perl-YAML-PP-3.14.1712772794.39ac610/bin/yamlpp-events#!/usr/bin/perl use strict; use warnings; use Encode; use YAML::PP::Parser; use YAML::PP::Common; use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( 'help|h' => \my $help, 'module|M=s' => \my $module, ) or usage(1); usage(0) if $help; $module ||= 'YAML::PP'; if ($module eq 'YAML::PP') { $module = 'YAML::PP::Parser'; } elsif ($module eq 'YAML::PP::LibYAML') { require YAML::PP::LibYAML::Parser; $module = 'YAML::PP::LibYAML::Parser'; } elsif ($module eq 'YAML::PP::Ref') { require YAML::PP::Ref; $module = 'YAML::PP::Ref::Parser'; } my ($file) = @ARGV; my $parser = $module->new( receiver => sub { my ($self, undef, $event) = @_; print encode_utf8(YAML::PP::Common::event_to_test_suite($event, { flow => 1 })), "\n"; }, $file ? (reader => YAML::PP::Reader::File->new) : (), ); if ($file) { $parser->parse_file($file); } else { my $yaml; $yaml = do { local $/; <STDIN> }; $yaml = decode_utf8($yaml); $parser->parse_string($yaml); } sub usage { my ($rc) = @_; print <<"EOM"; Usage: $0 [options] < file $0 [options] file Options: --module -M Module to use for parsing. YAML::PP (default), YAML::PP::LibYAML or YAML::PP::Ref EOM exit $rc; } 0707010000000A000081ED0000000000000000000000016616D6BA000003EF000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/bin/yamlpp-highlight#!/usr/bin/perl use strict; use warnings; use YAML::PP::Highlight; use Encode; use Getopt::Long; GetOptions( 'help|h' => \my $help, 'expand-tabs|et!' => \my $expand_tabs, ) or usage(1); $expand_tabs = 1 unless defined $expand_tabs; usage(0) if $help; my ($file) = @ARGV; my $yaml; unless ($file) { $yaml = do { local $/; <STDIN> }; $yaml = decode_utf8($yaml); } my $error; my $tokens; if (defined $file) { ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens( file => $file ); } else { ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens( string => $yaml ); } my $highlighted = YAML::PP::Highlight->ansicolored($tokens, expand_tabs => $expand_tabs); print encode_utf8 $highlighted; if ($error) { die $error; } sub usage { my ($rc) = @_; print <<"EOM"; Usage: $0 [options] < file $0 [options] file Options: --expand-tabs --et Expand tabs to 8 spaces (default true) --no-expand-tabs --no-et Don't expand tabs EOM exit $rc; } 0707010000000B000081ED0000000000000000000000016616D6BA00000D17000000000000000000000000000000000000003500000000perl-YAML-PP-3.14.1712772794.39ac610/bin/yamlpp-load#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use YAML::PP; use YAML::PP::Common qw/ PRESERVE_ORDER /; use Encode; use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( 'help|h' => \my $help, 'boolean=s' => \my $boolean, 'cyclic' => \my $cyclic, 'merge' => \my $merge, 'perl' => \my $perl, 'module|M=s' => \my $module, 'yaml-version=s' => \my $yaml_version, ) or usage(1); usage(0) if $help; $module ||= 'YAML::PP'; $boolean ||= 'JSON::PP'; $yaml_version ||= 1.2; my @yaml_versions = split m/,/, $yaml_version; my @schema = ('+'); if ($merge) { push @schema, 'Merge'; } if ($perl) { push @schema, 'Perl'; } my ($file) = @ARGV; my $yaml; my $decode = 1; if ($module eq 'YAML::XS') { $decode = 0; } if ($file) { open my $fh, '<', $file or die "Can not open '$file'"; $yaml = do { local $/; <$fh> }; close $fh; } else { $yaml = do { local $/; <STDIN> }; } $yaml = decode_utf8($yaml) if $decode; my %codes = ( 'YAML::PP' => \&yamlpp, 'YAML::PP::LibYAML' => \&yamlpplibyaml, 'YAML::PP::Ref' => \&yamlppref, 'YAML::XS' => \&yamlxs, 'YAML::Tiny' => \&yamltiny, 'YAML::Syck' => \&yamlsyck, 'YAML' => \&yaml, ); my $code = $codes{ $module } or die "Module '$module' not supported"; my @docs = $code->($yaml); sub _yamlpp { my ($class, $yaml) = @_; my $ypp = $class->new( schema => \@schema, boolean => $boolean, cyclic_refs => $cyclic ? 'allow' : 'fatal', preserve => PRESERVE_ORDER, yaml_version => \@yaml_versions, ); my @docs = $ypp->load_string($yaml); return @docs; } sub yamlpp { _yamlpp('YAML::PP' => $_[0]); } sub yamlpplibyaml { eval { require YAML::PP::LibYAML }; _yamlpp('YAML::PP::LibYAML' => $_[0]); } sub yamlppref { eval { require YAML::PP::Ref }; _yamlpp('YAML::PP::Ref' => $_[0]); } sub yamlxs { eval { require YAML::XS }; my ($yaml) = @_; no warnings 'once'; local $YAML::XS::LoadBlessed = $perl; return YAML::XS::Load($yaml); } sub yamlsyck { eval { require YAML::Syck }; my ($yaml) = @_; no warnings 'once'; local $YAML::Syck::LoadBlessed = $perl; local $YAML::Syck::ImplicitTyping = 1; local $YAML::Syck::ImplicitUnicode = 1; return YAML::Syck::Load($yaml); } sub yaml { eval { require YAML }; my ($yaml) = @_; no warnings 'once'; local $YAML::LoadBlessed = $perl; return YAML::Load($yaml); } sub yamltiny { eval { require YAML::Tiny }; my ($yaml) = @_; return YAML::Tiny::Load($yaml); } local $Data::Dumper::Useqq = 1; local $Data::Dumper::Sortkeys = 1; print Data::Dumper->Dump([$docs[ $_ ]], ["doc$_"]) for 0 ..$#docs; sub usage { my ($rc) = @_; print <<"EOM"; Usage: $0 [options] < file $0 [options] file Options: --boolean= 'perl', 'JSON::PP', 'boolean' --cyclic Allow cyclic references --merge Enable loading merge keys '<<' --perl Enable loading perl types and objects (use only on trusted input!) --module -M YAML::PP (default), YAML, YAML::PP::LibYAML, YAML::Syck, YAML::Tiny, YAML::XS, YAML::PP::Ref --yaml-version= '1.2' (default), '1.1', '1.2,1.1', '1.1,1.2' EOM exit $rc; } 0707010000000C000081ED0000000000000000000000016616D6BA00002106000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/bin/yamlpp-load-dump#!/usr/bin/perl use strict; use warnings; use YAML::PP; use YAML::PP::Dumper; use YAML::PP::Common qw/ :PRESERVE /; use Encode; use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( 'help|h' => \my $help, 'boolean=s' => \my $boolean, 'cyclic' => \my $cyclic, 'indent=i' => \my $indent, 'width=i' => \my $width, 'header!' => \my $header, 'footer!' => \my $footer, 'merge' => \my $merge, 'perl' => \my $perl, 'preserve|P=s' => \my $preserve, 'module|M=s' => \my $module, 'dump-module|D=s' => \my $dump_module, 'include' => \my $include, 'include-absolute' => \my $include_absolute, 'yaml-version=s' => \my $yaml_version, 'version-directive' => \my $version_directive, ) or usage(1); usage(0) if $help; $module ||= 'YAML::PP'; $boolean ||= 'JSON::PP'; $footer ||= 0; $indent ||= 2; $yaml_version ||= 1.2; $dump_module ||= $module; if ($dump_module eq 'YAML::PP::Ref') { $dump_module = 'YAML::PP'; } my @yaml_versions = split m/,/, $yaml_version; my @schema = ('+'); if ($merge) { push @schema, 'Merge'; } if ($perl) { push @schema, 'Perl'; } my $preserve_order = 1; if (defined $preserve) { $preserve_order = 0; my @split = split m/,/, $preserve; $preserve = 0; for my $split (@split) { $preserve |= PRESERVE_ORDER if $split eq 'order'; $preserve_order = 1 if $split eq 'order'; $preserve |= PRESERVE_SCALAR_STYLE if $split eq 'scalar'; $preserve |= PRESERVE_FLOW_STYLE if $split eq 'flow'; $preserve |= PRESERVE_ALIAS if $split eq 'alias'; } } elsif ($dump_module =~ m/JSON/) { $preserve = PRESERVE_ORDER; } else { $preserve = 1; } $header = 1 unless defined $header; my ($file) = @ARGV; my $yaml; my $decode = 1; if ($module eq 'YAML::XS') { $decode = 0; } if ($file) { open my $fh, '<', $file or die "Can not open '$file'"; $yaml = do { local $/; <$fh> }; close $fh; } else { $yaml = do { local $/; <STDIN> }; } $yaml = decode_utf8($yaml) if $decode; my %load_modules = ( 'YAML::PP' => \&yamlpp, 'YAML::PP::LibYAML' => \&yamlpplibyaml, 'YAML::PP::Ref' => \&yamlppref, 'YAML::XS' => \&yamlxs, 'YAML::Tiny' => \&yamltiny, 'YAML::Syck' => \&yamlsyck, 'YAML' => \&yaml, ); my %dump_modules = ( 'YAML::PP' => \&yamlpp_dump, 'YAML::PP::LibYAML' => \&yamlpplibyaml_dump, 'YAML::XS' => \&yamlxs_dump, 'YAML::Tiny' => \&yamltiny_dump, 'YAML::Syck' => \&yamlsyck_dump, 'YAML' => \&yaml_dump, 'Data::Dumper' => \&data_dumper, 'JSON::PP' => \&json_pp_dump, 'JSON::XS' => \&json_xs_dump, 'Cpanel::JSON::XS' => \&cpanel_json_xs_dump, ); my $code = $load_modules{ $module } or die "Module '$module' not supported for loading"; my $dump_code = $dump_modules{ $dump_module } or die "Module '$dump_module' not supported for dumping"; my $docs = $code->($yaml, $file); my $out_yaml = $dump_code->($docs); sub _yamlpp { my ($class, $yaml, $file) = @_; my %args; my $inc; if ($include) { require YAML::PP::Schema::Include; $inc = YAML::PP::Schema::Include->new( $include_absolute ? (allow_absolute => 1) : (), ); push @schema, $inc; } my $ypp = $class->new( schema => \@schema, boolean => $boolean, cyclic_refs => $cyclic ? 'allow' : 'fatal', preserve => $preserve, indent => $indent, width => $width, header => $header ? 1 : 0, footer => $footer ? 1 : 0, yaml_version => \@yaml_versions, version_directive => $version_directive || 0, ); if ($inc) { $inc->yp($ypp); } my @docs = $file ? $ypp->load_file($file) : $ypp->load_string($yaml); return \@docs; } sub yamlpp { _yamlpp('YAML::PP' => @_); } sub yamlpp_dump { _yamlpp_dump('YAML::PP' => @_); } sub yamlpplibyaml { eval { require YAML::PP::LibYAML }; _yamlpp('YAML::PP::LibYAML' => @_); } sub yamlppref { eval { require YAML::PP::Ref }; _yamlpp('YAML::PP::Ref' => @_); } sub yamlpplibyaml_dump { eval { require YAML::PP::LibYAML }; _yamlpp_dump('YAML::PP::LibYAML' => @_); } sub _yamlpp_dump { my ($class, $docs) = @_; my $ypp = $class->new( schema => \@schema, boolean => $boolean, preserve => $preserve, indent => $indent, width => $width, header => $header ? 1 : 0, footer => $footer ? 1 : 0, yaml_version => \@yaml_versions, version_directive => $version_directive || 0, ); return $ypp->dump_string(@$docs); } sub yamlxs { eval { require YAML::XS }; my ($yaml) = @_; no warnings 'once'; local $YAML::XS::LoadBlessed = $perl; my @docs = YAML::XS::Load($yaml); return \@docs; } sub yamlxs_dump { my ($docs) = @_; eval { require YAML::XS }; no warnings 'once'; local $YAML::XS::Indent = $indent; return YAML::XS::Dump(@$docs); } sub yamlsyck { eval { require YAML::Syck }; my ($yaml) = @_; no warnings 'once'; local $YAML::Syck::LoadBlessed = $perl; local $YAML::Syck::ImplicitTyping = 1; local $YAML::Syck::ImplicitUnicode = 1; my @docs = YAML::Syck::Load($yaml); return \@docs; } sub yamlsyck_dump { eval { require YAML::Syck }; my ($docs) = @_; no warnings 'once'; local $YAML::Syck::Headless = 1 unless $header; local $YAML::Syck::ImplicitTyping = 1; local $YAML::Syck::ImplicitUnicode = 1; return YAML::Syck::Dump(@$docs); } sub yaml { eval { require YAML }; no warnings 'once'; local $YAML::LoadBlessed = $perl; my ($yaml) = @_; my @docs = YAML::Load($yaml); return \@docs; } sub yaml_dump { my ($docs) = @_; eval { require YAML }; no warnings 'once'; local $YAML::UseHeader = $header ? 1 : 0; local $YAML::Indent = $indent; return YAML::Dump(@$docs); } sub yamltiny { eval { require YAML::Tiny }; my ($yaml) = @_; my @docs = YAML::Tiny::Load($yaml); return \@docs; } sub yamltiny_dump { eval { require YAML::Tiny }; my ($docs) = @_; return YAML::Tiny::Dump(@$docs); } sub data_dumper { my ($docs) = @_; local $Data::Dumper::Useqq = 1; local $Data::Dumper::Sortkeys = 1 unless $preserve_order; my $out = ''; $out .= Data::Dumper->Dump([$docs->[ $_ ]], ["doc$_"]) for 0 ..$#$docs; return $out; } sub json_pp_dump { require JSON::PP; _json_dump('JSON::PP', @_) } sub json_xs_dump { require JSON::XS; _json_dump('JSON::XS', @_) } sub cpanel_json_xs_dump { require Cpanel::JSON::XS; _json_dump('Cpanel::JSON::XS', @_) } sub _json_dump { my ($class, $docs) = @_; my $coder = $class->new->ascii->pretty->allow_nonref->space_before(0); $coder = $coder->indent_length($indent) if $coder->can('indent_length'); $coder = $coder->canonical unless $preserve_order; my $out = ''; $out .= $coder->encode($docs->[ $_ ]) for 0 ..$#$docs; return $out; } if ($decode) { print encode_utf8 $out_yaml; } else { print $out_yaml; } sub usage { my ($rc) = @_; print <<"EOM"; Usage: $0 [options] < file $0 [options] file Options: --boolean= 'perl', 'JSON::PP', 'boolean' --cyclic Allow cyclic references --indent= Number of spaces for indentation --width= Maximum column width (only used in flow style for now) --[no-]header Print '---' (default) --[no-]footer Print '...' --merge Enable loading merge keys '<<' --perl Enable loading perl types and objects (use only on trusted input!) --preserve, -P Comma separated: 'order', 'scalar', 'flow', 'alias'. Set to 0 to preserve nothing. By default all things are preserved --module -M YAML::PP (default), YAML, YAML::PP::LibYAML, YAML::Syck, YAML::Tiny, YAML::XS, YAML::PP::Ref --dump-module -D All of the above plus Data::Dumper, JSON::PP, JSON::XS, Cpanel::JSON::XS --yaml-version= '1.2' (default), '1.1', '1.2,1.1', '1.1,1.2' --version-directive Print '%YAML <version>' --include Enable Include Schema --include-absolute Allow absolute paths and ../../../ in includes (use only on trusted input!) EOM exit $rc; } 0707010000000D000081ED0000000000000000000000016616D6BA00000CB2000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/bin/yamlpp-parse-emit#!/usr/bin/perl use strict; use warnings; use YAML::PP; use YAML::PP::Common qw/ YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE /; use YAML::PP::Parser; use YAML::PP::Emitter; use YAML::PP::Writer; use Data::Dumper; use Encode; use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( 'help|h' => \my $help, 'indent=i' => \my $indent, 'module|M=s' => \my $module, 'dump|D=s' => \my $emit, 'verbose' => \my $verbose, 'flow=s' => \my $flow, 'width=i' => \my $width, ) or usage(1); usage(0) if $help; $module ||= 'YAML::PP'; $emit ||= $module; $flow ||= 'no'; my ($file) = @ARGV; my $yaml; if ($file) { open my $fh, '<', $file or die $!; $yaml = do { local $/; <$fh> }; close $fh; } else { $yaml = do { local $/; <STDIN> }; } $yaml = decode_utf8($yaml); if ($emit eq 'YAML::PP::Ref') { $emit = 'YAML::PP'; } my $parserclass = 'YAML::PP::Parser'; my $emitterclass = 'YAML::PP::Emitter'; if ($module eq 'YAML::PP::LibYAML') { eval { require YAML::PP::LibYAML } or die "Module $module not supported: $@"; $parserclass = 'YAML::PP::LibYAML::Parser'; $emitterclass = 'YAML::PP::LibYAML::Emitter'; } elsif ($module eq 'YAML::PP::Ref') { eval { require YAML::PP::Ref } or die "Module $module not supported: $@"; $parserclass = 'YAML::PP::Ref::Parser'; } if ($emit eq 'YAML::PP::LibYAML') { eval { require YAML::PP::LibYAML } or die "Module $emit not supported: $@"; $emitterclass = 'YAML::PP::LibYAML::Emitter'; } my @events; my $parser = $parserclass->new( receiver => sub { my ($self, undef, $event) = @_; push @events, $event; }, ); eval { $parser->parse_string($yaml); }; if ($@) { for (@events) { print YAML::PP::Common::event_to_test_suite($_) ."\n"; } warn "Error parsing: $@"; exit 1; } my $writer = YAML::PP::Writer->new; my $emitter = $emitterclass->new( indent => $indent, width => $width ); $emitter->set_writer($writer); for my $event (@events) { my $type = $event->{name}; my $str = YAML::PP::Common::event_to_test_suite($event); print "$str\n" if $verbose; if ($type eq 'sequence_start_event' or $type eq 'mapping_start_event') { if ($flow eq 'no') { delete $event->{style}; } elsif ($flow eq 'yes') { if ($type eq 'sequence_start_event') { $event->{style} = YAML_FLOW_SEQUENCE_STYLE; } else { $event->{style} = YAML_FLOW_MAPPING_STYLE; } } } $emitter->$type($event); } my $out_yaml = $emitter->writer->output; print encode_utf8 $out_yaml; sub usage { my ($rc) = @_; print <<"EOM"; Usage: $0 [options] < file $0 [options] file Options: --indent= Number of spaces for indentation --width= Maximum column width (only used in flow style for now) --module, -M YAML::PP, YAML::PP::LibYAML or YAML::PP::Ref --dump, -D YAML::PP, YAML::PP::LibYAML --flow 'no' (default, always output block style), 'yes' (always output flow style), 'keep' (output flow style like in the original input) EOM exit $rc; } 0707010000000E000081ED0000000000000000000000016616D6BA000002B4000000000000000000000000000000000000002C00000000perl-YAML-PP-3.14.1712772794.39ac610/dev.sh#!/bin/bash function is-valid-trace() { YAML_PP_TRACE=1 YAML_TEST_DIR=$1 prove -lrv t/10.parse-valid.t } function is-valid() { YAML_PP_DEBUG=1 YAML_TEST_DIR=$1 prove -lrv t/10.parse-valid.t } function is-invalid-trace() { YAML_PP_TRACE=1 YAML_TEST_DIR=$1 prove -lrv t/11.parse-invalid.t } function is-invalid() { YAML_PP_DEBUG=1 YAML_TEST_DIR=$1 prove -lrv t/11.parse-invalid.t } function test-dump() { YAML_TEST_DIR=$1 prove -lrv t/20.dump.t } function test-emit() { YAML_PP_EMIT_DEBUG=1 YAML_TEST_DIR=$1 prove -lrv t/21.emit.t } function json-load() { YAML_PP_LOAD_TRACE=1 YAML_TEST_DIR=$1 prove -lrv t/12.load-json.t } alias dmake="make -f Makefile.dev" 0707010000000F000081A40000000000000000000000016616D6BA0000048D000000000000000000000000000000000000002E00000000perl-YAML-PP-3.14.1712772794.39ac610/dist.ininame = YAML-PP author = Tina Müller <tinita@cpan.org> license = Perl_5 copyright_holder = Tina Müller copyright_year = 2024 version = v0.37.1 [@Filter] -bundle = @Basic -remove = GatherDir -remove = Readme option = for_basic [Prereqs] perl = 5.8.0 Scalar::Util = 1.07 ; openhandle() [AutoPrereqs] skip = Term::ANSIColor skip = boolean skip = JSON::PP skip = JSON::XS skip = Cpanel::JSON::XS skip = HTML::Entities skip = Tie::IxHash skip = Tie::StdHash skip = Tie::StdArray skip = YAML skip = YAML::PP::LibYAML skip = YAML::Syck skip = YAML::Tiny skip = YAML::XS [Prereqs / TestRequires] Test::More = 0.98 [Prereqs / TestRecommends] Test::Deep = 0 [OverridePkgVersion] [MetaProvides::Package] [Test::Compile] filename = t/00.compile.t [CopyFilesFromBuild] copy = Makefile.PL ; requires CopyFilesFromBuild >= 0.163040 copy = t/00.compile.t [GatherDir] exclude_filename = Makefile.PL exclude_filename = t/00.compile.t [MetaJSON] [MetaResources] bugtracker.web = https://github.com/perlpunk/YAML-PP-p5/issues repository.url = https://github.com/perlpunk/YAML-PP-p5 repository.web = https://github.com/perlpunk/YAML-PP-p5 repository.type = git 07070100000010000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000002900000000perl-YAML-PP-3.14.1712772794.39ac610/etc07070100000011000081A40000000000000000000000016616D6BA00000597000000000000000000000000000000000000003E00000000perl-YAML-PP-3.14.1712772794.39ac610/etc/generate-examples.pl#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use FindBin '$Bin'; use lib "$Bin/../lib"; use YAML::PP; my $tests_perl = require "$Bin/../examples/schema-perl.pm"; my $tests_ixhash = require "$Bin/../examples/schema-ixhash.pm"; my $schema_perl_pm_file = "$Bin/../lib/YAML/PP/Schema/Perl.pm"; my $schema_ixhash_pm_file = "$Bin/../lib/YAML/PP/Schema/Tie/IxHash.pm"; my $yp = YAML::PP->new( schema => [qw/ JSON Perl Tie::IxHash /] ); generate( file => $schema_perl_pm_file, tests => $tests_perl, ); generate( file => $schema_ixhash_pm_file, tests => $tests_ixhash, ); sub generate { my %args = @_; my $file = $args{file}; my $tests = $args{tests}; open my $fh, '<', $file; my $text = do { local $/; <$fh> }; close $fh; my $examples; for my $name (sort keys %$tests) { my $test = $tests->{ $name }; my $code = $test->[0]; my $data = eval $code; if ($@) { die "Error: $@"; } my $yaml = $yp->dump_string($data); $yaml =~ s/^/ /gm; my $example = <<"EOM"; =item $name # Code $code # YAML $yaml EOM $examples .= $example; } my $pod = <<"EOM"; ### BEGIN EXAMPLE =pod =over 4 $examples =back =cut ### END EXAMPLE EOM $text =~ s/^### BEGIN EXAMPLE.*^### END EXAMPLE\n/$pod/ms; open $fh, '>', $file; print $fh $text; close $fh; } 07070100000012000081ED0000000000000000000000016616D6BA00000652000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/etc/generate-grammar.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use FindBin '$Bin'; use Data::Dumper; use YAML::XS qw/ Load Dump /; my $grammar_file = "$Bin/grammar.yaml"; open my $fh, '<', $grammar_file or die $!; my $yaml = do { local $/; <$fh> }; close $fh; my $module_file = "$Bin/../lib/YAML/PP/Grammar.pm"; my $grammar = Load $yaml; open $fh, '<', $module_file or die $!; my $replaced = ''; while (my $line = <$fh>) { my $state = $line =~ m/^# START OF GRAMMAR INLINE/ ... $line =~ m/^# END OF GRAMMAR INLINE/; my $state2 = $line =~ m/^ *# START OF YAML INLINE/ ... $line =~ m/^ *# END OF YAML INLINE/; if ($state) { if ($state == 1) { $replaced .= $line; local $Data::Dumper::Indent = 1; local $Data::Dumper::Sortkeys = 1; my $dump = Data::Dumper->Dump([$grammar], ['GRAMMAR']); $replaced .= <<"EOM"; # DO NOT CHANGE THIS # This grammar is automatically generated from etc/grammar.yaml $dump EOM } elsif ($state =~ m/E0$/) { $replaced .= $line; } } elsif ($state2) { if ($state2 == 1) { $replaced .= $line; my $yaml_formatted = $yaml; $yaml_formatted =~ s/^/ /mg; $replaced .= <<"EOM"; # DO NOT CHANGE THIS # This grammar is automatically generated from etc/grammar.yaml $yaml_formatted EOM } elsif ($state2 =~ m/E0$/) { $replaced .= $line; } } else { $replaced .= $line; } } close $fh; open $fh, '>', $module_file or die $!; print $fh $replaced; close $fh; 07070100000013000081A40000000000000000000000016616D6BA000016B4000000000000000000000000000000000000004100000000perl-YAML-PP-3.14.1712772794.39ac610/etc/generate-schema-html.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use Data::Dumper; use FindBin '$Bin'; use lib "$Bin/../lib"; use YAML::PP; use URI::Escape qw/ uri_escape /; my $file = "$Bin/../ext/yaml-test-schema/yaml-schema.yaml"; my $modulesfile = "$Bin/../examples/yaml-schema-modules.yaml"; my $htmlfile = "$Bin/../gh-pages/schema-examples.html"; my $data = YAML::PP::LoadFile($file); my $modules = YAML::PP::LoadFile($modulesfile); my @mods = qw/ YAML YAML::Syck YAML::XS /; my %examples; for my $input (sort keys %$data) { my $schemas = $data->{ $input }; my @keys = keys %$schemas; for my $key (@keys) { my $def = $schemas->{ $key }; my @schemas = split m/ *, */, $key; for my $schema (@schemas) { $examples{ $input }->{ $schema } = $def; } } } my @keys = qw/ failsafe json core yaml11 /; for my $input (sort keys %examples) { my $schemas = $examples{ $input }; my $str = 0; for my $schema (@keys) { my $example = $schemas->{ $schema }; unless ($example) { $example = $schemas->{ $schema } = [ 'todo', '', '', '' ]; } if ($example->[0] eq 'str' or $example->[0] eq 'todo') { $str++; } } if ($str == 4) { delete $examples{ $input }; } } my %type_index = ( null => 0, bool => 1, float => 2, inf => 3, nan => 4, int => 5, str => 6, todo => 7, ); my $table = schema_table(\%examples, $modules); my $html = generate_html($table); open my $fh, '>', $htmlfile or die $!; print $fh $html; close $fh; sub sort_rows { my ($x, $y, $a, $b) = @_; $type_index{ $x->{yaml11}->[0] } <=> $type_index{ $y->{yaml11}->[0] } || $type_index{ $x->{core}->[0] } <=> $type_index{ $y->{core}->[0] } || $type_index{ $x->{json}->[0] } <=> $type_index{ $y->{json}->[0] } || lc $a cmp lc $b || $a cmp $b } sub schema_table { my ($examples) = @_; my $html = '<table class="schema">'; my @sorted = sort { sort_rows($examples->{ $a }, $examples->{ $b }, $a, $b) } grep { not m/^!!\w/ } keys %$examples; my @sorted_explicit = sort { sort_rows($examples->{ $a }, $examples->{ $b }, $a, $b) } grep { m/^!!\w/ } keys %$examples; my @all = (@sorted, @sorted_explicit); $html .= qq{<tr><th></th><th colspan="8">YAML::PP</th><th colspan="6">Other Perl Modules</th></tr>\n}; my $header; $header .= qq{<tr><th>Input YAML</th>}; $header .= join '', map { my $m = $_ eq 'YAML' ? 'YAML.pm' : $_; qq{<th colspan="2" class="border-left">$m</th>\n}; } (qw/ Failsafe JSON Core /, 'YAML 1.1', @mods); $header .= qq{</tr>\n}; $html .= $header; $html .= qq{<tr><td></td>} . (qq{<td class="border-left">Type</td><td>Output</td>} x 7) . qq{</tr>\n}; for my $i (0 .. $#all) { my $input = $all[ $i ]; if ($i and $i % 30 == 0) { $html .= $header; } my $schemas = $examples->{ $input }; my $mods = $modules->{ $input }; my $input_escaped = uri_escape($input); $input =~ s/ / /g; $html .= qq{<tr id="input-$input_escaped"><td class="input code"><a href="#input-$input_escaped">$input</a></th>}; for my $mod (@mods) { my $result = $mods->{ $mod }; $schemas->{ $mod } = [ $result->{type}, '', $result->{dump} // '' ]; } for my $schema (@keys, @mods) { my $example = $schemas->{ $schema }; my $class = 'type-str'; my ($type, $perl, $out) = @$example; $class = "type-$type"; for ($out) { s/ / /g; } if ($type eq 'str') { $html .= qq{<td class="code $class border-left" colspan="2">$type</td>}; } else { $html .= qq{<td class="code $class border-left">$type</td><td class="code $class"><pre>$out</pre></td>}; } } $html .= qq{</tr>\n}; } $html .= "</table>"; return $html; } #sub format_perl { # my ($type, $perl) = @_; # my $perlcode; # local $Data::Dumper::Terse = 1; # local $Data::Dumper::Useqq = 1; # if ($type eq 'null') { # $perlcode = 'undef'; # } # elsif ($type eq 'float' or $type eq 'int') { # $perlcode = $perl; # } # elsif ($type eq 'inf') { # if ($perl eq 'inf-neg()') { # $perlcode = '- "inf" + 0'; # } # else { # $perlcode = '"inf" + 0'; # } # } # elsif ($type eq 'nan') { # $perlcode = '"nan" + 0'; # } # elsif ($type eq 'bool') { # $perlcode = $perl; # } # else { # $perlcode = Data::Dumper->Dump([$perl], ['perl']); # } # return $perlcode; #} sub generate_html { my ($content) = @_; my $html = <<'EOM'; <html> <head> <title>YAML Schema examples in YAML::PP and other Perl Modules</title> <link rel="stylesheet" type="text/css" href="css/yaml.css"> </head> <body> <a href="test-suite.html">YAML Test Suite Test Cases</a> | <a href="schema-examples.html">Schema examples</a> | <a href="schemas.html">Schema comparison</a> <hr> <p> The Perl Module YAML::PP implements <a href="https://yaml.org/spec/1.2/spec.html">YAML 1.2</a>. You can choose between several Schemas.<br> The following table shows which strings result in which native data, depending on the Schema (or other YAML module) you use.<br> For each of the Schemas and modules, the first column is the type, and the second shows how the data is encoded into YAML again.<br> Note that the YAML 1.2 JSON Schema is not exactly like the official schema, as all strings would have to be quoted. </p> EOM $html .= $content; $html .= <<'EOM'; </body></html> EOM return $html; } 07070100000014000081A40000000000000000000000016616D6BA00004141000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/etc/grammar.yaml--- NODETYPE_NODE: DASH: match: cb_seqstart EOL: { new: FULLNODE } WS: { new: FULLNODE } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } NODETYPE_SCALAR_OR_MAP: # Flow nodes can follow tabs WS: { new: FULLMAPVALUE_INLINE } ALIAS: match: cb_alias EOL: { match: cb_send_alias_from_stack } WS: COLON: match: cb_insert_map_alias EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUESTION: match: cb_questionstart EOL: { new: FULLNODE } WS: { new: FULLNODE } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } WS: COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUOTED_MULTILINE: match: cb_quoted_multiline EOL: { } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar WS: COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } PLAIN_MULTI: match: cb_send_plain_multi EOL: { } COLON: match: cb_insert_empty_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } BLOCK_SCALAR: match: cb_send_block_scalar EOL: { } FLOWSEQ_START: match: cb_start_flowseq new: NEWFLOWSEQ FLOWMAP_START: match: cb_start_flowmap new: NEWFLOWMAP DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: NODETYPE_SCALAR_OR_MAP NODETYPE_COMPLEX: COLON: match: cb_complexcolon EOL: { new: FULLNODE } WS: { new: FULLNODE } DEFAULT: match: cb_empty_complexvalue new: NODETYPE_MAP EOL: new: NODETYPE_COMPLEX RULE_FULLFLOWSCALAR: ANCHOR: match: cb_anchor EOL: { new: RULE_FULLFLOWSCALAR_ANCHOR } DEFAULT: { new: RULE_FULLFLOWSCALAR_ANCHOR } TAG: match: cb_tag EOL: { new: RULE_FULLFLOWSCALAR_TAG } DEFAULT: { new: RULE_FULLFLOWSCALAR_TAG } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FULLFLOWSCALAR_ANCHOR: WS: { new: RULE_FULLFLOWSCALAR_ANCHOR } TAG: match: cb_tag WS: { new: RULE_FLOWSCALAR } EOL: { new: RULE_FLOWSCALAR } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FULLFLOWSCALAR_TAG: WS: { new: RULE_FULLFLOWSCALAR_TAG } ANCHOR: match: cb_anchor WS: { new: RULE_FLOWSCALAR } EOL: { new: RULE_FLOWSCALAR } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FLOWSCALAR: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_alias, return: 1 } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } WS: { match: cb_send_scalar, return: 1 } DEFAULT: { match: cb_send_scalar, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } PLAIN: match: cb_start_plain EOL: { match: cb_send_scalar } DEFAULT: { match: cb_send_scalar, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } FLOW_COMMA: { match: cb_empty_flow_mapkey, return: 1 } FLOWMAP_END: match: cb_end_flowmap_empty return: 1 FLOWSEQ: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_flow_alias, new: FLOWSEQ_NEXT } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY PLAIN_MULTI: { match: cb_send_plain_multi, new: FLOWSEQ_NEXT } QUOTED: match: cb_take_quoted EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY QUOTED_MULTILINE: { match: cb_quoted_multiline, new: FLOWSEQ_NEXT } COLON: WS: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR FLOWSEQ_PROPS: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY PLAIN_MULTI: { match: cb_send_plain_multi, new: FLOWSEQ_NEXT } QUOTED: match: cb_take_quoted EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY QUOTED_MULTILINE: { match: cb_quoted_multiline, new: FLOWSEQ_NEXT } FLOW_COMMA: match: cb_empty_flowseq_comma return: 1 FLOWSEQ_END: match: cb_empty_flowseq_end return: 1 COLON: WS: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR FLOWSEQ_EMPTY: FLOW_COMMA: match: cb_empty_flowseq_comma return: 1 FLOWSEQ_END: match: cb_empty_flowseq_end return: 1 FLOWSEQ_NEXT: WS: { new: FLOWSEQ_NEXT } EOL: { new: FLOWSEQ_NEXT } FLOW_COMMA: match: cb_flow_comma return: 1 FLOWSEQ_END: match: cb_end_flowseq return: 1 FLOWSEQ_MAYBE_KEY: WS: { new: FLOWSEQ_MAYBE_KEY } COLON: WS: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR DEFAULT: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR DEFAULT: new: FLOWSEQ_NEXT FLOWMAP_CONTENT: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_alias, return: 1 } PLAIN: { match: cb_flowkey_plain, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } QUOTED: { match: cb_flowkey_quoted, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR FLOWMAP_PROPS: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } PLAIN: { match: cb_flowkey_plain, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } QUOTED: { match: cb_flowkey_quoted, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 FLOWMAP_EMPTYKEY: FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 NEWFLOWSEQ: EOL: { new: NEWFLOWSEQ } WS: { new: NEWFLOWSEQ } ANCHOR: match: cb_anchor WS: { new: NEWFLOWSEQ_ANCHOR_SPC } EOL: { new: NEWFLOWSEQ_ANCHOR_SPC } DEFAULT: { new: NEWFLOWSEQ_ANCHOR } TAG: match: cb_tag WS: { new: NEWFLOWSEQ_TAG_SPC } EOL: { new: NEWFLOWSEQ_TAG_SPC } DEFAULT: { new: NEWFLOWSEQ_TAG } FLOWSEQ_END: match: cb_end_flowseq return: 1 DEFAULT: { new: FLOWSEQ } NODETYPE_FLOWSEQ: EOL: { new: NODETYPE_FLOWSEQ } WS: { new: NODETYPE_FLOWSEQ } FLOWSEQ_END: match: cb_end_flowseq return: 1 DEFAULT: { new: NEWFLOWSEQ } NODETYPE_FLOWMAPVALUE: WS: { new: NODETYPE_FLOWMAPVALUE } EOL: { new: NODETYPE_FLOWMAPVALUE } COLON: match: cb_flow_colon WS: { new: RULE_FULLFLOWSCALAR } EOL: { new: RULE_FULLFLOWSCALAR } DEFAULT: { new: RULE_FULLFLOWSCALAR } FLOW_COMMA: match: cb_empty_flowmap_value return: 1 FLOWMAP_END: match: cb_end_flowmap_empty return: 1 NEWFLOWSEQ_ANCHOR: DEFAULT: { new: FLOWSEQ_EMPTY } NEWFLOWSEQ_TAG: DEFAULT: { new: FLOWSEQ_EMPTY } NEWFLOWSEQ_ANCHOR_SPC: WS: { new: NEWFLOWSEQ_ANCHOR_SPC } EOL: { new: NEWFLOWSEQ_ANCHOR_SPC } TAG: match: cb_tag WS: { new: FLOWSEQ_PROPS } EOL: { new: FLOWSEQ_PROPS } DEFAULT: { new: FLOWSEQ_EMPTY } DEFAULT: { new: FLOWSEQ_PROPS } NEWFLOWSEQ_TAG_SPC: WS: { new: NEWFLOWSEQ_TAG_SPC } EOL: { new: NEWFLOWSEQ_TAG_SPC } ANCHOR: match: cb_anchor WS: { new: FLOWSEQ_PROPS } EOL: { new: FLOWSEQ_PROPS } DEFAULT: { new: FLOWSEQ_EMPTY } DEFAULT: { new: FLOWSEQ_PROPS } NEWFLOWMAP_ANCHOR: DEFAULT: { new: FLOWMAP_EMPTYKEY } NEWFLOWMAP_TAG: DEFAULT: { new: FLOWMAP_EMPTYKEY } NEWFLOWMAP_ANCHOR_SPC: WS: { new: NEWFLOWMAP_ANCHOR_SPC } EOL: { new: NEWFLOWMAP_ANCHOR_SPC } TAG: match: cb_tag WS: { new: FLOWMAP_PROPS } EOL: { new: FLOWMAP_PROPS } DEFAULT: { new: FLOWMAP_EMPTYKEY } DEFAULT: { new: FLOWMAP_PROPS } NEWFLOWMAP_TAG_SPC: WS: { new: NEWFLOWMAP_TAG_SPC } EOL: { new: NEWFLOWMAP_TAG_SPC } ANCHOR: match: cb_anchor WS: { new: FLOWMAP_PROPS } EOL: { new: FLOWMAP_PROPS } DEFAULT: { new: FLOWMAP_EMPTYKEY } DEFAULT: { new: FLOWMAP_PROPS } NEWFLOWMAP: EOL: { new: NEWFLOWMAP } WS: { new: NEWFLOWMAP } QUESTION: { match: cb_flow_question, new: FLOWMAP_EXPLICIT_KEY } DEFAULT: { new: FLOWMAP } FLOWMAP_EXPLICIT_KEY: WS: { new: FLOWMAP_EXPLICIT_KEY } EOL: { new: FLOWMAP_EXPLICIT_KEY } FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 DEFAULT: { new: FLOWMAP } FLOWMAP: EOL: { new: FLOWMAP } WS: { new: FLOWMAP } ANCHOR: match: cb_anchor WS: { new: NEWFLOWMAP_ANCHOR_SPC } EOL: { new: NEWFLOWMAP_ANCHOR_SPC } DEFAULT: { new: NEWFLOWMAP_ANCHOR } TAG: match: cb_tag WS: { new: NEWFLOWMAP_TAG_SPC } EOL: { new: NEWFLOWMAP_TAG_SPC } DEFAULT: { new: NEWFLOWMAP_TAG } FLOWMAP_END: match: cb_end_flowmap return: 1 COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR DEFAULT: { new: FLOWMAP_CONTENT } NODETYPE_FLOWMAP: EOL: { new: NODETYPE_FLOWMAP } WS: { new: NODETYPE_FLOWMAP } FLOWMAP_END: match: cb_end_flowmap return: 1 FLOW_COMMA: { match: cb_flow_comma, new: NEWFLOWMAP } DEFAULT: { new: NEWFLOWMAP } END_FLOW: EOL: match: cb_end_outer_flow return: 1 RULE_MAPKEY: QUESTION: match: cb_question EOL: { new: FULLNODE } WS: { new: FULLNODE } ALIAS: match: cb_send_alias_key WS: COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUOTED: match: cb_take_quoted_key WS: COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } PLAIN: match: cb_mapkey WS: COLON: match: cb_send_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_send_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_empty_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: RULE_MAPKEY NODETYPE_SEQ: DASH: match: cb_seqitem EOL: { new: FULLNODE } WS: { new: FULLNODE } DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: NODETYPE_SEQ NODETYPE_MAP: ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } FULLNODE_ANCHOR: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_ANCHOR } DEFAULT: { new: NODETYPE_NODE } FULLNODE_TAG: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP, } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_TAG } DEFAULT: { new: NODETYPE_NODE } FULLNODE_TAG_ANCHOR: ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_TAG_ANCHOR } DEFAULT: { new: NODETYPE_NODE } FULLNODE: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_ANCHOR } WS: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG } WS: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE } DEFAULT: { new: NODETYPE_NODE } FULLMAPVALUE_INLINE: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_ANCHOR } WS: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG } WS: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } NODETYPE_MAPVALUE_INLINE: ALIAS: match: cb_send_alias EOL: { } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } QUOTED_MULTILINE: match: cb_quoted_multiline EOL: { } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar PLAIN_MULTI: match: cb_send_plain_multi EOL: { } BLOCK_SCALAR: match: cb_send_block_scalar EOL: { } FLOWSEQ_START: match: cb_start_flowseq new: NEWFLOWSEQ FLOWMAP_START: match: cb_start_flowmap new: NEWFLOWMAP DOC_END: match: cb_end_document EOL: { } DOCUMENT_END: DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: DOCUMENT_END STREAM: DOC_END: match: cb_end_document_empty EOL: { } DOC_START: match: cb_doc_start_explicit EOL: { new: FULLNODE } WS: { new: FULLNODE } YAML_DIRECTIVE: match: cb_set_yaml_version_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } RESERVED_DIRECTIVE: match: cb_reserved_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } TAG_DIRECTIVE: match: cb_tag_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } EOL: new: STREAM DEFAULT: match: cb_doc_start_implicit new: FULLNODE DIRECTIVE: DOC_START: match: cb_doc_start_explicit EOL: { new: FULLNODE } WS: { new: FULLNODE } YAML_DIRECTIVE: match: cb_set_yaml_version_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } RESERVED_DIRECTIVE: match: cb_reserved_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } TAG_DIRECTIVE: match: cb_tag_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } EOL: new: DIRECTIVE 07070100000015000081A40000000000000000000000016616D6BA00000496000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/etc/json-numbers.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use JSON (); use JSON::PP (); use JSON::XS (); use Cpanel::JSON::XS (); require Mojolicious; use Mojo::JSON (); use B (); use Text::Table; my @classes = qw/ JSON JSON::PP JSON::XS Cpanel::JSON::XS Mojo::JSON /; my $t = Text::Table->new( qw/ Class Version 3 IV NV PV 3.140 IV NV PV 3.00 IV NV PV 0.3e3 IV NV PV encode /, ); my $json = <<'EOM'; [ 3, 3.140, 3.00, 0.3e3 ] EOM my @rows; for my $class (@classes) { my $version = $class eq 'Mojo::JSON' ? Mojolicious->VERSION : $class->VERSION; my @row = ( $class, $version ); my $decode = $class->can("decode_json"); my $encode = $class->can("encode_json"); my $data = $decode->($json); for my $num (@$data) { my $flags = B::svref_2object(\$num)->FLAGS; my $int = $flags & B::SVp_IOK ? 1 : 0; my $float = $flags & B::SVp_NOK ? 1 : 0; my $str = $flags & B::SVp_POK ? 1 : 0; push @row, '', $int, $float, $str; } my $enc = $encode->($data); push @row, $enc; push @rows, \@row; } say "Input: $json"; $t->load(@rows); say $t; 07070100000016000081A40000000000000000000000016616D6BA00000712000000000000000000000000000000000000004500000000perl-YAML-PP-3.14.1712772794.39ac610/etc/schema-test-yaml-modules.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use Data::Dumper; use FindBin '$Bin'; use lib "$Bin/../lib"; use YAML::PP; use JSON::PP; $YAML::XS::Boolean = 'JSON::PP'; use YAML::XS (); $YAML::Syck::ImplicitTyping = 1; use YAML::Syck (); $YAML::Numify = 1; use YAML (); use B; my $int_flags = B::SVp_IOK; my $float_flags = B::SVp_NOK; #my $yp = YAML::PP->new( schema => my $file = "$Bin/../ext/yaml-test-schema/yaml-schema.yaml"; my $outputfile = "$Bin/../examples/yaml-schema-modules.yaml"; my $data = YAML::PP::LoadFile($file); my %examples; my %output; my %special = ( (0+'nan').'' => 'nan', (0+'inf').'' => 'inf', (0-'inf').'' => 'inf' ); for my $input (sort keys %$data) { for my $mod (qw/ YAML YAML::XS YAML::Syck /) { my $out = $output{ $input }->{ $mod } ||= {}; my $output; my $load = $mod->can("Load"); my $dump = $mod->can("Dump"); my $data = eval { $load->("--- $input") }; if ($@) { $out->{error} = 1; $out->{type} = 'error'; } else { $out->{type} = get_type($data); $output = $dump->($data); chomp $output; $output =~ s/^--- //; $out->{dump} = $output; } } } YAML::PP::DumpFile($outputfile, \%output); sub get_type { my ($value) = @_; return 'null' unless defined $value; if (ref $value) { if (ref $value eq 'JSON::PP::Boolean') { return 'bool'; } return 'unknown'; } my $flags = B::svref_2object(\$value)->FLAGS; if ($flags & $float_flags) { if (exists $special{ $value }) { return $special{ $value }; } return 'float'; } if ($flags & $int_flags) { return 'int'; } return 'str'; } 07070100000017000081ED0000000000000000000000016616D6BA000026DB000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/etc/test-suite-html.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use FindBin '$Bin'; use lib "$Bin/../lib"; use IO::All; use Data::Dumper; use YAML::PP; use YAML::PP::Dumper; use File::Basename qw/ basename dirname /; use HTML::Entities qw/ encode_entities /; use YAML::PP::Highlight; use JSON::XS (); use Encode; chomp(my $version = qx{git describe --dirty}); my $yaml_test_suite = 'test-suite/yaml-test-suite-data/'; my @dirs = grep { m{/[0-9A-Z]{4}$} } map { "$_" } io->dir($yaml_test_suite)->all; my @subdirs; for my $dir (@dirs) { if (-f "$dir/in.yaml") { push @subdirs, $dir; } else { push @subdirs, grep { m{/[0-9]+$} } map { "$_" } io->dir($dir)->all; } } @subdirs = sort @subdirs; my @valid = grep { not -f "$_/error" } @subdirs; my @invalid = grep { -f "$_/error" } @subdirs; my %tags; for my $tagdir (io->dir("$yaml_test_suite/tags")->all) { for my $id (io->dir($tagdir)->all) { my $tag = basename $tagdir; push @{ $tags{ basename $id } }, basename $tag; } } my $html = <<"EOM"; <html> <head> <title>YAML Test Suite Highlighted</title> <link rel="stylesheet" type="text/css" href="css/yaml.css"> <style> body { font-family: Arial; } table.highlight { border: 1px solid #bbb; border-collapse: collapse; box-shadow: 2px 2px 4px 1px grey; } table.highlight tr th, table.highlight tr td { border: 1px solid #bbb; background-color: white; padding: 2px 3px 2px 3px; } td.error { background-color: #ff7777; } td.diff { background-color: #ffff77; } td.ok { background-color: #7777ff; } span.anchor { color: green; } span.indent { background-color: #e8e8e8; } span.dash { font-weight: bold; color: magenta; } span.colon { font-weight: bold; color: magenta; } span.question { font-weight: bold; color: magenta; } span.yaml_directive { color: cyan; } span.tag_directive { color: cyan; } span.tag { color: blue; } span.comment { color: grey; } span.eol { color: grey; } span.alias { color: green; } span.singlequote { font-weight: bold; color: green; } span.doublequote { font-weight: bold; color: green; } span.singlequoted { color: green; } span.doublequoted { color: green; } span.literal { font-weight: bold; color: magenta; } span.folded { font-weight: bold; color: magenta; } span.doc_start { font-weight: bold; } span.doc_end { font-weight: bold; } span.block_scalar_content { color: #aa7700; border-left: 2px solid #999; margin-left: -2px; } span.tab { background-color: lightblue; } span.error { background-color: #ff8888; } span.trailing_space { border: 1px solid red; margin: -1px; background-color: #eee; } span.flowseq_start { font-weight: bold; color: magenta; } span.flowseq_end { font-weight: bold; color: magenta; } span.flowmap_start { font-weight: bold; color: magenta; } span.flowmap_end { font-weight: bold; color: magenta; } span.flow_comma { font-weight: bold; color: magenta; } pre { background-color: white; padding: 2px; } pre.error { border: 1px solid red; } pre.diff { border: 1px solid #ff9900; } </style> </head> <body> <a href="test-suite.html">YAML Test Suite Test Cases</a> | <a href="schema-examples.html">Schema examples</a> | <a href="schemas.html">Schema comparison</a><hr> Generated with YAML::PP $version<br> <a href="#valid">Valid (@{[ scalar @valid ]})</a><br> <a href="#invalid">Invalid (@{[ scalar @invalid ]})</a><br> EOM my $ypp = YAML::PP->new( boolean => 'JSON::PP', schema => [qw/ Core /], ); my $table; for my $dir (sort @valid) { my $test = highlight_test($dir); $table .= $test; } $html .= <<"EOM"; <h1><a name="valid">Valid</a></h1> <table class="highlight"> <tr> <td></td> <td>YAML::PP::Highlight</td> <td>YAML::PP::Loader | Data::Dump</td> <td>YAML::PP::Loader | JSON::XS</td> <td>YAML::PP::Loader | YAML::PP::Dumper</td> <td>YAML::PP::Parser | YAML::PP::Emitter</td> </tr> $table </table> EOM $table = ''; for my $dir (sort @invalid) { my $test = highlight_test($dir); $table .= $test; } $html .= <<"EOM"; <h1><a name="invalid">Invalid</a></h1> <table class="highlight"> <tr> <td></td> <td>YAML::PP::Highlight</td> <td>YAML::PP::Loader | Data::Dump</td> <td>YAML::PP::Loader | JSON::XS</td> <td>YAML::PP::Loader | YAML::PP::Dumper</td> <td>YAML::PP::Parser | YAML::PP::Emitter</td> </tr> $table </table> EOM sub highlight_test { my ($dir) = @_; my $html; my $file = "$dir/in.yaml"; my $id = basename $dir; my $main_id = $id; if ($id !~ tr/0-9//c) { $main_id = basename(dirname $dir); $id = "$main_id/$id"; } my $title = io->file("$dir/===")->slurp; my $yaml; warn "$id\n"; $yaml = do { open my $fh, '<', $file or die $!; local $/; <$fh> }; $yaml = decode_utf8 $yaml; my $class = "ok"; my @docs; eval { @docs = $ypp->load_string($yaml); }; my $error = $@ || ''; my $tokens = $ypp->loader->parser->tokens; my $diff = 0; if ($error) { $error =~ s{\Q$Bin/../lib/}{}; $class = "error"; my $remaining_tokens = $ypp->loader->parser->_remaining_tokens; push @$tokens, map { +{ %$_, name => 'ERROR' } } @$remaining_tokens; my $out = join '', map { my $value = $_->{value}; my $sub = $_->{subtokens}; if ($sub) { $value = join '', map { defined $_->{orig} ? $_->{orig} : $_->{value} } @$sub; } $value; } @$tokens; if ($out ne $yaml) { local $Data::Dumper::Useqq = 1; warn __PACKAGE__.': '.__LINE__.$".Data::Dumper->Dump([\$out], ['out']); warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$yaml], ['yaml']); warn "$id error diff"; $diff = 1; } } else { my $out = join '', map { my $value = $_->{value}; my $sub = $_->{subtokens}; if ($sub) { $value = join '', map { defined $_->{orig} ? $_->{orig} : $_->{value} } @$sub; } $value; } @$tokens; if ($out ne $yaml) { $class = "diff"; local $Data::Dumper::Useqq = 1; warn __PACKAGE__.': '.__LINE__.$".Data::Dumper->Dump([\$out], ['out']); warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$yaml], ['yaml']); warn "$id diff"; $diff = 1; } } my $coder = JSON::XS->new->ascii->pretty->allow_nonref->canonical; my $json_dump = join "\n", map { "Doc " . ($_+1) . ': ' . $coder->encode( $docs[ $_ ] ); } 0 .. $#docs; my $yppd = YAML::PP->new( boolean => 'JSON::PP' ); my $yaml_dump = $yppd->dump_string(@docs); my @reload_docs = $ypp->load_string($yaml_dump); my $reload_tokens = $ypp->loader->parser->tokens; my $dd = eval { require Data::Dump; 1 }; my $data_dump = join "\n", map { if ($dd) { '$doc' . ($_ + 1) . ' = ' . Data::Dump::dump( $docs[ $_ ] ); } else { local $Data::Dumper::Useqq = 1; local $Data::Dumper::Sortkeys = 1; Data::Dumper->Dump([$docs[ $_ ]], ['doc' . ($_ + 1)]); } } 0 .. $#docs; my $emit_yaml = ''; { my @events; my $parser = YAML::PP::Parser->new( receiver => sub { my ($self, @args) = @_; push @events, [@args]; }, ); eval { $parser->parse_string($yaml); }; if ($@) { # warn "Error parsing: $@"; } else { my $writer = YAML::PP::Writer->new; my $emitter = YAML::PP::Emitter->new(); $emitter->set_writer($writer); eval { for my $event (@events) { my ($type, $info) = @$event; if ($type eq 'sequence_start_event' or $type eq 'mapping_end_event') { delete $info->{style}; } $emitter->$type($info); } }; if ($@) { warn __PACKAGE__.':'.__LINE__.": Error emitting $id: $@\n"; } $emit_yaml = $emitter->writer->output; } } my @emit_docs = eval { $ypp->load_string($emit_yaml) }; my $emit_tokens = $ypp->loader->parser->tokens; $title = decode_utf8($title); $title = encode_entities($title); $error =~ s{\Q$Bin/../lib/}{}g; $error = encode_entities($error); $yaml = encode_entities($yaml); $data_dump = encode_entities($data_dump); $json_dump = encode_entities($json_dump); $yaml_dump = encode_entities($yaml_dump); my $taglist = join ', ', @{ $tags{ $id } || [] }; $html .= <<"EOM"; <tr> <td colspan="6" valign="top" style="background-color: #dddddd"><b>$id - $title</b></td></tr> <tr> <td style="max-width: 15em;" valign="top" >Tags:<br>$taglist<br> <a href="https://github.com/yaml/yaml-test-suite/blob/master/src/$main_id.yaml">View source</a><br> </td> EOM my $high = YAML::PP::Highlight->htmlcolored($tokens); my $reload_high = YAML::PP::Highlight->htmlcolored($reload_tokens); my $emit_high = YAML::PP::Highlight->htmlcolored($emit_tokens); my $orig = $diff ? qq{<br><pre>$yaml</pre>} : ''; $html .= <<"EOM"; <td style="max-width: 20em; overflow-x: auto;" valign="top"><pre class="$class">$high</pre> <pre>$error</pre> $orig </td> <td valign="top" style="max-width: 20em; overflow-x: auto;"> <pre>$data_dump</pre> </td> <td valign="top" style="max-width: 20em; overflow-x: auto;"> <pre>$json_dump</pre> </td> <td valign="top" style="max-width: 20em; overflow-x: auto;"> <pre>$reload_high</pre> </td> <td valign="top" style="max-width: 20em; overflow-x: auto;"> <pre>$emit_high</pre> </td> </tr> EOM return $html; } $html .= <<"EOM"; </body></html> EOM binmode STDOUT, ":encoding(utf-8)"; say $html; 07070100000018000081A40000000000000000000000016616D6BA00000477000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/etc/yaml-numbers.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use YAML (); local $YAML::Numify = 1; use YAML::PP (); use YAML::XS (); use YAML::Syck (); local $YAML::Syck::ImplicitTyping = 1; use YAML::Tiny (); use B (); use Text::Table; my @classes = qw/ YAML YAML::PP YAML::XS YAML::Syck YAML::Tiny /; my $t = Text::Table->new( qw/ Class Version 3 IV NV PV 3.140 IV NV PV 3.00 IV NV PV 0.3e3 IV NV PV Dump /, ); my $yaml = <<'EOM'; - 3 - 3.140 - 3.00 - 0.3e3 EOM my @rows; for my $class (@classes) { my $version = $class->VERSION; my @row = ( $class, $version ); my $decode = $class->can("Load"); my $encode = $class->can("Dump"); my $data = $decode->($yaml); for my $num (@$data) { my $flags = B::svref_2object(\$num)->FLAGS; my $int = $flags & B::SVp_IOK ? 1 : 0; my $float = $flags & B::SVp_NOK ? 1 : 0; my $str = $flags & B::SVp_POK ? 1 : 0; push @row, '', $int, $float, $str; } my $enc = $encode->($data); push @row, $enc; push @rows, \@row; } say "Input:\n$yaml"; $t->load(@rows); say $t; 07070100000019000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002E00000000perl-YAML-PP-3.14.1712772794.39ac610/examples0707010000001A000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000004600000000perl-YAML-PP-3.14.1712772794.39ac610/examples/external-vars-templates0707010000001B000081A40000000000000000000000016616D6BA00000648000000000000000000000000000000000000004D00000000perl-YAML-PP-3.14.1712772794.39ac610/examples/external-vars-templates/ext.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use YAML::PP; use Data::Dumper; my $ypp = YAML::PP->new( schema => ['Failsafe'] ); my ($filename) = @ARGV; my $external_data = { env => \%ENV, argv => \@ARGV, config => { prefix => '/usr/local' }, }; my $schema = $ypp->schema; $schema->add_resolver( tag => "!external", match => [ all => => sub { my ($constructor, $event) = @_; my $value = $event->{value}; path($external_data, $value) }], implicit => 0, ); $schema->add_resolver( tag => "!template", match => [ all => sub { my ($constructor, $event) = @_; my $value = $event->{value}; template($external_data, $value) }], implicit => 0, ); my $data = $ypp->load_file($filename); say $ypp->dump_string($data); # utility functions # turn /env/FOO into $data->{env}->{FOO} sub path { my ($data, $path) = @_; my @paths = split qr{/}, $path; my $replaced = $data; for my $p (@paths) { next unless length $p; if (ref $replaced eq 'ARRAY') { if ($p !~ tr/0-9//c and $p < @$replaced) { $replaced = $replaced->[ $p ]; } else { return; } } elsif (ref $replaced eq 'HASH') { $replaced = $replaced->{ $p }; } last unless defined $replaced; } return $replaced; } # replace ${/some/path} in string with path(...) sub template { my ($data, $string) = @_; $string =~ s<\$\{([\w/]+)\}> <path($data, $1)>eg; return $string; } 0707010000001C000081A40000000000000000000000016616D6BA00000081000000000000000000000000000000000000004F00000000perl-YAML-PP-3.14.1712772794.39ac610/examples/external-vars-templates/ext.yaml--- filename: !external /argv/0 env.LANG: !external /env/LANG argv: !external /argv path: !template "${/config/prefix}/bin/perl" 0707010000001D000081A40000000000000000000000016616D6BA00000429000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/examples/schema-ixhash.pm#!/usr/bin/env perl use strict; use warnings; ### TEST DATA ### my %tests = ( ### - Ordered Hashref (Tie::IxHash) order => [ <<'EOM', tie(my %order, 'Tie::IxHash'); %order = ( U => 2, B => 52, c => 64, 19 => 84, Disco => 2000, Year => 2525, days_on_earth => 20_000, ); \%order; EOM <<'EOM', --- - &1 U: 2 B: 52 c: 64 19: 84 Disco: 2000 Year: 2525 days_on_earth: 20000 - *1 EOM ], ### - Blessed Ordered Hashref order_blessed => [ <<'EOM', tie(my %order, 'Tie::IxHash'); %order = ( U => 2, B => 52, c => 64, 19 => 84, Disco => 2000, Year => 2525, days_on_earth => 20_000, ); bless \%order, 'Order'; EOM <<'EOM', --- - &1 !perl/hash:Order U: 2 B: 52 c: 64 19: 84 Disco: 2000 Year: 2525 days_on_earth: 20000 - *1 EOM ], ); ### TEST DATA END ### \%tests; 0707010000001E000081A40000000000000000000000016616D6BA00000B1B000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/examples/schema-perl.pm#!/usr/bin/env perl use strict; use warnings; my %tests = ( hash => [ <<'EOM', { U => 2, B => 52, } EOM <<'EOM', --- - &1 !perl/hash B: 52 U: 2 - *1 EOM { load_only => 1 }, ], hash_blessed => [ <<'EOM', bless { U => 2, B => 52, }, 'A::Very::Exclusive::Class' EOM <<'EOM', --- - &1 !perl/hash:A::Very::Exclusive::Class B: 52 U: 2 - *1 EOM ], array => [ <<'EOM', [ qw/ one two three four / ] EOM <<'EOM', --- - &1 !perl/array - one - two - three - four - *1 EOM { load_only => 1 }, ], array_blessed => [ <<'EOM', bless [ qw/ one two three four / ], "Just::An::Arrayref" EOM <<'EOM', --- - &1 !perl/array:Just::An::Arrayref - one - two - three - four - *1 EOM ], regexp => [ <<'EOM', my $string = 'unblessed'; qr{$string} EOM <<"EOM", --- - &1 !perl/regexp unblessed - *1 EOM ], regexp_blessed => [ <<'EOM', my $string = 'blessed'; bless qr{$string}, "Foo" EOM <<"EOM", --- - &1 !perl/regexp:Foo blessed - *1 EOM ], circular => [ <<'EOM', my $circle = bless [ 1, 2 ], 'Circle'; push @$circle, $circle; $circle; EOM <<'EOM', --- - &1 !perl/array:Circle - 1 - 2 - *1 - *1 EOM ], coderef => [ <<'EOM', sub { my (%args) = @_; return $args{x} + $args{y}; } EOM qr{- &1 !{1,2}perl/code \|-.*return.*args.*x.*\+.*y}s, { load_code => 1 }, ], coderef_blessed => [ <<'EOM', bless sub { my (%args) = @_; return $args{x} - $args{y}; }, "I::Am::Code" EOM qr{- &1 !{1,2}perl/code:I::Am::Code \|-.*return.*args.*x.*\-.*y}s, { load_code => 1 }, ], scalarref => [ <<'EOM', my $scalar = "some string"; my $scalarref = \$scalar; $scalarref; EOM <<'EOM', --- - &1 !perl/scalar =: some string - *1 EOM ], scalarref_blessed => [ <<'EOM', my $scalar = "some other string"; my $scalarref = bless \$scalar, 'Foo'; $scalarref; EOM <<'EOM', --- - &1 !perl/scalar:Foo =: some other string - *1 EOM ], refref => [ <<'EOM', my $ref = { a => 'hash' }; my $refref = \$ref; $refref; EOM <<'EOM', --- - &1 !perl/ref =: a: hash - *1 EOM ], refref_blessed => [ <<'EOM', my $ref = { a => 'hash' }; my $refref = bless \$ref, 'Foo'; $refref; EOM <<'EOM', --- - &1 !perl/ref:Foo =: a: hash - *1 EOM ], ); \%tests; 0707010000001F000081A40000000000000000000000016616D6BA00000212000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/examples/schemas.pl#!/usr/bin/env perl use strict; use warnings; use FindBin '$Bin'; use lib "$Bin/../lib"; use YAML::PP; my $tests_perl = require "$Bin/schema-perl.pm"; my $tests_ixhash = require "$Bin/schema-ixhash.pm"; my %tests = ( %$tests_perl, %$tests_ixhash, ); my %all_data; for my $name (sort keys %tests) { my $test = $tests{ $name }; my $data = eval $test->[0]; $all_data{ $name } = $data; } my $yp = YAML::PP->new( schema => [qw/ JSON Perl Tie::IxHash /] ); my $yaml = $yp->dump_string(\%all_data); print $yaml; 07070100000020000081A40000000000000000000000016616D6BA00000BD4000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/examples/strings.yaml############################################### # Various strings ############################################### '" "': failsafe, json, core, yaml11: ['str', ' ', "' '"] '"@array"': failsafe, json, core, yaml11: ['str', '@array', "'@array'"] '"%percent"': failsafe, json, core, yaml11: ['str', '%percent', "'%percent'"] '"`cmd`"': failsafe, json, core, yaml11: ['str', '`cmd`', "'`cmd`'"] '"!string"': failsafe, json, core, yaml11: ['str', '!string', "'!string'"] '"*string"': failsafe, json, core, yaml11: ['str', '*string', "'*string'"] '"string:"': failsafe, json, core, yaml11: ['str', 'string:', "'string:'"] '"string "': failsafe, json, core, yaml11: ['str', 'string ', "'string '"] '"string\t"': failsafe, json, core, yaml11: ['str', "string\t", '"string\t"'] '"string\r"': failsafe, json, core, yaml11: ['str', "string\r", '"string\r"'] '"key: val"': failsafe, json, core, yaml11: ['str', 'key: val', "'key: val'"] '"-"': failsafe, json, core, yaml11: ['str', '-', "'-'"] '"- "': failsafe, json, core, yaml11: ['str', '- ', "'- '"] '"-\n"': failsafe, json, core, yaml11: ['str', "-\n", "|\n -"] '"-\t"': failsafe, json, core, yaml11: ['str', "-\t", '"-\t"'] '"- a"': failsafe, json, core, yaml11: ['str', '- a', "'- a'"] '":"': failsafe, json, core, yaml11: ['str', ':', "':'"] '"{"': failsafe, json, core, yaml11: ['str', '{', "'{'"] '"}"': failsafe, json, core, yaml11: ['str', '}', "'}'"] '"["': failsafe, json, core, yaml11: ['str', '[', "'['"] '"]"': failsafe, json, core, yaml11: ['str', ']', "']'"] '","': failsafe, json, core, yaml11: ['str', ',', "','"] '"?"': failsafe, json, core, yaml11: ['str', '?', "'?'"] '"? "': failsafe, json, core, yaml11: ['str', '? ', "'? '"] '"? a"': failsafe, json, core, yaml11: ['str', '? a', "'? a'"] '"#"': failsafe, json, core, yaml11: ['str', '#', "'#'"] '"no comment #"': failsafe, json, core, yaml11: ['str', 'no comment #', "'no comment #'"] '"# "': failsafe, json, core, yaml11: ['str', '# ', "'# '"] '"no #comment"': failsafe, json, core, yaml11: ['str', 'no #comment', "'no #comment'"] '"|"': failsafe, json, core, yaml11: ['str', '|', "'|'"] '">"': failsafe, json, core, yaml11: ['str', '>', "'>'"] '"''"': failsafe, json, core, yaml11: ['str', '''', "\"'\""] '"''\""': failsafe, json, core, yaml11: ['str', '''"', "'''\"'"] '"\""': failsafe, json, core, yaml11: ['str', '"', "'\"'"] '"\n "': failsafe, json, core, yaml11: ['str', "\n ", '"\n "'] '" \n"': failsafe, json, core, yaml11: ['str', " \n", '" \n"'] '"foo\nbar"': failsafe, json, core, yaml11: ['str', "foo\nbar", "|-\n foo\n bar"] '"x\n\"y\\z"': failsafe, json, core, yaml11: ['str', "x\n\"y\\z", "|-\n x\n \"y\\z"] '"no comment#"': failsafe, json, core, yaml11: ['str', 'no comment#', "no comment#"] 'foo\bar': failsafe, json, core, yaml11: ['str', 'foo\bar', 'foo\bar'] '^string': failsafe, json, core, yaml11: ['str', '^string', '^string'] 'str"ing': failsafe, json, core, yaml11: ['str', 'str"ing', 'str"ing'] 07070100000021000081A40000000000000000000000016616D6BA0000A0A6000000000000000000000000000000000000004700000000perl-YAML-PP-3.14.1712772794.39ac610/examples/yaml-schema-modules.yaml--- '!!bool FALSE': YAML: dump: 'FALSE' type: str YAML::Syck: dump: '''FALSE''' type: str YAML::XS: error: 1 type: error '!!bool False': YAML: dump: 'False' type: str YAML::Syck: dump: '''False''' type: str YAML::XS: error: 1 type: error '!!bool N': YAML: dump: N type: str YAML::Syck: dump: '''N''' type: str YAML::XS: error: 1 type: error '!!bool NO': YAML: dump: NO type: str YAML::Syck: dump: '''NO''' type: str YAML::XS: error: 1 type: error '!!bool OFF': YAML: dump: OFF type: str YAML::Syck: dump: '''OFF''' type: str YAML::XS: error: 1 type: error '!!bool ON': YAML: dump: ON type: str YAML::Syck: dump: '''ON''' type: str YAML::XS: error: 1 type: error '!!bool Off': YAML: dump: Off type: str YAML::Syck: dump: '''Off''' type: str YAML::XS: error: 1 type: error '!!bool On': YAML: dump: On type: str YAML::Syck: dump: '''On''' type: str YAML::XS: error: 1 type: error '!!bool TRUE': YAML: dump: 'TRUE' type: str YAML::Syck: dump: '''TRUE''' type: str YAML::XS: error: 1 type: error '!!bool True': YAML: dump: 'True' type: str YAML::Syck: dump: '''True''' type: str YAML::XS: error: 1 type: error '!!bool Y': YAML: dump: Y type: str YAML::Syck: dump: '''Y''' type: str YAML::XS: error: 1 type: error '!!bool YES': YAML: dump: YES type: str YAML::Syck: dump: '''YES''' type: str YAML::XS: error: 1 type: error '!!bool Yes': YAML: dump: Yes type: str YAML::Syck: dump: '''Yes''' type: str YAML::XS: error: 1 type: error '!!bool false': YAML: dump: 'false' type: str YAML::Syck: dump: '''false''' type: str YAML::XS: error: 1 type: error '!!bool n': YAML: dump: n type: str YAML::Syck: dump: '''n''' type: str YAML::XS: error: 1 type: error '!!bool no': YAML: dump: no type: str YAML::Syck: dump: '''no''' type: str YAML::XS: error: 1 type: error '!!bool off': YAML: dump: off type: str YAML::Syck: dump: '''off''' type: str YAML::XS: error: 1 type: error '!!bool on': YAML: dump: on type: str YAML::Syck: dump: '''on''' type: str YAML::XS: error: 1 type: error '!!bool true': YAML: dump: 'true' type: str YAML::Syck: dump: '''true''' type: str YAML::XS: error: 1 type: error '!!bool y': YAML: dump: y type: str YAML::Syck: dump: '''y''' type: str YAML::XS: error: 1 type: error '!!bool yes': YAML: dump: yes type: str YAML::Syck: dump: '''yes''' type: str YAML::XS: error: 1 type: error '!!float +.INF': YAML: dump: '+.INF' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float +.Inf': YAML: dump: '+.Inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float +.inf': YAML: dump: '+.inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float +0.3e+3': YAML: dump: '+0.3e+3' type: str YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '+0.3e+3' type: float '!!float +0.3e3': YAML: dump: '+0.3e3' type: str YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '+0.3e3' type: float '!!float -.INF': YAML: dump: '-.INF' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float -.Inf': YAML: dump: '-.Inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float -.inf': YAML: dump: '-.inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float -3.14': YAML: dump: '-3.14' type: float YAML::Syck: dump: '''-3.14''' type: float YAML::XS: dump: '-3.14' type: float '!!float .0': YAML: dump: '0' type: float YAML::Syck: dump: '''0''' type: float YAML::XS: dump: '.0' type: float '!!float .3E-1': YAML: dump: '0.03' type: float YAML::Syck: dump: '''0.03''' type: float YAML::XS: dump: '.3E-1' type: float '!!float .3e+3': YAML: dump: '300' type: int YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '.3e+3' type: float '!!float .3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '.3e3' type: float '!!float .INF': YAML: dump: '.INF' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float .Inf': YAML: dump: '.Inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float .NAN': YAML: dump: '.NAN' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float .NaN': YAML: dump: '.NaN' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float .inf': YAML: dump: '.inf' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float .nan': YAML: dump: '.nan' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!float 0.0': YAML: dump: '0' type: float YAML::Syck: dump: '''0''' type: float YAML::XS: dump: '0.0' type: float '!!float 0.3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '0.3e3' type: float '!!float 001.23': YAML: dump: '001.23' type: str YAML::Syck: dump: '''1.23''' type: float YAML::XS: dump: '001.23' type: float '!!float 190:20:30.15': YAML: dump: 190:20:30.15 type: str YAML::Syck: dump: '''190''' type: float YAML::XS: error: 1 type: error '!!float 3.14': YAML: dump: '3.14' type: float YAML::Syck: dump: '''3.14''' type: float YAML::XS: dump: '3.14' type: float '!!float 3.3e+3': YAML: dump: '3300' type: int YAML::Syck: dump: '''3300''' type: float YAML::XS: dump: '3.3e+3' type: float '!!float 85.230_15e+03': YAML: dump: 85.230_15e+03 type: str YAML::Syck: dump: '''85.23''' type: float YAML::XS: error: 1 type: error '!!float 85_230.15': YAML: dump: 85_230.15 type: str YAML::Syck: dump: '''85''' type: float YAML::XS: error: 1 type: error '!!int +0': YAML: dump: '+0' type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: '+0' type: int '!!int +0100_200': YAML: dump: +0100_200 type: str YAML::Syck: dump: '''100''' type: float YAML::XS: error: 1 type: error '!!int +0b100': YAML: dump: +0b100 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int +190:20:30': YAML: dump: +190:20:30 type: str YAML::Syck: dump: '''190''' type: float YAML::XS: error: 1 type: error '!!int +23': YAML: dump: '+23' type: str YAML::Syck: dump: '23' type: int YAML::XS: dump: '+23' type: int '!!int -0': YAML: dump: '0' type: int YAML::Syck: dump: '0' type: int YAML::XS: dump: '-0' type: int '!!int -0100_200': YAML: dump: -0100_200 type: str YAML::Syck: dump: '''-100''' type: float YAML::XS: error: 1 type: error '!!int -0b101': YAML: dump: -0b101 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int -0x30': YAML: dump: -0x30 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int -190:20:30': YAML: dump: -190:20:30 type: str YAML::Syck: dump: '''-190''' type: float YAML::XS: error: 1 type: error '!!int -23': YAML: dump: '-23' type: int YAML::Syck: dump: '-23' type: int YAML::XS: dump: '-23' type: int '!!int 0': YAML: dump: '0' type: int YAML::Syck: dump: '0' type: int YAML::XS: dump: '0' type: int '!!int 00': YAML: dump: '00' type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: '00' type: int '!!int 0011': YAML: dump: '0011' type: str YAML::Syck: dump: '11' type: int YAML::XS: dump: '0011' type: int '!!int 010': YAML: dump: '010' type: str YAML::Syck: dump: '10' type: int YAML::XS: dump: '010' type: int '!!int 02_0': YAML: dump: 02_0 type: str YAML::Syck: dump: '''2''' type: float YAML::XS: error: 1 type: error '!!int 07': YAML: dump: '07' type: str YAML::Syck: dump: '7' type: int YAML::XS: dump: '07' type: int '!!int 0b0': YAML: dump: 0b0 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0b100_101': YAML: dump: 0b100_101 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0o0': YAML: dump: '0o0' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0o10': YAML: dump: '0o10' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0o7': YAML: dump: '0o7' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0x0': YAML: dump: '0x0' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0x10': YAML: dump: '0x10' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0x2_0': YAML: dump: 0x2_0 type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0x42': YAML: dump: '0x42' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 0xa': YAML: dump: '0xa' type: str YAML::Syck: dump: '''0''' type: float YAML::XS: error: 1 type: error '!!int 100_000': YAML: dump: 100_000 type: str YAML::Syck: dump: '''100''' type: float YAML::XS: error: 1 type: error '!!int 190:20:30': YAML: dump: 190:20:30 type: str YAML::Syck: dump: '''190''' type: float YAML::XS: error: 1 type: error '!!int 23': YAML: dump: '23' type: int YAML::Syck: dump: '23' type: int YAML::XS: dump: '23' type: int '!!null #empty': YAML: dump: '''#empty''' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' '!!null NULL': YAML: dump: 'NULL' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: error: 1 type: error '!!null Null': YAML: dump: 'Null' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: error: 1 type: error '!!null null': YAML: dump: 'null' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' '!!null ~': YAML: dump: '''~''' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' '!!str #empty': YAML: dump: '''#empty''' type: str YAML::Syck: dump: '''''' type: str YAML::XS: dump: '''''' type: str '!!str +.INF': YAML: dump: '+.INF' type: str YAML::Syck: dump: '+.INF' type: str YAML::XS: dump: '+.INF' type: str '!!str +.Inf': YAML: dump: '+.Inf' type: str YAML::Syck: dump: '+.Inf' type: str YAML::XS: dump: '+.Inf' type: str '!!str +.inf': YAML: dump: '+.inf' type: str YAML::Syck: dump: '+.inf' type: str YAML::XS: dump: '+.inf' type: str '!!str +0': YAML: dump: '+0' type: str YAML::Syck: dump: '+0' type: str YAML::XS: dump: '''+0''' type: str '!!str +0.3e+3': YAML: dump: '+0.3e+3' type: str YAML::Syck: dump: '''+0.3e+3''' type: str YAML::XS: dump: '''+0.3e+3''' type: str '!!str +0.3e3': YAML: dump: '+0.3e3' type: str YAML::Syck: dump: '''+0.3e3''' type: str YAML::XS: dump: '''+0.3e3''' type: str '!!str +0100_200': YAML: dump: +0100_200 type: str YAML::Syck: dump: +0100_200 type: str YAML::XS: dump: +0100_200 type: str '!!str +0b100': YAML: dump: +0b100 type: str YAML::Syck: dump: +0b100 type: str YAML::XS: dump: +0b100 type: str '!!str +190:20:30': YAML: dump: +190:20:30 type: str YAML::Syck: dump: +190:20:30 type: str YAML::XS: dump: +190:20:30 type: str '!!str +23': YAML: dump: '+23' type: str YAML::Syck: dump: '+23' type: str YAML::XS: dump: '''+23''' type: str '!!str -.INF': YAML: dump: '-.INF' type: str YAML::Syck: dump: '-.INF' type: str YAML::XS: dump: '-.INF' type: str '!!str -.Inf': YAML: dump: '-.Inf' type: str YAML::Syck: dump: '-.Inf' type: str YAML::XS: dump: '-.Inf' type: str '!!str -.inf': YAML: dump: '-.inf' type: str YAML::Syck: dump: '-.inf' type: str YAML::XS: dump: '-.inf' type: str '!!str -0': YAML: dump: '0' type: int YAML::Syck: dump: '''-0''' type: str YAML::XS: dump: '''-0''' type: str '!!str -0100_200': YAML: dump: -0100_200 type: str YAML::Syck: dump: -0100_200 type: str YAML::XS: dump: -0100_200 type: str '!!str -0b101': YAML: dump: -0b101 type: str YAML::Syck: dump: -0b101 type: str YAML::XS: dump: -0b101 type: str '!!str -0x30': YAML: dump: -0x30 type: str YAML::Syck: dump: -0x30 type: str YAML::XS: dump: -0x30 type: str '!!str -190:20:30': YAML: dump: -190:20:30 type: str YAML::Syck: dump: -190:20:30 type: str YAML::XS: dump: -190:20:30 type: str '!!str -23': YAML: dump: '-23' type: int YAML::Syck: dump: '-23' type: str YAML::XS: dump: '''-23''' type: str '!!str -3.14': YAML: dump: '-3.14' type: float YAML::Syck: dump: '''-3.14''' type: str YAML::XS: dump: '''-3.14''' type: str '!!str .0': YAML: dump: '0' type: float YAML::Syck: dump: '.0' type: str YAML::XS: dump: '''.0''' type: str '!!str .3E-1': YAML: dump: '0.03' type: float YAML::Syck: dump: '''.3E-1''' type: str YAML::XS: dump: '''.3E-1''' type: str '!!str .3e+3': YAML: dump: '300' type: int YAML::Syck: dump: '''.3e+3''' type: str YAML::XS: dump: '''.3e+3''' type: str '!!str .3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''.3e3''' type: str YAML::XS: dump: '''.3e3''' type: str '!!str .INF': YAML: dump: '.INF' type: str YAML::Syck: dump: '.INF' type: str YAML::XS: dump: '.INF' type: str '!!str .Inf': YAML: dump: '.Inf' type: str YAML::Syck: dump: '.Inf' type: str YAML::XS: dump: '.Inf' type: str '!!str .NAN': YAML: dump: '.NAN' type: str YAML::Syck: dump: '.NAN' type: str YAML::XS: dump: '.NAN' type: str '!!str .NaN': YAML: dump: '.NaN' type: str YAML::Syck: dump: '.NaN' type: str YAML::XS: dump: '.NaN' type: str '!!str .inf': YAML: dump: '.inf' type: str YAML::Syck: dump: '.inf' type: str YAML::XS: dump: '.inf' type: str '!!str .nan': YAML: dump: '.nan' type: str YAML::Syck: dump: '.nan' type: str YAML::XS: dump: '.nan' type: str '!!str 0': YAML: dump: '0' type: int YAML::Syck: dump: '0' type: str YAML::XS: dump: '''0''' type: str '!!str 0.0': YAML: dump: '0' type: float YAML::Syck: dump: '''0.0''' type: str YAML::XS: dump: '''0.0''' type: str '!!str 0.3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''0.3e3''' type: str YAML::XS: dump: '''0.3e3''' type: str '!!str 00': YAML: dump: '00' type: str YAML::Syck: dump: '''00''' type: str YAML::XS: dump: '''00''' type: str '!!str 001.23': YAML: dump: '001.23' type: str YAML::Syck: dump: '''001.23''' type: str YAML::XS: dump: '''001.23''' type: str '!!str 0011': YAML: dump: '0011' type: str YAML::Syck: dump: '''0011''' type: str YAML::XS: dump: '''0011''' type: str '!!str 010': YAML: dump: '010' type: str YAML::Syck: dump: '''010''' type: str YAML::XS: dump: '''010''' type: str '!!str 02_0': YAML: dump: 02_0 type: str YAML::Syck: dump: 02_0 type: str YAML::XS: dump: 02_0 type: str '!!str 07': YAML: dump: '07' type: str YAML::Syck: dump: '''07''' type: str YAML::XS: dump: '''07''' type: str '!!str 0b0': YAML: dump: 0b0 type: str YAML::Syck: dump: 0b0 type: str YAML::XS: dump: 0b0 type: str '!!str 0b100_101': YAML: dump: 0b100_101 type: str YAML::Syck: dump: 0b100_101 type: str YAML::XS: dump: 0b100_101 type: str '!!str 0o0': YAML: dump: '0o0' type: str YAML::Syck: dump: '0o0' type: str YAML::XS: dump: '0o0' type: str '!!str 0o10': YAML: dump: '0o10' type: str YAML::Syck: dump: '0o10' type: str YAML::XS: dump: '0o10' type: str '!!str 0o7': YAML: dump: '0o7' type: str YAML::Syck: dump: '0o7' type: str YAML::XS: dump: '0o7' type: str '!!str 0x0': YAML: dump: '0x0' type: str YAML::Syck: dump: '0x0' type: str YAML::XS: dump: '0x0' type: str '!!str 0x2_0': YAML: dump: 0x2_0 type: str YAML::Syck: dump: 0x2_0 type: str YAML::XS: dump: 0x2_0 type: str '!!str 0xa': YAML: dump: '0xa' type: str YAML::Syck: dump: '0xa' type: str YAML::XS: dump: '0xa' type: str '!!str 100_000': YAML: dump: 100_000 type: str YAML::Syck: dump: 100_000 type: str YAML::XS: dump: 100_000 type: str '!!str 190:20:30': YAML: dump: 190:20:30 type: str YAML::Syck: dump: 190:20:30 type: str YAML::XS: dump: 190:20:30 type: str '!!str 190:20:30.15': YAML: dump: 190:20:30.15 type: str YAML::Syck: dump: 190:20:30.15 type: str YAML::XS: dump: 190:20:30.15 type: str '!!str 23': YAML: dump: '23' type: int YAML::Syck: dump: '23' type: str YAML::XS: dump: '''23''' type: str '!!str 3.14': YAML: dump: '3.14' type: float YAML::Syck: dump: '''3.14''' type: str YAML::XS: dump: '''3.14''' type: str '!!str 3.3e+3': YAML: dump: '3300' type: int YAML::Syck: dump: '''3.3e+3''' type: str YAML::XS: dump: '''3.3e+3''' type: str '!!str 85.230_15e+03': YAML: dump: 85.230_15e+03 type: str YAML::Syck: dump: 85.230_15e+03 type: str YAML::XS: dump: 85.230_15e+03 type: str '!!str 85_230.15': YAML: dump: 85_230.15 type: str YAML::Syck: dump: 85_230.15 type: str YAML::XS: dump: 85_230.15 type: str '!!str FALSE': YAML: dump: 'FALSE' type: str YAML::Syck: dump: '''FALSE''' type: str YAML::XS: dump: 'FALSE' type: str '!!str False': YAML: dump: 'False' type: str YAML::Syck: dump: '''False''' type: str YAML::XS: dump: 'False' type: str '!!str N': YAML: dump: N type: str YAML::Syck: dump: '''N''' type: str YAML::XS: dump: N type: str '!!str NO': YAML: dump: NO type: str YAML::Syck: dump: '''NO''' type: str YAML::XS: dump: NO type: str '!!str NULL': YAML: dump: 'NULL' type: str YAML::Syck: dump: '''NULL''' type: str YAML::XS: dump: 'NULL' type: str '!!str Null': YAML: dump: 'Null' type: str YAML::Syck: dump: '''Null''' type: str YAML::XS: dump: 'Null' type: str '!!str OFF': YAML: dump: OFF type: str YAML::Syck: dump: '''OFF''' type: str YAML::XS: dump: OFF type: str '!!str ON': YAML: dump: ON type: str YAML::Syck: dump: '''ON''' type: str YAML::XS: dump: ON type: str '!!str Off': YAML: dump: Off type: str YAML::Syck: dump: '''Off''' type: str YAML::XS: dump: Off type: str '!!str On': YAML: dump: On type: str YAML::Syck: dump: '''On''' type: str YAML::XS: dump: On type: str '!!str TRUE': YAML: dump: 'TRUE' type: str YAML::Syck: dump: '''TRUE''' type: str YAML::XS: dump: 'TRUE' type: str '!!str True': YAML: dump: 'True' type: str YAML::Syck: dump: '''True''' type: str YAML::XS: dump: 'True' type: str '!!str Y': YAML: dump: Y type: str YAML::Syck: dump: '''Y''' type: str YAML::XS: dump: Y type: str '!!str YES': YAML: dump: YES type: str YAML::Syck: dump: '''YES''' type: str YAML::XS: dump: YES type: str '!!str Yes': YAML: dump: Yes type: str YAML::Syck: dump: '''Yes''' type: str YAML::XS: dump: Yes type: str '!!str false': YAML: dump: 'false' type: str YAML::Syck: dump: '''false''' type: str YAML::XS: dump: '''false''' type: str '!!str n': YAML: dump: n type: str YAML::Syck: dump: '''n''' type: str YAML::XS: dump: n type: str '!!str no': YAML: dump: no type: str YAML::Syck: dump: '''no''' type: str YAML::XS: dump: no type: str '!!str null': YAML: dump: 'null' type: str YAML::Syck: dump: '''null''' type: str YAML::XS: dump: '''null''' type: str '!!str off': YAML: dump: off type: str YAML::Syck: dump: '''off''' type: str YAML::XS: dump: off type: str '!!str on': YAML: dump: on type: str YAML::Syck: dump: '''on''' type: str YAML::XS: dump: on type: str '!!str true': YAML: dump: 'true' type: str YAML::Syck: dump: '''true''' type: str YAML::XS: dump: '''true''' type: str '!!str y': YAML: dump: y type: str YAML::Syck: dump: '''y''' type: str YAML::XS: dump: y type: str '!!str yes': YAML: dump: yes type: str YAML::Syck: dump: '''yes''' type: str YAML::XS: dump: yes type: str '!!str ~': YAML: dump: '''~''' type: str YAML::Syck: dump: '''~''' type: str YAML::XS: dump: '''~''' type: str '" "': YAML: dump: ''' ''' type: str YAML::Syck: dump: '" "' type: str YAML::XS: dump: ''' ''' type: str '"!string"': YAML: dump: '''!string''' type: str YAML::Syck: dump: '"!string"' type: str YAML::XS: dump: '''!string''' type: str '"# "': YAML: dump: '''# ''' type: str YAML::Syck: dump: '"# "' type: str YAML::XS: dump: '''# ''' type: str '"#"': YAML: dump: '''#''' type: str YAML::Syck: dump: '"#"' type: str YAML::XS: dump: '''#''' type: str '"%percent"': YAML: dump: '''%percent''' type: str YAML::Syck: dump: '"%percent"' type: str YAML::XS: dump: '''%percent''' type: str '"''"': YAML: dump: '"''"' type: str YAML::Syck: dump: '"''"' type: str YAML::XS: dump: '''''''''' type: str '"*string"': YAML: dump: '''*string''' type: str YAML::Syck: dump: '"*string"' type: str YAML::XS: dump: '''*string''' type: str '","': YAML: dump: ''',''' type: str YAML::Syck: dump: '","' type: str YAML::XS: dump: ''',''' type: str '"- "': YAML: dump: '''- ''' type: str YAML::Syck: dump: '"- "' type: str YAML::XS: dump: '''- ''' type: str '"- a"': YAML: dump: '''- a''' type: str YAML::Syck: dump: '"- a"' type: str YAML::XS: dump: '''- a''' type: str '"-"': YAML: dump: '''-''' type: str YAML::Syck: dump: '"-"' type: str YAML::XS: dump: '''-''' type: str '"-\n"': YAML: dump: '"-\n"' type: str YAML::Syck: dump: '"-\n"' type: str YAML::XS: dump: |- '- ' type: str '"-\t"': YAML: dump: "'-\t'" type: str YAML::Syck: dump: '"-\t"' type: str YAML::XS: dump: '"-\t"' type: str '":"': YAML: dump: ''':''' type: str YAML::Syck: dump: '":"' type: str YAML::XS: dump: ''':''' type: str '">"': YAML: dump: '''>''' type: str YAML::Syck: dump: '">"' type: str YAML::XS: dump: '''>''' type: str '"? "': YAML: dump: '''? ''' type: str YAML::Syck: dump: '"? "' type: str YAML::XS: dump: '''? ''' type: str '"? a"': YAML: dump: '''? a''' type: str YAML::Syck: dump: '"? a"' type: str YAML::XS: dump: '''? a''' type: str '"?"': YAML: dump: '''?''' type: str YAML::Syck: dump: '"?"' type: str YAML::XS: dump: '''?''' type: str '"@array"': YAML: dump: '''@array''' type: str YAML::Syck: dump: '"@array"' type: str YAML::XS: dump: '''@array''' type: str '"["': YAML: dump: '''[''' type: str YAML::Syck: dump: '"["' type: str YAML::XS: dump: '''[''' type: str '"\""': YAML: dump: '''"''' type: str YAML::Syck: dump: '"\""' type: str YAML::XS: dump: '''"''' type: str '"]"': YAML: dump: ''']''' type: str YAML::Syck: dump: '"]"' type: str YAML::XS: dump: ''']''' type: str '"`cmd`"': YAML: dump: '''`cmd`''' type: str YAML::Syck: dump: '"`cmd`"' type: str YAML::XS: dump: '''`cmd`''' type: str '"foo\nbar"': YAML: dump: '"foo\nbar"' type: str YAML::Syck: dump: '"foo\nbar"' type: str YAML::XS: dump: '"foo\nbar"' type: str '"key: val"': YAML: dump: '''key: val''' type: str YAML::Syck: dump: '"key: val"' type: str YAML::XS: dump: '''key: val''' type: str '"no #comment"': YAML: dump: '''no #comment''' type: str YAML::Syck: dump: '"no #comment"' type: str YAML::XS: dump: '''no #comment''' type: str '"no comment #"': YAML: dump: '''no comment #''' type: str YAML::Syck: dump: '"no comment #"' type: str YAML::XS: dump: '''no comment #''' type: str '"no comment#"': YAML: dump: no comment# type: str YAML::Syck: dump: no comment# type: str YAML::XS: dump: no comment# type: str '"string "': YAML: dump: '''string ''' type: str YAML::Syck: dump: '"string "' type: str YAML::XS: dump: '''string ''' type: str '"string:"': YAML: dump: '''string:''' type: str YAML::Syck: dump: '"string:"' type: str YAML::XS: dump: '''string:''' type: str '"string\r"': YAML: dump: '"string\r"' type: str YAML::Syck: dump: "string\r" type: str YAML::XS: dump: '"string\r"' type: str '"string\t"': YAML: dump: "'string\t'" type: str YAML::Syck: dump: '"string\t"' type: str YAML::XS: dump: '"string\t"' type: str '"x\n\"y\\z"': YAML: dump: '"x\n\"y\\z"' type: str YAML::Syck: dump: '"x\n\"y\\z"' type: str YAML::XS: dump: '"x\n\"y\\z"' type: str '"{"': YAML: dump: '''{''' type: str YAML::Syck: dump: '"{"' type: str YAML::XS: dump: '''{''' type: str '"|"': YAML: dump: '''|''' type: str YAML::Syck: dump: '"|"' type: str YAML::XS: dump: '''|''' type: str '"}"': YAML: dump: '''}''' type: str YAML::Syck: dump: '"}"' type: str YAML::XS: dump: '''}''' type: str '#empty': YAML: dump: '''''' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' '+.INF': YAML: dump: '+.INF' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '+.INF' type: str '+.Inf': YAML: dump: '+.Inf' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '+.Inf' type: str '+.inf': YAML: dump: '+.inf' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '+.inf' type: str '+0': YAML: dump: '+0' type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: '+0' type: int '+0.3e+3': YAML: dump: '+0.3e+3' type: str YAML::Syck: dump: '''300''' type: float YAML::XS: dump: '+0.3e+3' type: float '+0.3e3': YAML: dump: '+0.3e3' type: str YAML::Syck: dump: '''+0.3e3''' type: str YAML::XS: dump: '+0.3e3' type: float +0100_200: YAML: dump: +0100_200 type: str YAML::Syck: dump: +0100_200 type: str YAML::XS: dump: +0100_200 type: str +0b100: YAML: dump: +0b100 type: str YAML::Syck: dump: +0b100 type: str YAML::XS: dump: +0b100 type: str +190:20:30: YAML: dump: +190:20:30 type: str YAML::Syck: dump: '685230' type: int YAML::XS: dump: +190:20:30 type: str '+23': YAML: dump: '+23' type: str YAML::Syck: dump: '23' type: int YAML::XS: dump: '+23' type: int '+3.14': YAML: dump: '+3.14' type: str YAML::Syck: dump: '''3.14''' type: float YAML::XS: dump: '+3.14' type: float '-.INF': YAML: dump: '-.INF' type: str YAML::Syck: dump: '''-Inf''' type: inf YAML::XS: dump: '-.INF' type: str '-.Inf': YAML: dump: '-.Inf' type: str YAML::Syck: dump: '''-Inf''' type: inf YAML::XS: dump: '-.Inf' type: str '-.inf': YAML: dump: '-.inf' type: str YAML::Syck: dump: '''-Inf''' type: inf YAML::XS: dump: '-.inf' type: str '-0': YAML: dump: '0' type: int YAML::Syck: dump: '0' type: int YAML::XS: dump: '-0' type: int -0100_200: YAML: dump: -0100_200 type: str YAML::Syck: dump: -0100_200 type: str YAML::XS: dump: -0100_200 type: str -0b101: YAML: dump: -0b101 type: str YAML::Syck: dump: -0b101 type: str YAML::XS: dump: -0b101 type: str -0x30: YAML: dump: -0x30 type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: -0x30 type: str -190:20:30: YAML: dump: -190:20:30 type: str YAML::Syck: dump: '''18446744073708868846''' type: int YAML::XS: dump: -190:20:30 type: str '-23': YAML: dump: '-23' type: int YAML::Syck: dump: '-23' type: int YAML::XS: dump: '-23' type: int '-3.14': YAML: dump: '-3.14' type: float YAML::Syck: dump: '''-3.14''' type: float YAML::XS: dump: '-3.14' type: float '.0': YAML: dump: '0' type: float YAML::Syck: dump: '.0' type: str YAML::XS: dump: '.0' type: float '.14': YAML: dump: '0.14' type: float YAML::Syck: dump: '.14' type: str YAML::XS: dump: '.14' type: float '.3E-1': YAML: dump: '0.03' type: float YAML::Syck: dump: '''.3E-1''' type: str YAML::XS: dump: '.3E-1' type: float '.3e+3': YAML: dump: '300' type: int YAML::Syck: dump: '''.3e+3''' type: str YAML::XS: dump: '.3e+3' type: float '.3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''.3e3''' type: str YAML::XS: dump: '.3e3' type: float '.INF': YAML: dump: '.INF' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '.INF' type: str '.Inf': YAML: dump: '.Inf' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '.Inf' type: str '.NAN': YAML: dump: '.NAN' type: str YAML::Syck: dump: '''NaN''' type: nan YAML::XS: dump: '.NAN' type: str '.NaN': YAML: dump: '.NaN' type: str YAML::Syck: dump: '''NaN''' type: nan YAML::XS: dump: '.NaN' type: str '.inf': YAML: dump: '.inf' type: str YAML::Syck: dump: '''Inf''' type: inf YAML::XS: dump: '.inf' type: str '.nan': YAML: dump: '.nan' type: str YAML::Syck: dump: '''NaN''' type: nan YAML::XS: dump: '.nan' type: str '0': YAML: dump: '0' type: int YAML::Syck: dump: '0' type: int YAML::XS: dump: '0' type: int '0.0': YAML: dump: '0' type: float YAML::Syck: dump: '''0''' type: float YAML::XS: dump: '0.0' type: float '0.3e3': YAML: dump: '300' type: int YAML::Syck: dump: '''0.3e3''' type: str YAML::XS: dump: '0.3e3' type: float '00': YAML: dump: '00' type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: '00' type: int '001.23': YAML: dump: '001.23' type: str YAML::Syck: dump: '''1.23''' type: float YAML::XS: dump: '001.23' type: float '0011': YAML: dump: '0011' type: str YAML::Syck: dump: '9' type: int YAML::XS: dump: '0011' type: int '010': YAML: dump: '010' type: str YAML::Syck: dump: '8' type: int YAML::XS: dump: '010' type: int 02_0: YAML: dump: 02_0 type: str YAML::Syck: dump: 02_0 type: str YAML::XS: dump: 02_0 type: str '07': YAML: dump: '07' type: str YAML::Syck: dump: '7' type: int YAML::XS: dump: '07' type: int '08': YAML: dump: '08' type: str YAML::Syck: dump: '''08''' type: str YAML::XS: dump: '08' type: int 0b0: YAML: dump: 0b0 type: str YAML::Syck: dump: 0b0 type: str YAML::XS: dump: 0b0 type: str 0b100_101: YAML: dump: 0b100_101 type: str YAML::Syck: dump: 0b100_101 type: str YAML::XS: dump: 0b100_101 type: str '0o0': YAML: dump: '0o0' type: str YAML::Syck: dump: '0o0' type: str YAML::XS: dump: '0o0' type: str '0o10': YAML: dump: '0o10' type: str YAML::Syck: dump: '0o10' type: str YAML::XS: dump: '0o10' type: str '0o7': YAML: dump: '0o7' type: str YAML::Syck: dump: '0o7' type: str YAML::XS: dump: '0o7' type: str '0x0': YAML: dump: '0x0' type: str YAML::Syck: dump: '0' type: int YAML::XS: dump: '0x0' type: str '0x10': YAML: dump: '0x10' type: str YAML::Syck: dump: '16' type: int YAML::XS: dump: '0x10' type: str 0x2_0: YAML: dump: 0x2_0 type: str YAML::Syck: dump: 0x2_0 type: str YAML::XS: dump: 0x2_0 type: str '0x42': YAML: dump: '0x42' type: str YAML::Syck: dump: '66' type: int YAML::XS: dump: '0x42' type: str '0xa': YAML: dump: '0xa' type: str YAML::Syck: dump: '10' type: int YAML::XS: dump: '0xa' type: str 100_000: YAML: dump: 100_000 type: str YAML::Syck: dump: 100_000 type: str YAML::XS: dump: 100_000 type: str 190:20:30: YAML: dump: 190:20:30 type: str YAML::Syck: dump: '685230' type: int YAML::XS: dump: 190:20:30 type: str 190:20:30.15: YAML: dump: 190:20:30.15 type: str YAML::Syck: dump: '''685230.15''' type: float YAML::XS: dump: 190:20:30.15 type: str '23': YAML: dump: '23' type: int YAML::Syck: dump: '23' type: int YAML::XS: dump: '23' type: int '3.14': YAML: dump: '3.14' type: float YAML::Syck: dump: '''3.14''' type: float YAML::XS: dump: '3.14' type: float '3.3e+3': YAML: dump: '3300' type: int YAML::Syck: dump: '''3300''' type: float YAML::XS: dump: '3.3e+3' type: float '3e3': YAML: dump: '3000' type: int YAML::Syck: dump: '''3e3''' type: str YAML::XS: dump: '3e3' type: float 85.230_15e+03: YAML: dump: 85.230_15e+03 type: str YAML::Syck: dump: 85.230_15e+03 type: str YAML::XS: dump: 85.230_15e+03 type: str 85_230.15: YAML: dump: 85_230.15 type: str YAML::Syck: dump: 85_230.15 type: str YAML::XS: dump: 85_230.15 type: str 'FALSE': YAML: dump: 'FALSE' type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: 'FALSE' type: str 'False': YAML: dump: 'False' type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: 'False' type: str N: YAML: dump: N type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: N type: str NO: YAML: dump: NO type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: NO type: str 'NULL': YAML: dump: 'NULL' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: 'NULL' type: str 'Null': YAML: dump: 'Null' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: 'Null' type: str OFF: YAML: dump: OFF type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: OFF type: str ON: YAML: dump: ON type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: ON type: str Off: YAML: dump: Off type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: Off type: str On: YAML: dump: On type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: On type: str 'TRUE': YAML: dump: 'TRUE' type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: 'TRUE' type: str 'True': YAML: dump: 'True' type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: 'True' type: str Y: YAML: dump: Y type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: Y type: str YES: YAML: dump: YES type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: YES type: str Yes: YAML: dump: Yes type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: Yes type: str ^string: YAML: dump: '''^string''' type: str YAML::Syck: dump: '"^string"' type: str YAML::XS: dump: ^string type: str 'false': YAML: dump: 'false' type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: 'false' type: bool foo\bar: YAML: dump: foo\bar type: str YAML::Syck: dump: foo\bar type: str YAML::XS: dump: foo\bar type: str n: YAML: dump: n type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: n type: str no: YAML: dump: no type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: no type: str 'null': YAML: dump: 'null' type: str YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' off: YAML: dump: off type: str YAML::Syck: dump: '''''' type: float YAML::XS: dump: off type: str on: YAML: dump: on type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: on type: str str"ing: YAML: dump: str"ing type: str YAML::Syck: dump: str"ing type: str YAML::XS: dump: str"ing type: str 'true': YAML: dump: 'true' type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: 'true' type: bool y: YAML: dump: y type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: y type: str yes: YAML: dump: yes type: str YAML::Syck: dump: '1' type: float YAML::XS: dump: yes type: str '~': YAML: dump: '~' type: 'null' YAML::Syck: dump: '~' type: 'null' YAML::XS: dump: '~' type: 'null' 07070100000022000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002900000000perl-YAML-PP-3.14.1712772794.39ac610/ext07070100000023000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema07070100000024000081A40000000000000000000000016616D6BA00000009000000000000000000000000000000000000004500000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/.gitignoregh-pages 07070100000025000081A40000000000000000000000016616D6BA000001A4000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/.gitrepo; DO NOT EDIT (unless you know what you are doing) ; ; This subdirectory is a git "subrepo", and this file is maintained by the ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme ; [subrepo] remote = git@github.com:perlpunk/yaml-test-schema branch = master commit = 63558dd730d378362a09a0358bf7ff4a9d29045c parent = d936660251d051fbc58d6b89be29fc791734485c method = merge cmdver = 0.4.1 07070100000026000081A40000000000000000000000016616D6BA00000059000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/Makefilegh-pages: git worktree add gh-pages gh-pages update: perl etc/generate-schema-html.pl 07070100000027000081A40000000000000000000000016616D6BA0000007E000000000000000000000000000000000000004400000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/README.md## YAML Test Data for Schemas (YAML 1.1, YAML 1.2 Core, JSON, Failsafe) [HTML](https://perlpunk.github.io/yaml-test-schema/) 07070100000028000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003E00000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/etc07070100000029000081A40000000000000000000000016616D6BA00001048000000000000000000000000000000000000005600000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/etc/generate-schema-html.pl#!/usr/bin/env perl use strict; use warnings; use 5.010; use Data::Dumper; use FindBin '$Bin'; use lib "$Bin/../lib"; use YAML::PP; use URI::Escape qw/ uri_escape /; my $file = "$Bin/../yaml-schema.yaml"; my $htmlfile = "$Bin/../gh-pages/data.html"; my $data = YAML::PP::LoadFile($file); my %examples; for my $input (sort keys %$data) { my $schemas = $data->{ $input }; my @keys = keys %$schemas; for my $key (@keys) { my $def = $schemas->{ $key }; my @schemas = split m/ *, */, $key; for my $schema (@schemas) { $examples{ $input }->{ $schema } = $def; } } } my @keys = qw/ failsafe json core yaml11 /; for my $input (sort keys %examples) { my $schemas = $examples{ $input }; my $str = 0; for my $schema (@keys) { my $example = $schemas->{ $schema }; unless ($example) { $example = $schemas->{ $schema } = [ 'todo', '', '', '' ]; } if ($example->[0] eq 'str' or $example->[0] eq 'todo') { $str++; } } } my %type_index = ( null => 0, bool => 1, float => 2, inf => 3, nan => 4, int => 5, str => 6, todo => 7, ); my $table = schema_table(\%examples); my $html = generate_html($table); open my $fh, '>', $htmlfile or die $!; print $fh $html; close $fh; sub sort_rows { my ($x, $y, $a, $b) = @_; $type_index{ $x->{yaml11}->[0] } <=> $type_index{ $y->{yaml11}->[0] } || $type_index{ $x->{core}->[0] } <=> $type_index{ $y->{core}->[0] } || $type_index{ $x->{json}->[0] } <=> $type_index{ $y->{json}->[0] } || lc $a cmp lc $b || $a cmp $b } sub schema_table { my ($examples) = @_; my $html = '<table class="schema">'; my @sorted = sort { sort_rows($examples->{ $a }, $examples->{ $b }, $a, $b) } grep { not m/^!!\w/ } keys %$examples; my @sorted_explicit = sort { sort_rows($examples->{ $a }, $examples->{ $b }, $a, $b) } grep { m/^!!\w/ } keys %$examples; my @all = (@sorted, @sorted_explicit); $html .= qq{<tr><th></th><th colspan="6">YAML 1.2</th><th colspan="2">YAML 1.1</th></tr>\n}; my $header; $header .= qq{<tr><th>Input YAML</th>}; $header .= join '', map { my $m = $_ eq 'YAML' ? 'YAML.pm' : $_; qq{<th colspan="2" class="border-left">$m</th>\n}; } (qw/ Failsafe JSON Core /, 'YAML 1.1'); $header .= qq{</tr>\n}; $html .= $header; $html .= qq{<tr><td></td>} . (qq{<td class="border-left">Type</td><td>Output</td>} x 4) . qq{</tr>\n}; for my $i (0 .. $#all) { my $input = $all[ $i ]; if ($i and $i % 30 == 0) { $html .= $header; } my $schemas = $examples->{ $input }; my $input_escaped = uri_escape($input); $input =~ s/ / /g; $html .= qq{<tr id="input-$input_escaped"><td class="input code"><a href="#input-$input_escaped">$input</a></th>}; for my $schema (@keys) { my $example = $schemas->{ $schema }; my $class = 'type-str'; my ($type, $perl, $out) = @$example; $class = "type-$type"; for ($out) { s/ / /g; } if (0 and $type eq 'str') { $html .= qq{<td class="code $class border-left" colspan="2">$type</td>}; } else { $html .= qq{<td class="code $class border-left">$type</td><td class="code $class"><pre>$out</pre></td>}; } } $html .= qq{</tr>\n}; } $html .= "</table>"; return $html; } sub generate_html { my ($content) = @_; my $html = <<'EOM'; <html> <head> <title>YAML Schema Data</title> <link rel="stylesheet" type="text/css" href="css/yaml.css"> </head> <body> <a href="index.html">YAML Test Schema</a> | <a href="schemas.html">Schemas</a> | <a href="data.html">Test Data</a> <hr> <p> For each of the four schemas, the first column shows to which type the input YAML should resolve. The second column shows how the output YAML should look like. </p> EOM $html .= $content; $html .= <<'EOM'; </body></html> EOM return $html; } 0707010000002A000081A40000000000000000000000016616D6BA00005907000000000000000000000000000000000000004B00000000perl-YAML-PP-3.14.1712772794.39ac610/ext/yaml-test-schema/yaml-schema.yaml--- # Documentation: # # 'input YAML': # schema1, schema2: ['type', 'loaded value', 'dumped YAML'] # # If you use this, you need to split the keys by ', ' to be able # to iterate over the schemas. # # In case the 'loaded value' is a function (e.g. 'true()'), it stands for the # native type # true(): boolean true # false(): boolean false # null(): undefined, Null, None, ... # inf(): infinity # inf-neg(): negative infinity # nan(): Not A Number # # The 'dumped YAML' is how the value should be dumped, without the starting --- ############################################### # True ############################################### 'true': json, core, yaml11: ['bool', 'true()', 'true'] failsafe: ['str', 'true', 'true'] 'True': core, yaml11: ['bool', 'true()', 'true'] failsafe, json: ['str', 'True', 'True'] 'TRUE': core, yaml11: ['bool', 'true()', 'true'] failsafe, json: ['str', 'TRUE', 'TRUE'] 'y': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'y', "y"] 'Y': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'Y', "Y"] 'yes': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'yes', "yes"] 'Yes': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'Yes', "Yes"] 'YES': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'YES', "YES"] 'on': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'on', "on"] 'On': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'On', "On"] 'ON': yaml11: ['bool', 'true()', "true"] failsafe, json, core: ['str', 'ON', "ON"] '!!bool true': json, core, yaml11: ['bool', 'true()', 'true'] '!!bool True': core, yaml11: ['bool', 'true()', 'true'] '!!bool TRUE': core, yaml11: ['bool', 'true()', 'true'] '!!bool y': yaml11: ['bool', 'true()', "true"] '!!bool Y': yaml11: ['bool', 'true()', "true"] '!!bool yes': yaml11: ['bool', 'true()', "true"] '!!bool Yes': yaml11: ['bool', 'true()', "true"] '!!bool YES': yaml11: ['bool', 'true()', "true"] '!!bool on': yaml11: ['bool', 'true()', "true"] '!!bool On': yaml11: ['bool', 'true()', "true"] '!!bool ON': yaml11: ['bool', 'true()', "true"] '!!str true': failsafe: ['str', 'true', 'true'] json, core, yaml11: ['str', 'true', "'true'"] '!!str True': failsafe, json: ['str', 'True', 'True'] core, yaml11: ['str', 'True', "'True'"] '!!str TRUE': failsafe, json: ['str', 'TRUE', 'TRUE'] core, yaml11: ['str', 'TRUE', "'TRUE'"] '!!str yes': failsafe, json, core: ['str', 'yes', "yes" ] yaml11: ['str', 'yes', "'yes'" ] '!!str Yes': failsafe, json, core: ['str', 'Yes', "Yes" ] yaml11: ['str', 'Yes', "'Yes'" ] '!!str YES': failsafe, json, core: ['str', 'YES', "YES" ] yaml11: ['str', 'YES', "'YES'" ] '!!str y': failsafe, json, core: ['str', 'y', "y" ] yaml11: ['str', 'y', "'y'" ] '!!str Y': failsafe, json, core: ['str', 'Y', "Y" ] yaml11: ['str', 'Y', "'Y'" ] '!!str on': failsafe, json, core: ['str', 'on', "on" ] yaml11: ['str', 'on', "'on'" ] '!!str On': failsafe, json, core: ['str', 'On', "On" ] yaml11: ['str', 'On', "'On'" ] '!!str ON': failsafe, json, core: ['str', 'ON', "ON" ] yaml11: ['str', 'ON', "'ON'" ] ############################################### # False ############################################### 'false': failsafe: ['str', 'false', 'false'] json, core, yaml11: ['bool', 'false()', 'false'] 'False': failsafe, json: ['str', 'False', 'False'] core, yaml11: ['bool', 'false()', 'false'] 'FALSE': failsafe, json: ['str', 'FALSE', 'FALSE'] core, yaml11: ['bool', 'false()', 'false'] 'n': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'n', "n"] 'N': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'N', "N"] 'no': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'no', "no"] 'NO': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'NO', "NO"] 'off': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'off', "off"] 'Off': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'Off', "Off"] 'OFF': yaml11: ['bool', 'false()', "false"] failsafe, json, core: ['str', 'OFF', "OFF"] '!!bool false': json, core, yaml11: ['bool', 'false()', 'false'] '!!bool False': core, yaml11: ['bool', 'false()', 'false'] '!!bool FALSE': core, yaml11: ['bool', 'false()', 'false'] '!!bool n': yaml11: ['bool', 'false()', "false"] '!!bool N': yaml11: ['bool', 'false()', "false"] '!!bool no': yaml11: ['bool', 'false()', "false"] '!!bool No': yaml11: ['bool', 'false()', "false"] '!!bool NO': yaml11: ['bool', 'false()', "false"] '!!bool off': yaml11: ['bool', 'false()', "false"] '!!bool Off': yaml11: ['bool', 'false()', "false"] '!!bool OFF': yaml11: ['bool', 'false()', "false"] '!!str false': json, core, yaml11: ['str', 'false', "'false'"] failsafe: ['str', 'false', 'false'] '!!str False': failsafe, json: ['str', 'False', "False"] core, yaml11: ['str', 'False', "'False'"] '!!str FALSE': failsafe, json: ['str', 'FALSE', "FALSE"] core, yaml11: ['str', 'FALSE', "'FALSE'"] '!!str n': failsafe, json, core: ['str', 'n', "n" ] yaml11: ['str', 'n', "'n'" ] '!!str N': failsafe, json, core: ['str', 'N', "N" ] yaml11: ['str', 'N', "'N'" ] '!!str no': failsafe, json, core: ['str', 'no', "no" ] yaml11: ['str', 'no', "'no'" ] '!!str NO': failsafe, json, core: ['str', 'NO', "NO" ] yaml11: ['str', 'NO', "'NO'" ] '!!str off': failsafe, json, core: ['str', 'off', "off" ] yaml11: ['str', 'off', "'off'" ] '!!str Off': failsafe, json, core: ['str', 'Off', "Off" ] yaml11: ['str', 'Off', "'Off'" ] '!!str OFF': failsafe, json, core: ['str', 'OFF', "OFF" ] yaml11: ['str', 'OFF', "'OFF'" ] ############################################### # Null ############################################### 'null': failsafe: ['str', 'null', 'null'] json, core, yaml11: ['null', 'null()', "null"] 'Null': failsafe, json: ['str', 'Null', 'Null'] core, yaml11: ['null', 'null()', "null"] 'NULL': failsafe, json: ['str', 'NULL', 'NULL'] core, yaml11: ['null', 'null()', "null"] '~': failsafe, json: ['str', '~', '~'] core, yaml11: ['null', 'null()', "null"] '!!null null': json, core, yaml11: ['null', 'null()', 'null'] '!!null Null': core, yaml11: ['null', 'null()', "null"] '!!null NULL': core, yaml11: ['null', 'null()', "null"] '!!null ~': core, yaml11: ['null', 'null()', 'null'] '!!str null': failsafe: ['str', 'null', 'null'] json, core, yaml11: ['str', 'null', "'null'"] '!!str Null': failsafe, json: ['str', 'Null', "Null"] core, yaml11: ['str', 'Null', "'Null'"] '!!str NULL': failsafe, json: ['str', 'NULL', "NULL"] core, yaml11: ['str', 'NULL', "'NULL'"] '!!str ~': core, yaml11: ['str', '~', "'~'"] failsafe, json: ['str', '~', '~'] '#empty': core, yaml11: ['null', 'null()', "null"] failsafe, json: ['str', '', "''"] '!!null #empty': core, yaml11: ['null', 'null()', "null"] '!!str #empty': failsafe, json, core, yaml11: ['str', '', "''"] ############################################### # Inf ############################################### '.inf': failsafe, json: ['str', '.inf', '.inf'] core, yaml11: ['inf', 'inf()', '.inf'] '.Inf': failsafe, json: ['str', '.Inf', '.Inf'] core, yaml11: ['inf', 'inf()', '.inf'] '.INF': failsafe, json: ['str', '.INF', '.INF'] core, yaml11: ['inf', 'inf()', '.inf'] '!!float .inf': core, yaml11: ['inf', 'inf()', '.inf'] '!!float .Inf': core, yaml11: ['inf', 'inf()', '.inf'] '!!float .INF': core, yaml11: ['inf', 'inf()', '.inf'] '!!str .inf': failsafe, json: ['str', '.inf', ".inf"] core, yaml11: ['str', '.inf', "'.inf'"] '!!str .Inf': failsafe, json: ['str', '.Inf', ".Inf"] core, yaml11: ['str', '.Inf', "'.Inf'"] '!!str .INF': failsafe, json: ['str', '.INF', ".INF"] core, yaml11: ['str', '.INF', "'.INF'"] '+.inf': core, yaml11: ['inf', 'inf()', '.inf'] failsafe, json: ['str', '+.inf', '+.inf'] '+.Inf': core, yaml11: ['inf', 'inf()', '.inf'] failsafe, json: ['str', '+.Inf', '+.Inf'] '+.INF': core, yaml11: ['inf', 'inf()', '.inf'] failsafe, json: ['str', '+.INF', '+.INF'] '!!float +.inf': core, yaml11: ['inf', 'inf()', '.inf'] '!!float +.Inf': core, yaml11: ['inf', 'inf()', '.inf'] '!!float +.INF': core, yaml11: ['inf', 'inf()', '.inf'] '!!str +.inf': failsafe, json: ['str', '+.inf', "+.inf"] core, yaml11: ['str', '+.inf', "'+.inf'"] '!!str +.Inf': failsafe, json: ['str', '+.Inf', "+.Inf"] core, yaml11: ['str', '+.Inf', "'+.Inf'"] '!!str +.INF': failsafe, json: ['str', '+.INF', "+.INF"] core, yaml11: ['str', '+.INF', "'+.INF'"] '-.inf': failsafe, json: ['str', '-.inf', '-.inf'] core, yaml11: ['inf', 'inf-neg()', '-.inf'] '-.Inf': failsafe, json: ['str', '-.Inf', '-.Inf'] core, yaml11: ['inf', 'inf-neg()', '-.inf'] '-.INF': failsafe, json: ['str', '-.INF', '-.INF'] core, yaml11: ['inf', 'inf-neg()', '-.inf'] '!!float -.inf': core, yaml11: ['inf', 'inf-neg()', '-.inf'] '!!float -.Inf': core, yaml11: ['inf', 'inf-neg()', '-.inf'] '!!float -.INF': core, yaml11: ['inf', 'inf-neg()', '-.inf'] '!!str -.inf': failsafe, json: ['str', '-.inf', "-.inf"] core, yaml11: ['str', '-.inf', "'-.inf'"] '!!str -.Inf': failsafe, json: ['str', '-.Inf', "-.Inf"] core, yaml11: ['str', '-.Inf', "'-.Inf'"] '!!str -.INF': failsafe, json: ['str', '-.INF', "-.INF"] core, yaml11: ['str', '-.INF', "'-.INF'"] ############################################### # NaN ############################################### '.nan': failsafe, json: ['str', '.nan', '.nan'] core, yaml11: ['nan', 'nan()', '.nan'] '.NaN': core, yaml11: ['nan', 'nan()', '.nan'] failsafe, json: ['str', '.NaN', '.NaN'] '.NAN': failsafe, json: ['str', '.NAN', '.NAN'] core, yaml11: ['nan', 'nan()', '.nan'] '!!float .nan': core, yaml11: ['nan', 'nan()', '.nan'] '!!float .NaN': core, yaml11: ['nan', 'nan()', '.nan'] '!!float .NAN': core, yaml11: ['nan', 'nan()', '.nan'] '!!str .nan': failsafe, json: ['str', '.nan', ".nan"] core, yaml11: ['str', '.nan', "'.nan'"] '!!str .NaN': failsafe, json: ['str', '.NaN', ".NaN"] core, yaml11: ['str', '.NaN', "'.NaN'"] '!!str .NAN': failsafe, json: ['str', '.NAN', ".NAN"] core, yaml11: ['str', '.NAN', "'.NAN'"] ############################################### # Int ############################################### '0': failsafe: ['str', '0', '0'] json, core, yaml11: ['int', '0', '0'] '00': failsafe, json: ['str', '00', '00'] core: ['int', '0', '0'] yaml11: ['int', '0', '0'] '0011': core: ['int', '11', '11'] failsafe, json: ['str', '0011', '0011'] yaml11: ['int', '9', '9'] '010': failsafe, json: ['str', '010', '010'] core: ['int', '10', '10'] yaml11: ['int', '8', '8'] '07': failsafe, json: ['str', '07', '07'] yaml11: ['int', '7', '7'] core: ['int', '7', '7'] '08': failsafe, json: ['str', '08', '08'] yaml11: ['str', '08', '08'] core: ['int', '8', '8'] '02_0': failsafe, json, core: ['str', '02_0', '02_0'] yaml11: ['int', '16', '16'] '23': failsafe: ['str', '23', '23'] json, core, yaml11: ['int', '23', '23'] '100_000': yaml11: ['int', '100000', '100000'] failsafe, json, core: ['str', '100_000', '100_000'] '!!int 0': json, core, yaml11: ['int', '0', '0'] '!!int 00': yaml11: ['int', '0', '0'] '!!int 0011': yaml11: ['int', '9', '9'] core: ['int', '11', '11'] '!!int 010': yaml11: ['int', '8', '8'] '!!int 07': core: ['int', '7', '7'] yaml11: ['int', '7', '7'] '!!int 02_0': yaml11: ['int', '16', '16'] '!!int 23': json, core, yaml11: ['int', '23', '23'] '!!int 100_000': yaml11: ['int', '100000', '100000'] '-0': json, core, yaml11: ['int', '0', '0'] failsafe: ['str', '-0', '-0'] '-23': json, core, yaml11: ['int', '-23', '-23'] failsafe: ['str', '-23', '-23'] '-0100_200': failsafe, json, core: ['str', '-0100_200', '-0100_200'] yaml11: ['int', '-32896', '-32896'] '!!int -0': json, core, yaml11: ['int', '0', '0'] '!!int -23': json, core, yaml11: ['int', '-23', '-23'] '!!int -0100_200': yaml11: ['int', '-32896', '-32896'] '+0': core, yaml11: ['int', '0', '0'] failsafe, json: ['str', '+0', '+0'] '+23': core, yaml11: ['int', '23', '23'] failsafe, json: ['str', '+23', '+23'] '+0100_200': yaml11: ['int', '32896', '32896'] failsafe, json, core: ['str', '+0100_200', '+0100_200'] '!!int +0': core, yaml11: ['int', '0', '0'] '!!int +23': core, yaml11: ['int', '23', '23'] '!!int +0100_200': yaml11: ['int', '32896', '32896'] '!!str 0': failsafe: ['str', '0', "0"] json, core, yaml11: ['str', '0', "'0'"] '!!str 00': failsafe, json: ['str', '00', "00"] core, yaml11: ['str', '00', "'00'"] '!!str 010': failsafe, json: ['str', '010', "010"] core, yaml11: ['str', '010', "'010'"] '!!str 0011': failsafe, json: ['str', '0011', "0011"] core, yaml11: ['str', '0011', "'0011'"] '!!str 07': failsafe, json: ['str', '07', "07"] core, yaml11: ['str', '07', "'07'"] '!!str 23': failsafe: ['str', '23', '23'] json, core, yaml11: ['str', '23', "'23'"] '!!str 100_000': failsafe, json, core: ['str', '100_000', "100_000"] yaml11: ['str', '100_000', "'100_000'"] '!!str 02_0': failsafe, json, core: ['str', '02_0', "02_0"] yaml11: ['str', '02_0', "'02_0'"] '!!str -0': failsafe: ['str', '-0', "-0"] json, core, yaml11: ['str', '-0', "'-0'"] '!!str -23': failsafe: ['str', '-23', "-23"] json, core, yaml11: ['str', '-23', "'-23'"] '!!str +0': failsafe, json: ['str', '+0', "+0"] core, yaml11: ['str', '+0', "'+0'"] '!!str +23': failsafe, json: ['str', '+23', "+23"] core, yaml11: ['str', '+23', "'+23'"] '!!str +0100_200': failsafe, json, core: ['str', '+0100_200', "+0100_200"] yaml11: ['str', '+0100_200', "'+0100_200'"] '!!str -0100_200': failsafe, json, core: ['str', '-0100_200', "-0100_200"] yaml11: ['str', '-0100_200', "'-0100_200'"] ############################################### # Oct ############################################### '0o0': core: ['int', '0', '0'] failsafe, json, yaml11: ['str', '0o0', '0o0'] '0o7': core: ['int', '7', '7'] failsafe, json, yaml11: ['str', '0o7', '0o7'] '0o10': core: ['int', '8', '8'] failsafe, json, yaml11: ['str', '0o10', '0o10'] '!!int 0o0': core: ['int', '0', '0'] '!!int 0o7': core: ['int', '7', '7'] '!!int 0o10': core: ['int', '8', '8'] '!!str 0o0': failsafe, json, yaml11: ['str', '0o0', "0o0"] core: ['str', '0o0', "'0o0'"] '!!str 0o7': failsafe, json, yaml11: ['str', '0o7', "0o7"] core: ['str', '0o7', "'0o7'"] '!!str 0o10': failsafe, json, yaml11: ['str', '0o10', "0o10"] core: ['str', '0o10', "'0o10'"] ############################################### # Hex ############################################### '0x0': failsafe, json: ['str', '0x0', '0x0'] core, yaml11: ['int', '0', '0'] '0x10': failsafe, json: ['str', '0x10', '0x10'] core, yaml11: ['int', '16', '16'] '0x42': failsafe, json: ['str', '0x42', '0x42'] core, yaml11: ['int', '66', '66'] '0xa': failsafe, json: ['str', '0xa', '0xa'] core, yaml11: ['int', '10', '10'] '-0x30': failsafe, json, core: ['str', '-0x30', '-0x30'] yaml11: ['int', '-48', '-48'] '0x2_0': failsafe, json, core: ['str', '0x2_0', '0x2_0'] yaml11: ['int', '32', '32'] '!!int 0x10': core, yaml11: ['int', '16', '16'] '!!int 0x0': core, yaml11: ['int', '0', '0'] '!!int 0x42': core, yaml11: ['int', '66', '66'] '!!int 0xa': core, yaml11: ['int', '10', '10'] '!!int 0x2_0': yaml11: ['int', '32', '32'] '!!int -0x30': yaml11: ['int', '-48', '-48'] '!!str 0x0': failsafe, json: ['str', '0x0', "0x0"] core, yaml11: ['str', '0x0', "'0x0'"] '!!str 0x2_0': failsafe, json, core: ['str', '0x2_0', "0x2_0"] yaml11: ['str', '0x2_0', "'0x2_0'"] '!!str -0x30': failsafe, json, core: ['str', '-0x30', "-0x30"] yaml11: ['str', '-0x30', "'-0x30'"] '!!str 0xa': failsafe, json: ['str', '0xa', "0xa"] core, yaml11: ['str', '0xa', "'0xa'"] ############################################### # Binary ############################################### '0b0': failsafe, json, core: ['str', '0b0', '0b0'] yaml11: ['int', '0', '0'] '+0b100': failsafe, json, core: ['str', '+0b100', '+0b100'] yaml11: ['int', '4', '4'] '-0b101': failsafe, json, core: ['str', '-0b101', '-0b101'] yaml11: ['int', '-5', '-5'] '0b100_101': failsafe, json, core: ['str', '0b100_101', '0b100_101'] yaml11: ['int', '37', '37'] '!!int 0b0': yaml11: ['int', '0', '0'] '!!int 0b100_101': yaml11: ['int', '37', '37'] '!!int +0b100': yaml11: ['int', '4', '4'] '!!int -0b101': yaml11: ['int', '-5', '-5'] '!!str 0b0': failsafe, json, core: ['str', '0b0', "0b0"] yaml11: ['str', '0b0', "'0b0'"] '!!str -0b101': failsafe, json, core: ['str', '-0b101', "-0b101"] yaml11: ['str', '-0b101', "'-0b101'"] '!!str 0b100_101': failsafe, json, core: ['str', '0b100_101', "0b100_101"] yaml11: ['str', '0b100_101', "'0b100_101'"] '!!str +0b100': failsafe, json, core: ['str', '+0b100', "+0b100"] yaml11: ['str', '+0b100', "'+0b100'"] ############################################### # Sexagesimal ############################################### '190:20:30': failsafe, json, core: ['str', '190:20:30', '190:20:30'] yaml11: ['int', '685230', '685230'] '-190:20:30': failsafe, json, core: ['str', '-190:20:30', '-190:20:30'] yaml11: ['int', '-685230', '-685230'] '+190:20:30': failsafe, json, core: ['str', '+190:20:30', '+190:20:30'] yaml11: ['int', '685230', '685230'] '!!int 190:20:30': yaml11: ['int', '685230', '685230'] '!!int -190:20:30': yaml11: ['int', '-685230', '-685230'] '!!int +190:20:30': yaml11: ['int', '685230', '685230'] '!!str 190:20:30': failsafe, json, core: ['str', '190:20:30', "190:20:30"] yaml11: ['str', '190:20:30', "'190:20:30'"] '!!str -190:20:30': failsafe, json, core: ['str', '-190:20:30', "-190:20:30"] yaml11: ['str', '-190:20:30', "'-190:20:30'"] '!!str +190:20:30': failsafe, json, core: ['str', '+190:20:30', "+190:20:30"] yaml11: ['str', '+190:20:30', "'+190:20:30'"] ############################################### # Float ############################################### '.0': failsafe, json: ['str', '.0', '.0'] core, yaml11: ['float', '0.0', '0.0'] '.14': failsafe, json: ['str', '.14', '.14'] core, yaml11: ['float', '0.14', '0.14'] '0.0': failsafe: ['str', '0.0', '0.0'] json, core, yaml11: ['float', '0.0', '0.0'] '3.14': failsafe: ['str', '3.14', '3.14'] json, core, yaml11: ['float', '3.14', '3.14'] '001.23': failsafe, json: ['str', '001.23', '001.23'] core, yaml11: ['float', '1.23', '1.23'] '85_230.15': failsafe, json, core: ['str', '85_230.15', '85_230.15'] yaml11: ['float', '85230.15', '85230.15'] '-3.14': failsafe: ['str', '-3.14', '-3.14'] json, core, yaml11: ['float', '-3.14', '-3.14'] '+3.14': failsafe, json: ['str', '+3.14', '+3.14'] core, yaml11: ['float', '3.14', '3.14'] '!!float .0': core, yaml11: ['float', '0.0', '0.0'] '!!float 0.0': json, core, yaml11: ['float', '0.0', '0.0'] '!!float 3.14': json, core, yaml11: ['float', '3.14', '3.14'] '!!float -3.14': json, core, yaml11: ['float', '-3.14', '-3.14'] '!!float 001.23': core, yaml11: ['float', '1.23', '1.23'] '!!float 85_230.15': yaml11: ['float', '85230.15', '85230.15'] '!!str .0': failsafe, json: ['str', '.0', ".0"] core, yaml11: ['str', '.0', "'.0'"] '!!str 0.0': failsafe: ['str', '0.0', "0.0"] json, core, yaml11: ['str', '0.0', "'0.0'"] '!!str 3.14': failsafe: ['str', '3.14', "3.14"] json, core, yaml11: ['str', '3.14', "'3.14'"] '!!str -3.14': failsafe: ['str', '-3.14', "-3.14"] json, core, yaml11: ['str', '-3.14', "'-3.14'"] '!!str 001.23': failsafe, json: ['str', '001.23', "001.23"] core, yaml11: ['str', '001.23', "'001.23'"] '!!str 85_230.15': failsafe, json, core: ['str', '85_230.15', "85_230.15"] yaml11: ['str', '85_230.15', "'85_230.15'"] ############################################### # Exp ############################################### '.3e3': failsafe, json, yaml11: ['str', '.3e3', '.3e3'] core: ['float', '300.0', '300.0'] '.3e+3': failsafe, json: ['str', '.3e+3', '.3e+3'] core, yaml11: ['float', '300.0', '300.0'] '.3E-1': failsafe, json: ['str', '.3E-1', '.3E-1'] core, yaml11: ['float', '0.03', '0.03'] '0.3e3': json, core: ['float', '300.0', '300.0'] failsafe, yaml11: ['str', '0.3e3', '0.3e3'] '3.3e+3': failsafe: ['str', '3.3e+3', '3.3e+3'] json, core, yaml11: ['float', '3300', '3300.0'] '3e3': json, core: ['float', '3000', '3000.0'] failsafe, yaml11: ['str', '3e3', '3e3'] '85.230_15e+03': failsafe, json, core: ['str', '85.230_15e+03', '85.230_15e+03'] yaml11: ['float', '85230.15', '85230.15'] '+0.3e+3': failsafe, json: ['str', '+0.3e+3', '+0.3e+3'] core, yaml11: ['float', '300.0', '300.0'] '+0.3e3': failsafe, json: ['str', '+0.3e3', '+0.3e3'] core: ['float', '300.0', '300.0'] yaml11: ['str', '+0.3e3', '+0.3e3'] '!!float .3e3': core: ['float', '300.0', '300.0'] '!!float 0.3e3': json, core: ['float', '300.0', '300.0'] '!!float +0.3e3': core: ['float', '300.0', '300.0'] '!!float .3E-1': core, yaml11: ['float', '0.03', '0.03'] '!!float 3.3e+3': core, yaml11: ['float', '3300.0', '3300.0'] '!!float +0.3e+3': core, yaml11: ['float', '300.0', '300.0'] '!!float .3e+3': core, yaml11: ['float', '300.0', '300.0'] '!!float 85.230_15e+03': yaml11: ['float', '85230.15', '85230.15'] '!!str .3e+3': failsafe, json: ['str', '.3e+3', ".3e+3"] core, yaml11: ['str', '.3e+3', "'.3e+3'"] '!!str .3E-1': failsafe, json: ['str', '.3E-1', ".3E-1"] core, yaml11: ['str', '.3E-1', "'.3E-1'"] '!!str .3e3': failsafe, json, yaml11: ['str', '.3e3', ".3e3"] core: ['str', '.3e3', "'.3e3'"] '!!str 0.3e3': failsafe, yaml11: ['str', '0.3e3', "0.3e3"] json, core: ['str', '0.3e3', "'0.3e3'"] '!!str +0.3e3': failsafe, json, yaml11: ['str', '+0.3e3', "+0.3e3"] core: ['str', '+0.3e3', "'+0.3e3'"] '!!str 3.3e+3': failsafe: ['str', '3.3e+3', "3.3e+3"] json, core, yaml11: ['str', '3.3e+3', "'3.3e+3'"] '!!str +0.3e+3': failsafe, json: ['str', '+0.3e+3', "+0.3e+3"] core, yaml11: ['str', '+0.3e+3', "'+0.3e+3'"] '!!str 85.230_15e+03': failsafe, json, core: ['str', '85.230_15e+03', "85.230_15e+03"] yaml11: ['str', '85.230_15e+03', "'85.230_15e+03'"] ############################################### # Sexagesimal ############################################### '190:20:30.15': failsafe, json, core: ['str', '190:20:30.15', '190:20:30.15'] yaml11: ['float', '685230.15', '685230.15'] '!!float 190:20:30.15': yaml11: ['float', '685230.15', '685230.15'] '!!str 190:20:30.15': failsafe, json, core: ['str', '190:20:30.15', "190:20:30.15"] yaml11: ['str', '190:20:30.15', "'190:20:30.15'"] 0707010000002B000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002900000000perl-YAML-PP-3.14.1712772794.39ac610/lib0707010000002C000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002E00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML0707010000002D000041ED0000000000000000000000056616D6BA00000000000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP0707010000002E000081A40000000000000000000000016616D6BA00009222000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP.pm# ABSTRACT: YAML 1.2 Processor use strict; use warnings; package YAML::PP; our $VERSION = '0.000'; # VERSION use YAML::PP::Schema; use YAML::PP::Schema::JSON; use YAML::PP::Loader; use YAML::PP::Dumper; use Scalar::Util qw/ blessed /; use Carp qw/ croak /; use base 'Exporter'; our @EXPORT_OK = qw/ Load LoadFile Dump DumpFile /; my %YAML_VERSIONS = ('1.1' => 1, '1.2' => 1); sub new { my ($class, %args) = @_; my $bool = delete $args{boolean}; $bool = 'perl' unless defined $bool; my $schemas = delete $args{schema} || ['+']; my $cyclic_refs = delete $args{cyclic_refs} || 'fatal'; my $indent = delete $args{indent}; my $width = delete $args{width}; my $writer = delete $args{writer}; my $header = delete $args{header}; my $footer = delete $args{footer}; my $duplicate_keys = delete $args{duplicate_keys}; my $yaml_version = $class->_arg_yaml_version(delete $args{yaml_version}); my $default_yaml_version = $yaml_version->[0]; my $version_directive = delete $args{version_directive}; my $preserve = delete $args{preserve}; my $parser = delete $args{parser}; my $emitter = delete $args{emitter} || { indent => $indent, width => $width, writer => $writer, }; if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } my %schemas; for my $v (@$yaml_version) { my $schema; if (blessed($schemas) and $schemas->isa('YAML::PP::Schema')) { $schema = $schemas; } else { $schema = YAML::PP::Schema->new( boolean => $bool, yaml_version => $v, ); $schema->load_subschemas(@$schemas); } $schemas{ $v } = $schema; } my $default_schema = $schemas{ $default_yaml_version }; my $loader = YAML::PP::Loader->new( schemas => \%schemas, cyclic_refs => $cyclic_refs, parser => $parser, default_yaml_version => $default_yaml_version, preserve => $preserve, duplicate_keys => $duplicate_keys, ); my $dumper = YAML::PP::Dumper->new( schema => $default_schema, emitter => $emitter, header => $header, footer => $footer, version_directive => $version_directive, preserve => $preserve, ); my $self = bless { schema => \%schemas, loader => $loader, dumper => $dumper, }, $class; return $self; } sub clone { my ($self) = @_; my $clone = { schema => $self->schema, loader => $self->loader->clone, dumper => $self->dumper->clone, }; return bless $clone, ref $self; } sub _arg_yaml_version { my ($class, $version) = @_; my @versions = ('1.2'); if (defined $version) { @versions = (); if (not ref $version) { $version = [$version]; } for my $v (@$version) { unless ($YAML_VERSIONS{ $v }) { croak "YAML Version '$v' not supported"; } push @versions, $v; } } return \@versions; } sub loader { if (@_ > 1) { $_[0]->{loader} = $_[1] } return $_[0]->{loader}; } sub dumper { if (@_ > 1) { $_[0]->{dumper} = $_[1] } return $_[0]->{dumper}; } sub schema { if (@_ > 1) { $_[0]->{schema}->{'1.2'} = $_[1] } return $_[0]->{schema}->{'1.2'}; } sub default_schema { my ($self, %args) = @_; my $schema = YAML::PP::Schema->new( boolean => $args{boolean}, ); $schema->load_subschemas(qw/ Core /); return $schema; } sub load_string { my ($self, $yaml) = @_; return $self->loader->load_string($yaml); } sub load_file { my ($self, $file) = @_; return $self->loader->load_file($file); } sub dump { my ($self, @data) = @_; return $self->dumper->dump(@data); } sub dump_string { my ($self, @data) = @_; return $self->dumper->dump_string(@data); } sub dump_file { my ($self, $file, @data) = @_; return $self->dumper->dump_file($file, @data); } # legagy interface sub Load { my ($yaml) = @_; YAML::PP->new->load_string($yaml); } sub LoadFile { my ($file) = @_; YAML::PP->new->load_file($file); } sub Dump { my (@data) = @_; YAML::PP->new->dump_string(@data); } sub DumpFile { my ($file, @data) = @_; YAML::PP->new->dump_file($file, @data); } sub preserved_scalar { my ($self, $value, %args) = @_; my $scalar = YAML::PP::Preserve::Scalar->new( value => $value, %args, ); return $scalar; } sub preserved_mapping { my ($self, $hash, %args) = @_; my $data = {}; tie %$data, 'YAML::PP::Preserve::Hash'; %$data = %$hash; my $t = tied %$data; $t->{style} = $args{style}; $t->{alias} = $args{alias}; return $data; } sub preserved_sequence { my ($self, $array, %args) = @_; my $data = []; tie @$data, 'YAML::PP::Preserve::Array'; push @$data, @$array; my $t = tied @$data; $t->{style} = $args{style}; $t->{alias} = $args{alias}; return $data; } package YAML::PP::Preserve::Hash; # experimental use Tie::Hash; use base qw/ Tie::StdHash /; use Scalar::Util qw/ reftype blessed /; sub TIEHASH { my ($class, %args) = @_; my $self = bless { keys => [keys %args], data => { %args }, }, $class; } sub STORE { my ($self, $key, $val) = @_; my $keys = $self->{keys}; unless (exists $self->{data}->{ $key }) { push @$keys, $key; } if (ref $val and not blessed($val)) { if (reftype($val) eq 'HASH' and not tied %$val) { tie %$val, 'YAML::PP::Preserve::Hash', %$val; } elsif (reftype($val) eq 'ARRAY' and not tied @$val) { tie @$val, 'YAML::PP::Preserve::Array', @$val; } } $self->{data}->{ $key } = $val; } sub FIRSTKEY { my ($self) = @_; return $self->{keys}->[0]; } sub NEXTKEY { my ($self, $last) = @_; my $keys = $self->{keys}; for my $i (0 .. $#$keys) { if ("$keys->[ $i ]" eq "$last") { return $keys->[ $i + 1 ]; } } return; } sub FETCH { my ($self, $key) = @_; my $val = $self->{data}->{ $key }; } sub DELETE { my ($self, $key) = @_; @{ $self->{keys} } = grep { "$_" ne "$key" } @{ $self->{keys} }; delete $self->{data}->{ $key }; } sub EXISTS { my ($self, $key) = @_; return exists $self->{data}->{ $key }; } sub CLEAR { my ($self) = @_; $self->{keys} = []; $self->{data} = {}; } sub SCALAR { my ($self) = @_; return scalar %{ $self->{data} }; } package YAML::PP::Preserve::Array; # experimental use Tie::Array; use base qw/ Tie::StdArray /; use Scalar::Util qw/ reftype blessed /; sub TIEARRAY { my ($class, @items) = @_; my $self = bless { data => [@items], }, $class; return $self; } sub FETCH { my ($self, $i) = @_; return $self->{data}->[ $i ]; } sub FETCHSIZE { my ($self) = @_; return $#{ $self->{data} } + 1; } sub _preserve { my ($val) = @_; if (ref $val and not blessed($val)) { if (reftype($val) eq 'HASH' and not tied %$val) { tie %$val, 'YAML::PP::Preserve::Hash', %$val; } elsif (reftype($val) eq 'ARRAY' and not tied @$val) { tie @$val, 'YAML::PP::Preserve::Array', @$val; } } return $val; } sub STORE { my ($self, $i, $val) = @_; _preserve($val); $self->{data}->[ $i ] = $val; } sub PUSH { my ($self, @args) = @_; push @{ $self->{data} }, map { _preserve $_ } @args; } sub STORESIZE { my ($self, $i) = @_; $#{ $self->{data} } = $i - 1; } sub DELETE { my ($self, $i) = @_; delete $self->{data}->[ $i ]; } sub EXISTS { my ($self, $i) = @_; return exists $self->{data}->[ $i ]; } sub CLEAR { my ($self) = @_; $self->{data} = []; } sub SHIFT { my ($self) = @_; shift @{ $self->{data} }; } sub UNSHIFT { my ($self, @args) = @_; unshift @{ $self->{data} }, map { _preserve $_ } @args; } sub SPLICE { my ($self, $offset, $length, @args) = @_; splice @{ $self->{data} }, $offset, $length, map { _preserve $_ } @args; } sub EXTEND {} package YAML::PP::Preserve::Scalar; use overload fallback => 1, '+' => \&value, '""' => \&value, 'bool' => \&value, ; sub new { my ($class, %args) = @_; my $self = { %args, }; bless $self, $class; } sub value { $_[0]->{value} } sub tag { $_[0]->{tag} } sub style { $_[0]->{style} || 0 } sub alias { $_[0]->{alias} } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP - YAML 1.2 processor =head1 SYNOPSIS WARNING: Most of the inner API is not stable yet. Here are a few examples of the basic load and dump methods: use YAML::PP; my $ypp = YAML::PP->new; my $yaml = <<'EOM'; --- # Document one is a mapping name: Tina age: 29 favourite language: Perl --- # Document two is a sequence - plain string - 'in single quotes' - "in double quotes we have escapes! like \t and \n" - | # a literal block scalar line1 line2 - > # a folded block scalar this is all one single line because the linebreaks will be folded EOM my @documents = $ypp->load_string($yaml); my @documents = $ypp->load_file($filename); my $yaml = $ypp->dump_string($data1, $data2); $ypp->dump_file($filename, $data1, $data2); # Enable perl data types and objects my $ypp = YAML::PP->new(schema => [qw/ + Perl /]); my $yaml = $yp->dump_string($data_with_perl_objects); # Legacy interface use YAML::PP qw/ Load Dump LoadFile DumpFile /; my @documents = Load($yaml); my @documents = LoadFile($filename); my @documents = LoadFile($filehandle); my $yaml = = Dump(@documents); DumpFile($filename, @documents); DumpFile($filenhandle @documents); Some utility scripts, mostly useful for debugging: # Load YAML into a data structure and dump with Data::Dumper yamlpp-load < file.yaml # Load and Dump yamlpp-load-dump < file.yaml # Print the events from the parser in yaml-test-suite format yamlpp-events < file.yaml # Parse and emit events directly without loading yamlpp-parse-emit < file.yaml # Create ANSI colored YAML. Can also be useful for invalid YAML, showing # you the exact location of the error yamlpp-highlight < file.yaml =head1 DESCRIPTION YAML::PP is a modular YAML processor. It aims to support C<YAML 1.2> and C<YAML 1.1>. See L<https://yaml.org/>. Some (rare) syntax elements are not yet supported and documented below. YAML is a serialization language. The YAML input is called "YAML Stream". A stream consists of one or more "Documents", separated by a line with a document start marker C<--->. A document optionally ends with the document end marker C<...>. This allows one to process continuous streams additionally to a fixed input file or string. The YAML::PP frontend will currently load all documents, and return only the first if called with scalar context. The YAML backend is implemented in a modular way that allows one to add custom handling of YAML tags, perl objects and data types. The inner API is not yet stable. Suggestions welcome. You can check out all current parse and load results from the yaml-test-suite here: L<https://perlpunk.github.io/YAML-PP-p5/test-suite.html> =head1 METHODS =head2 new my $ypp = YAML::PP->new; # use YAML 1.2 Failsafe Schema my $ypp = YAML::PP->new( schema => ['Failsafe'] ); # use YAML 1.2 JSON Schema my $ypp = YAML::PP->new( schema => ['JSON'] ); # use YAML 1.2 Core Schema my $ypp = YAML::PP->new( schema => ['Core'] ); # Die when detecting cyclic references my $ypp = YAML::PP->new( cyclic_refs => 'fatal' ); my $ypp = YAML::PP->new( boolean => 'perl', schema => ['Core'], cyclic_refs => 'fatal', indent => 4, header => 1, footer => 0, version_directive => 0, ); Options: =over =item boolean Values: C<perl> (currently default), C<JSON::PP>, C<boolean>, C<perl_experimental> This option is for loading and dumping. In case of perl 5.36 and later, builtin booleans should work out of the box (since YAML::PP >= 0.38.0). print YAML::PP->new->dump_string([ builtin::true, !1 ]); # --- # - true # - false For earlier perl versions, you can use "pseudo" booleans like documented in the following examples. Examples: # load/dump booleans via boolean.pm my $ypp = YAML::PP->new( boolean => 'boolean' ); # load/dump booleans via JSON::PP::true/false my $ypp = YAML::PP->new( boolean => 'JSON::PP' ); You can also specify more than one class, comma separated. This is important for dumping. boolean => 'JSON::PP,boolean' Booleans will be loaded as JSON::PP::Booleans, but when dumping, also 'boolean' objects will be recognized boolean => 'JSON::PP,*' Booleans will be loaded as JSON::PP::Booleans, but when dumping, all currently supported boolean classes will be recognized boolean => '*' Booleans will be loaded as perl booleans, but when dumping, all currently supported boolean classes will be recognized boolean => '' Booleans will be loaded as perl booleans, but when dumping, nothing will be recognized as booleans. This option is for backwards compatibility for perl versions < 5.36, if you rely on [!!1, !1] being dumped as [1, '']. The option c<perl_experimental> was introduced when experimental boolean support was added to perl 5.36. Since it will not be experimental anymore in perl 5.40 \o/ the option is deprecated and the same as C<perl>. =item schema Default: C<['Core']> This option is for loading and dumping. Array reference. Here you can define what schema to use. Supported standard Schemas are: C<Failsafe>, C<JSON>, C<Core>, C<YAML1_1>. To get an overview how the different Schemas behave, see L<https://perlpunk.github.io/YAML-PP-p5/schemas.html> Additionally you can add further schemas, for example C<Merge>. =item cyclic_refs Default: C<fatal> (since 0.037) Before the default was C<allow>, but this can lead to memory leaks when loading on untrusted data, so it was changed to C<fatal> by default. This option is for loading only. Defines what to do when a cyclic reference is detected when loading. # fatal - die # warn - Just warn about them and replace with undef # ignore - replace with undef # allow - Default =item duplicate_keys Default: 0 Since version 0.027 This option is for loading. The YAML Spec says duplicate mapping keys should be forbidden. When set to true, duplicate keys in mappings are allowed (and will overwrite the previous key). When set to false, duplicate keys will result in an error when loading. This is especially useful when you have a longer mapping and don't see the duplicate key in your editor: --- a: 1 b: 2 # ............. a: 23 # error =item indent Default: 2 This option is for dumping. Use that many spaces for indenting =item width Since version 0.025 Default: 80 This option is for dumping. Maximum columns when dumping. This is only respected when dumping flow collections right now. in the future it will be used also for wrapping long strings. =item header Default: 1 This option is for dumping. Print document header C<---> =item footer Default: 0 This option is for dumping. Print document footer C<...> =item yaml_version Since version 0.020 This option is for loading and dumping. Default: C<1.2> Note that in this case, a directive C<%YAML 1.1> will basically be ignored and everything loaded with the C<1.2 Core> Schema. If you want to support both YAML 1.1 and 1.2, you have to specify that, and the schema (C<Core> or C<YAML1_1>) will be chosen automatically. my $yp = YAML::PP->new( yaml_version => ['1.2', '1.1'], ); This is the same as my $yp = YAML::PP->new( schema => ['+'], yaml_version => ['1.2', '1.1'], ); because the C<+> stands for the default schema per version. When loading, and there is no C<%YAML> directive, C<1.2> will be considered as default, and the C<Core> schema will be used. If there is a C<%YAML 1.1> directive, the C<YAML1_1> schema will be used. Of course, you can also make C<1.1> the default: my $yp = YAML::PP->new( yaml_version => ['1.1', '1.2'], ); You can also specify C<1.1> only: my $yp = YAML::PP->new( yaml_version => ['1.1'], ); In this case also documents with C<%YAML 1.2> will be loaded with the C<YAML1_1> schema. =item version_directive Since version 0.020 This option is for dumping. Default: 0 Print Version Directive C<%YAML 1.2> (or C<%YAML 1.1>) on top of each YAML document. It will use the first version specified in the C<yaml_version> option. =item preserve Since version 0.021 Default: false This option is for loading and dumping. Preserving scalar styles is still experimental. use YAML::PP::Common qw/ :PRESERVE /; # Preserve the order of hash keys my $yp = YAML::PP->new( preserve => PRESERVE_ORDER ); # Preserve the quoting style of scalars my $yp = YAML::PP->new( preserve => PRESERVE_SCALAR_STYLE ); # Preserve block/flow style (since 0.024) my $yp = YAML::PP->new( preserve => PRESERVE_FLOW_STYLE ); # Preserve alias names (since 0.027) my $yp = YAML::PP->new( preserve => PRESERVE_ALIAS ); # Combine, e.g. preserve order and scalar style my $yp = YAML::PP->new( preserve => PRESERVE_ORDER | PRESERVE_SCALAR_STYLE ); Do NOT rely on the internal implementation of it. If you load the following input: --- z: 1 a: 2 --- - plain - 'single' - "double" - | literal - > folded --- block mapping: &alias flow sequence: [a, b] same mapping: *alias flow mapping: {a: b} with this code: my $yp = YAML::PP->new( preserve => PRESERVE_ORDER | PRESERVE_SCALAR_STYLE | PRESERVE_FLOW_STYLE | PRESERVE_ALIAS ); my ($hash, $styles, $flow) = $yp->load_file($file); $yp->dump_file($hash, $styles, $flow); Then dumping it will return the same output. Note that YAML allows repeated definition of anchors. They cannot be preserved with YAML::PP right now. Example: --- - &seq [a] - *seq - &seq [b] - *seq Because the data could be shuffled before dumping again, the anchor definition could be broken. In this case repeated anchor names will be discarded when loading and dumped with numeric anchors like usual. Implementation: When loading, hashes will be tied to an internal class (C<YAML::PP::Preserve::Hash>) that keeps the key order. Scalars will be returned as objects of an internal class (C<YAML::PP::Preserve::Scalar>) with overloading. If you assign to such a scalar, the object will be replaced by a simple scalar. # assignment, style gets lost $styles->[1] .= ' append'; You can also pass C<1> as a value. In this case all preserving options will be enabled, also if there are new options added in the future. There are also methods to create preserved nodes from scratch. See the C<preserved_(scalar|mapping|sequence)> L<"METHODS"> below. =back =head2 load_string my $doc = $ypp->load_string("foo: bar"); my @docs = $ypp->load_string("foo: bar\n---\n- a"); Input should be Unicode characters. So if you read from a file, you should decode it, for example with C<Encode::decode()>. Note that in scalar context, C<load_string> and C<load_file> return the first document (like L<YAML::Syck>), while L<YAML> and L<YAML::XS> return the last. =head2 load_file my $doc = $ypp->load_file("file.yaml"); my @docs = $ypp->load_file("file.yaml"); Strings will be loaded as unicode characters. =head2 dump_string my $yaml = $ypp->dump_string($doc); my $yaml = $ypp->dump_string($doc1, $doc2); my $yaml = $ypp->dump_string(@docs); Input strings should be Unicode characters. Output will return Unicode characters. So if you want to write that to a file (or pass to YAML::XS, for example), you typically encode it via C<Encode::encode()>. =head2 dump_file $ypp->dump_file("file.yaml", $doc); $ypp->dump_file("file.yaml", $doc1, $doc2); $ypp->dump_file("file.yaml", @docs); Input data should be Unicode characters. =head2 dump This will dump to a predefined writer. By default it will just use the L<YAML::PP::Writer> and output a string. my $writer = MyWriter->new(\my $output); my $yp = YAML::PP->new( writer => $writer, ); $yp->dump($data); =head2 preserved_scalar Since version 0.024 Experimental. Please report bugs or let me know this is useful and works. You can define a certain scalar style when dumping data. Figuring out the best style is a hard task and practically impossible to get it right for all cases. It's also a matter of taste. use YAML::PP::Common qw/ PRESERVE_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE /; my $yp = YAML::PP->new( preserve => PRESERVE_SCALAR_STYLE, ); # a single linebreak would normally be dumped with double quotes: "\n" my $scalar = $yp->preserved_scalar("\n", style => YAML_LITERAL_SCALAR_STYLE ); my $data = { literal => $scalar }; my $dump = $yp->dump_string($data); # output --- literal: |+ ... =head2 preserved_mapping, preserved_sequence Since version 0.024 Experimental. Please report bugs or let me know this is useful and works. With this you can define which nodes are dumped with the more compact flow style instead of block style. If you add C<PRESERVE_ORDER> to the C<preserve> option, it will also keep the order of the keys in a hash. use YAML::PP::Common qw/ PRESERVE_ORDER PRESERVE_FLOW_STYLE YAML_FLOW_MAPPING_STYLE YAML_FLOW_SEQUENCE_STYLE /; my $yp = YAML::PP->new( preserve => PRESERVE_FLOW_STYLE | PRESERVE_ORDER ); my $hash = $yp->preserved_mapping({}, style => YAML_FLOW_MAPPING_STYLE); # Add values after initialization to preserve order %$hash = (z => 1, a => 2, y => 3, b => 4); my $array = $yp->preserved_sequence([23, 24], style => YAML_FLOW_SEQUENCE_STYLE); my $data = $yp->preserved_mapping({}); %$data = ( map => $hash, seq => $array ); my $dump = $yp->dump_string($data); # output --- map: {z: 1, a: 2, y: 3, b: 4} seq: [23, 24] =head2 loader Returns or sets the loader object, by default L<YAML::PP::Loader> =head2 dumper Returns or sets the dumper object, by default L<YAML::PP::Dumper> =head2 schema Returns or sets the schema object =head2 default_schema Creates and returns the default schema =head1 FUNCTIONS The functions C<Load>, C<LoadFile>, C<Dump> and C<DumpFile> are provided as a drop-in replacement for other existing YAML processors. No function is exported by default. Note that in scalar context, C<Load> and C<LoadFile> return the first document (like L<YAML::Syck>), while L<YAML> and L<YAML::XS> return the last. =over =item Load use YAML::PP qw/ Load /; my $doc = Load($yaml); my @docs = Load($yaml); Works like C<load_string>. =item LoadFile use YAML::PP qw/ LoadFile /; my $doc = LoadFile($file); my @docs = LoadFile($file); my @docs = LoadFile($filehandle); Works like C<load_file>. =item Dump use YAML::PP qw/ Dump /; my $yaml = Dump($doc); my $yaml = Dump(@docs); Works like C<dump_string>. =item DumpFile use YAML::PP qw/ DumpFile /; DumpFile($file, $doc); DumpFile($file, @docs); DumpFile($filehandle, @docs); Works like C<dump_file>. =back =head1 PLUGINS You can alter the behaviour of YAML::PP by using the following schema classes: =over =item L<YAML::PP::Schema::Failsafe> One of the three YAML 1.2 official schemas =item L<YAML::PP::Schema::JSON> One of the three YAML 1.2 official schemas. =item L<YAML::PP::Schema::Core> One of the three YAML 1.2 official schemas. Default =item L<YAML::PP::Schema::YAML1_1> Schema implementing the most common YAML 1.1 types =item L<YAML::PP::Schema::Perl> Serializing Perl objects and types =item L<YAML::PP::Schema::Binary> Serializing binary data =item L<YAML::PP::Schema::Tie::IxHash> Deprecated. See option C<preserve> =item L<YAML::PP::Schema::Merge> YAML 1.1 merge keys for mappings =item L<YAML::PP::Schema::Include> Include other YAML files via C<!include> tags =back To make the parsing process faster, you can plugin the libyaml parser with L<YAML::PP::LibYAML>. =head1 IMPLEMENTATION The process of loading and dumping is split into the following steps: Load: YAML Stream Tokens Event List Data Structure ---------> ---------> ---------> lex parse construct Dump: Data Structure Event List YAML Stream ---------> ---------> represent emit You can dump basic perl types like hashes, arrays, scalars (strings, numbers). For dumping blessed objects and things like coderefs have a look at L<YAML::PP::Perl>/L<YAML::PP::Schema::Perl>. =over =item L<YAML::PP::Lexer> The Lexer is reading the YAML stream into tokens. This makes it possible to generate syntax highlighted YAML output. Note that the API to retrieve the tokens will change. =item L<YAML::PP::Parser> The Parser retrieves the tokens from the Lexer. The main YAML content is then parsed with the Grammar. =item L<YAML::PP::Grammar> =item L<YAML::PP::Constructor> The Constructor creates a data structure from the Parser events. =item L<YAML::PP::Loader> The Loader combines the constructor and parser. =item L<YAML::PP::Dumper> The Dumper will delegate to the Representer =item L<YAML::PP::Representer> The Representer will create Emitter events from the given data structure. =item L<YAML::PP::Emitter> The Emitter creates a YAML stream. =back =head2 YAML::PP::Parser Still TODO: =over 4 =item Implicit collection keys --- [ a, b, c ]: value =item Implicit mapping in flow style sequences This is supported since 0.029 (except some not relevant cases): --- [ a, b, c: d ] # equals [ a, b, { c: d } ] =item Plain mapping keys ending with colons --- key ends with two colons::: value This was implemented in 0.037. =item Supported Characters If you have valid YAML that's not parsed, or the other way round, please create an issue. =item Line and Column Numbers You will see line and column numbers in the error message. The column numbers might still be wrong in some cases. =item Error Messages The error messages need to be improved. =item Unicode Surrogate Pairs Currently loaded as single characters without validating =item Possibly more =back =head2 YAML::PP::Constructor The Constructor now supports all three YAML 1.2 Schemas, Failsafe, JSON and Core. Additionally you can choose the schema for YAML 1.1 as C<YAML1_1>. Too see what strings are resolved as booleans, numbers, null etc. look at L<https://perlpunk.github.io/YAML-PP-p5/schema-examples.html>. You can choose the Schema like this: my $ypp = YAML::PP->new(schema => ['JSON']); # default is 'Core' The Tags C<!!seq> and C<!!map> are still ignored for now. It supports: =over 4 =item Handling of Anchors/Aliases Like in modules like L<YAML>, the Constructor will use references for mappings and sequences, but obviously not for scalars. L<YAML::XS> uses real aliases, which allows also aliasing scalars. I might add an option for that since aliasing is now available in pure perl. =item Boolean Handling You can choose between C<'perl'> (1/'', currently default), C<'JSON::PP'> and C<'boolean'>.pm for handling boolean types. That allows you to dump the data structure with one of the JSON modules without losing information about booleans. =item Numbers Numbers are created as real numbers instead of strings, so that they are dumped correctly by modules like L<JSON::PP> or L<JSON::XS>, for example. =item Complex Keys Mapping Keys in YAML can be more than just scalars. Of course, you can't load that into a native perl structure. The Constructor will stringify those keys with L<Data::Dumper> instead of just returning something like C<HASH(0x55dc1b5d0178)>. Example: use YAML::PP; use JSON::PP; my $ypp = YAML::PP->new; my $coder = JSON::PP->new->ascii->pretty->allow_nonref->canonical; my $yaml = <<'EOM'; complex: ? ? a: 1 c: 2 : 23 : 42 EOM my $data = $yppl->load_string($yaml); say $coder->encode($data); __END__ { "complex" : { "{'{a => 1,c => 2}' => 23}" : 42 } } =back TODO: =over 4 =item Parse Tree I would like to generate a complete parse tree, that allows you to manipulate the data structure and also dump it, including all whitespaces and comments. The spec says that this is throwaway content, but I read that many people wish to be able to keep the comments. =back =head2 YAML::PP::Dumper, YAML::PP::Emitter The Dumper should be able to dump strings correctly, adding quotes whenever a plain scalar would look like a special string, like C<true>, or when it contains or starts with characters that are not allowed. Most strings will be dumped as plain scalars without quotes. If they contain special characters or have a special meaning, they will be dumped with single quotes. If they contain control characters, including <"\n">, they will be dumped with double quotes. It will recognize JSON::PP::Boolean and boolean.pm objects and dump them correctly. Numbers which also have a C<PV> flag will be recognized as numbers and not as strings: my $int = 23; say "int: $int"; # $int will now also have a PV flag That means that if you accidentally use a string in numeric context, it will also be recognized as a number: my $string = "23"; my $something = $string + 0; print $yp->dump_string($string); # will be emitted as an integer without quotes! The layout is like libyaml output: key: - a - b - c --- - key1: 1 key2: 2 key3: 3 --- - - a1 - a2 - - b1 - b2 =head1 FAQ - Frequently Asked Questions =over =item Are C<<<> merge keys supported? Yes, this can be enabled optionally, see L<YAML::PP::Schema::Merge> =item Is there a linter / formatter for YAML There is the widely L<"yamllint"|https://yamllint.readthedocs.io/>, based on python's PyYAML. It is very configurable and will report errors or warnings. It cannot format. Now there is also L<YAML::Tidy>, which will format the given file according to your configuration. So far only a few configuration options exist, but they can already be quite helpful. =back =head1 Which YAML module should I use? There are many YAML modules on CPAN. For historical reasons some of them aren't handling YAML correctly. Most of them are not compatible with the YAML spec and with each other, meaning they can interpret the same YAML differently. The behaviours we are discussing here can be divided into parsing issues (syntax) and loading/constructing issues (for example type resolving which decides what is a number, boolean or null). See also L<https://matrix.yaml.info/> (parsing) and L<https://perlpunk.github.io/YAML-PP-p5/schema-examples.html> (loading). =over =item L<"YAML.pm"|YAML> It was written even before the YAML 1.0 spec was finished and by that enabled perl users to process YAML very early. It might work for you if you have simple data, but it's missing quite some features and can also produce YAML that doesn't roundtrip. Nowadays it might be a good idea to switch. =item L<YAML::XS> A libyaml binding that is robust and widely used. However, there are two things to consider. 1. (syntax) libyaml diverged from the spec in several aspects. They are rare though. 2. The type resolving does not adhere to YAML 1.1 or YAML 1.2, meaning it is incompatible with other YAML libraries in perl or other languages. =item L<YAML::Tiny> It implements both a tiny subset of YAML, but also a superset. Meaning it will happily accept some YAML documents that are not officially valid. Type resolving is also not implemented according to the spec. =item L<YAML::Syck> A binding to libsyck. It is even less compatible to YAML than libyaml. Also type resolving is not implemented according to the spec. =item L<YAML::PP> Regarding YAML syntax, it is the second most YAML 1.2 compatible perl module. The cases it cannot (yet) parse are not relevant in perl programming, e.g. hash keys that are not strings. Regarding type resolving, it is compatible with the YAML 1.2 Core schema, so it should be possible to exchange data as YAML with other libraries in other languages. One downside is that it is the slowest perl YAML module. =item L<YAML::Parser> This is a parser generated by the YAML grammar, and it's passing all official tests. A L<YAML::PP::Ref> frontend exists that you can use just like YAML::PP. It is quite slow (although it might be ok for small files depending on the use case). The error messages it creates on invalid YAML are not helpful currently. =item L<YAML::PP::LibYAML> This combines the L<YAML::LibYAML::API> binding for parsing with the YAML::PP frontend for loading and type resolving. It is faster than YAML::PP but slower than YAML::XS. The divergence from the YAML spec regarding syntax is usually not a problem, and at the same time you have the advantage of being compatible to the YAML 1.2 Core Schema. =back =head1 WHY Why did I start to write a new YAML module? All the available parsers and loaders for Perl are behaving differently, and more important, aren't conforming to the spec. L<YAML::XS> is doing pretty well, but C<libyaml> only handles YAML 1.1 and diverges a bit from the spec. The pure perl loaders lack support for a number of features. I was going over L<YAML>.pm issues end of 2016, integrating old patches from rt.cpan.org and creating some pull requests myself. I realized that it would be difficult to patch YAML.pm to parse YAML 1.1 or even 1.2, and it would also break existing usages relying on the current behaviour. In 2016 Ingy döt Net initiated two really cool projects: =over 4 =item L<"YAML TEST SUITE"> =item L<"YAML EDITOR"> =back These projects are a big help for any developer. So I got the idea to write my own parser and started on New Year's Day 2017. Without the test suite and the editor I would have never started this. I also started another YAML Test project which allows one to get a quick overview of which frameworks support which YAML features: =over 4 =item L<"YAML TEST MATRIX"> =back =head2 YAML TEST SUITE L<https://github.com/yaml/yaml-test-suite> It contains almost 400 test cases and expected parsing events and more. There will be more tests coming. This test suite allows you to write parsers without turning the examples from the Specification into tests yourself. Also the examples aren't completely covering all cases - the test suite aims to do that. Thanks also to Felix Krause, who is writing a YAML parser in Nim. He turned all the spec examples into test cases. =head2 YAML EDITOR This is a tool to play around with several YAML parsers and loaders in vim. L<https://github.com/yaml/yaml-editor> The project contains the code to build the frameworks (16 as of this writing) and put it into one big Docker image. It also contains the yaml-editor itself, which will start a vim in the docker container. It uses a lot of funky vimscript that makes playing with it easy and useful. You can choose which frameworks you want to test and see the output in a grid of vim windows. Especially when writing a parser it is extremely helpful to have all the test cases and be able to play around with your own examples to see how they are handled. =head2 YAML TEST MATRIX I was curious to see how the different frameworks handle the test cases, so, using the test suite and the docker image, I wrote some code that runs the tests, manipulates the output to compare it with the expected output, and created a matrix view. L<https://github.com/perlpunk/yaml-test-matrix> You can find the latest build at L<https://matrix.yaml.info> =head1 CONTRIBUTORS =over =item Ingy döt Net Ingy is one of the creators of YAML. In 2016 he started the YAML Test Suite and the YAML Editor. He also made useful suggestions on the class hierarchy of YAML::PP. =item Felix "flyx" Krause Felix answered countless questions about the YAML Specification. =back =head1 SEE ALSO =over =item L<YAML> =item L<YAML::XS> =item L<YAML::Syck> =item L<YAML::Tiny> =item L<YAML::PP::LibYAML> =item L<YAML::LibYAML::API> =item L<YAML::Tidy> =item L<https://www.yaml.info/> =back =head1 SPONSORS The Perl Foundation L<https://www.perlfoundation.org/> sponsored this project (and the YAML Test Suite) with a grant of 2500 USD in 2017-2018. =head1 COPYRIGHT AND LICENSE Copyright 2017-2022 by Tina Müller This library is free software and may be distributed under the same terms as perl itself. =cut 0707010000002F000081A40000000000000000000000016616D6BA00001BD7000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Common.pmuse strict; use warnings; package YAML::PP::Common; our $VERSION = '0.000'; # VERSION use base 'Exporter'; my @p = qw/ PRESERVE_ALL PRESERVE_ORDER PRESERVE_SCALAR_STYLE PRESERVE_FLOW_STYLE PRESERVE_ALIAS /; my @s = qw/ YAML_ANY_SCALAR_STYLE YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_QUOTED_SCALAR_STYLE YAML_ANY_SEQUENCE_STYLE YAML_BLOCK_SEQUENCE_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_ANY_MAPPING_STYLE YAML_BLOCK_MAPPING_STYLE YAML_FLOW_MAPPING_STYLE /; our @EXPORT_OK = (@s, @p); our %EXPORT_TAGS = ( PRESERVE => [@p], STYLES => [@s], ); use constant { YAML_ANY_SCALAR_STYLE => 0, YAML_PLAIN_SCALAR_STYLE => 1, YAML_SINGLE_QUOTED_SCALAR_STYLE => 2, YAML_DOUBLE_QUOTED_SCALAR_STYLE => 3, YAML_LITERAL_SCALAR_STYLE => 4, YAML_FOLDED_SCALAR_STYLE => 5, YAML_QUOTED_SCALAR_STYLE => 'Q', # deprecated YAML_ANY_SEQUENCE_STYLE => 0, YAML_BLOCK_SEQUENCE_STYLE => 1, YAML_FLOW_SEQUENCE_STYLE => 2, YAML_ANY_MAPPING_STYLE => 0, YAML_BLOCK_MAPPING_STYLE => 1, YAML_FLOW_MAPPING_STYLE => 2, PRESERVE_ORDER => 2, PRESERVE_SCALAR_STYLE => 4, PRESERVE_FLOW_STYLE => 8, PRESERVE_ALIAS => 16, PRESERVE_ALL => 31, }; my %scalar_style_to_string = ( YAML_PLAIN_SCALAR_STYLE() => ':', YAML_SINGLE_QUOTED_SCALAR_STYLE() => "'", YAML_DOUBLE_QUOTED_SCALAR_STYLE() => '"', YAML_LITERAL_SCALAR_STYLE() => '|', YAML_FOLDED_SCALAR_STYLE() => '>', ); sub event_to_test_suite { my ($event, $args) = @_; my $ev = $event->{name}; my $string; my $content = $event->{value}; my $properties = ''; $properties .= " &$event->{anchor}" if defined $event->{anchor}; $properties .= " <$event->{tag}>" if defined $event->{tag}; if ($ev eq 'document_start_event') { $string = "+DOC"; $string .= " ---" unless $event->{implicit}; } elsif ($ev eq 'document_end_event') { $string = "-DOC"; $string .= " ..." unless $event->{implicit}; } elsif ($ev eq 'stream_start_event') { $string = "+STR"; } elsif ($ev eq 'stream_end_event') { $string = "-STR"; } elsif ($ev eq 'mapping_start_event') { $string = "+MAP"; if ($event->{style} and $event->{style} eq YAML_FLOW_MAPPING_STYLE) { $string .= ' {}' if $args->{flow}; } $string .= $properties; if (0) { # doesn't match yaml-test-suite format } } elsif ($ev eq 'sequence_start_event') { $string = "+SEQ"; if ($event->{style} and $event->{style} eq YAML_FLOW_SEQUENCE_STYLE) { $string .= ' []' if $args->{flow}; } $string .= $properties; if (0) { # doesn't match yaml-test-suite format } } elsif ($ev eq 'mapping_end_event') { $string = "-MAP"; } elsif ($ev eq 'sequence_end_event') { $string = "-SEQ"; } elsif ($ev eq 'scalar_event') { $string = '=VAL'; $string .= $properties; $content =~ s/\\/\\\\/g; $content =~ s/\t/\\t/g; $content =~ s/\r/\\r/g; $content =~ s/\n/\\n/g; $content =~ s/[\b]/\\b/g; $string .= ' ' . $scalar_style_to_string{ $event->{style} } . $content; } elsif ($ev eq 'alias_event') { $string = "=ALI *$content"; } return $string; } sub test_suite_to_event { my ($str) = @_; my $event = {}; if ($str =~ s/^\+STR//) { $event->{name} = 'stream_start_event'; } elsif ($str =~ s/^\-STR//) { $event->{name} = 'stream_end_event'; } elsif ($str =~ s/^\+DOC//) { $event->{name} = 'document_start_event'; if ($str =~ s/^ ---//) { $event->{implicit} = 0; } else { $event->{implicit} = 1; } } elsif ($str =~ s/^\-DOC//) { $event->{name} = 'document_end_event'; if ($str =~ s/^ \.\.\.//) { $event->{implicit} = 0; } else { $event->{implicit} = 1; } } elsif ($str =~ s/^\+SEQ//) { $event->{name} = 'sequence_start_event'; if ($str =~ s/^ \&(\S+)//) { $event->{anchor} = $1; } if ($str =~ s/^ <(\S+)>//) { $event->{tag} = $1; } } elsif ($str =~ s/^\-SEQ//) { $event->{name} = 'sequence_end_event'; } elsif ($str =~ s/^\+MAP//) { $event->{name} = 'mapping_start_event'; if ($str =~ s/^ \&(\S+)//) { $event->{anchor} = $1; } if ($str =~ s/^ <(\S+)>//) { $event->{tag} = $1; } } elsif ($str =~ s/^\-MAP//) { $event->{name} = 'mapping_end_event'; } elsif ($str =~ s/^=VAL//) { $event->{name} = 'scalar_event'; if ($str =~ s/^ <(\S+)>//) { $event->{tag} = $1; } if ($str =~ s/^ [:'">|]//) { $event->{style} = $1; } if ($str =~ s/^(.*)//) { $event->{value} = $1; } } elsif ($str =~ s/^=ALI//) { $event->{name} = 'alias_event'; if ($str =~ s/^ \*(.*)//) { $event->{value} = $1; } } else { die "Could not parse event '$str'"; } return $event; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Common - Constants and common functions =head1 SYNOPSIS use YAML::PP::Common ':STYLES'; # or use YAML::PP::Common qw/ YAML_ANY_SCALAR_STYLE YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_QUOTED_SCALAR_STYLE YAML_ANY_SEQUENCE_STYLE YAML_BLOCK_SEQUENCE_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_ANY_MAPPING_STYLE YAML_BLOCK_MAPPING_STYLE YAML_FLOW_MAPPING_STYLE /; use YAML::PP::Common ':PRESERVE'; # or use YAML::PP::Common qw/ PRESERVE_ALL PRESERVE_ORDER PRESERVE_SCALAR_STYLE PRESERVE_FLOW_STYLE PRESERVE_ALIAS /: =head1 DESCRIPTION This module provides common constants and functions for modules working with YAML::PP events. =head1 FUNCTIONS =over =item event_to_test_suite my $string = YAML::PP::Common::event_to_test_suite($event_prom_parser); For examples of the returned format look into this distributions's directory C<yaml-test-suite> which is a copy of L<https://github.com/yaml/yaml-test-suite>. =item test_suite_to_event my $event = YAML::PP::Common::test_suite_to_event($str); Turns an event string in test suite format into an event hashref. Not complete yet. =back 07070100000030000081A40000000000000000000000016616D6BA00003258000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Constructor.pm# ABSTRACT: Construct data structure from Parser Events use strict; use warnings; package YAML::PP::Constructor; our $VERSION = '0.000'; # VERSION use YAML::PP; use YAML::PP::Common qw/ PRESERVE_ORDER PRESERVE_SCALAR_STYLE PRESERVE_FLOW_STYLE PRESERVE_ALIAS /; use Scalar::Util qw/ reftype /; use Carp qw/ croak /; use constant DEBUG => ($ENV{YAML_PP_LOAD_DEBUG} or $ENV{YAML_PP_LOAD_TRACE}) ? 1 : 0; use constant TRACE => $ENV{YAML_PP_LOAD_TRACE} ? 1 : 0; my %cyclic_refs = qw/ allow 1 ignore 1 warn 1 fatal 1 /; sub new { my ($class, %args) = @_; my $default_yaml_version = delete $args{default_yaml_version}; my $duplicate_keys = delete $args{duplicate_keys}; unless (defined $duplicate_keys) { $duplicate_keys = 0; } my $preserve = delete $args{preserve} || 0; if ($preserve == 1) { $preserve = PRESERVE_ORDER | PRESERVE_SCALAR_STYLE | PRESERVE_FLOW_STYLE | PRESERVE_ALIAS; } my $cyclic_refs = delete $args{cyclic_refs} || 'fatal'; die "Invalid value for cyclic_refs: $cyclic_refs" unless $cyclic_refs{ $cyclic_refs }; my $schemas = delete $args{schemas}; if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } my $self = bless { default_yaml_version => $default_yaml_version, schemas => $schemas, cyclic_refs => $cyclic_refs, preserve => $preserve, duplicate_keys => $duplicate_keys, }, $class; $self->init; return $self; } sub clone { my ($self) = @_; my $clone = { schemas => $self->{schemas}, schema => $self->{schema}, default_yaml_version => $self->{default_yaml_version}, cyclic_refs => $self->cyclic_refs, preserve => $self->{preserve}, }; return bless $clone, ref $self; } sub init { my ($self) = @_; $self->set_docs([]); $self->set_stack([]); $self->set_anchors({}); $self->set_yaml_version($self->default_yaml_version); $self->set_schema($self->schemas->{ $self->yaml_version } ); } sub docs { return $_[0]->{docs} } sub stack { return $_[0]->{stack} } sub anchors { return $_[0]->{anchors} } sub set_docs { $_[0]->{docs} = $_[1] } sub set_stack { $_[0]->{stack} = $_[1] } sub set_anchors { $_[0]->{anchors} = $_[1] } sub schemas { return $_[0]->{schemas} } sub schema { return $_[0]->{schema} } sub set_schema { $_[0]->{schema} = $_[1] } sub cyclic_refs { return $_[0]->{cyclic_refs} } sub set_cyclic_refs { $_[0]->{cyclic_refs} = $_[1] } sub yaml_version { return $_[0]->{yaml_version} } sub set_yaml_version { $_[0]->{yaml_version} = $_[1] } sub default_yaml_version { return $_[0]->{default_yaml_version} } sub preserve_order { return $_[0]->{preserve} & PRESERVE_ORDER } sub preserve_scalar_style { return $_[0]->{preserve} & PRESERVE_SCALAR_STYLE } sub preserve_flow_style { return $_[0]->{preserve} & PRESERVE_FLOW_STYLE } sub preserve_alias { return $_[0]->{preserve} & PRESERVE_ALIAS } sub duplicate_keys { return $_[0]->{duplicate_keys} } sub document_start_event { my ($self, $event) = @_; my $stack = $self->stack; if ($event->{version_directive}) { my $version = $event->{version_directive}; $version = "$version->{major}.$version->{minor}"; if ($self->{schemas}->{ $version }) { $self->set_yaml_version($version); $self->set_schema($self->schemas->{ $version }); } else { $self->set_yaml_version($self->default_yaml_version); $self->set_schema($self->schemas->{ $self->default_yaml_version }); } } my $ref = []; push @$stack, { type => 'document', ref => $ref, data => $ref, event => $event }; } sub document_end_event { my ($self, $event) = @_; my $stack = $self->stack; my $last = pop @$stack; $last->{type} eq 'document' or die "Expected mapping, but got $last->{type}"; if (@$stack) { die "Got unexpected end of document"; } my $docs = $self->docs; push @$docs, $last->{ref}->[0]; $self->set_anchors({}); $self->set_stack([]); } sub mapping_start_event { my ($self, $event) = @_; my ($data, $on_data) = $self->schema->create_mapping($self, $event); my $ref = { type => 'mapping', ref => [], data => \$data, event => $event, on_data => $on_data, }; my $stack = $self->stack; my $preserve_order = $self->preserve_order; my $preserve_style = $self->preserve_flow_style; my $preserve_alias = $self->preserve_alias; if (($preserve_order or $preserve_style or $preserve_alias) and not tied(%$data)) { tie %$data, 'YAML::PP::Preserve::Hash', %$data; } if ($preserve_style) { my $t = tied %$data; $t->{style} = $event->{style}; } push @$stack, $ref; if (defined(my $anchor = $event->{anchor})) { if ($preserve_alias) { my $t = tied %$data; unless (exists $self->anchors->{ $anchor }) { # Repeated anchors cannot be preserved $t->{alias} = $anchor; } } $self->anchors->{ $anchor } = { data => $ref->{data} }; } } sub mapping_end_event { my ($self, $event) = @_; my $stack = $self->stack; my $last = pop @$stack; my ($ref, $data) = @{ $last }{qw/ ref data /}; $last->{type} eq 'mapping' or die "Expected mapping, but got $last->{type}"; my @merge_keys; my @ref; for (my $i = 0; $i < @$ref; $i += 2) { my $key = $ref->[ $i ]; if (ref $key eq 'YAML::PP::Type::MergeKey') { my $merge = $ref->[ $i + 1 ]; if ((reftype($merge) || '') eq 'HASH') { push @merge_keys, $merge; } elsif ((reftype($merge) || '') eq 'ARRAY') { for my $item (@$merge) { if ((reftype($item) || '') eq 'HASH') { push @merge_keys, $item; } else { die "Expected hash for merge key"; } } } else { die "Expected hash or array for merge key"; } } else { push @ref, $key, $ref->[ $i + 1 ]; } } for my $merge (@merge_keys) { for my $key (keys %$merge) { unless (exists $$data->{ $key }) { $$data->{ $key } = $merge->{ $key }; } } } my $on_data = $last->{on_data} || sub { my ($self, $hash, $items) = @_; my %seen; for (my $i = 0; $i < @$items; $i += 2) { my ($key, $value) = @$items[ $i, $i + 1 ]; $key = '' unless defined $key; if (ref $key) { $key = $self->stringify_complex($key); } if ($seen{ $key }++ and not $self->duplicate_keys) { croak "Duplicate key '$key'"; } $$hash->{ $key } = $value; } }; $on_data->($self, $data, \@ref); push @{ $stack->[-1]->{ref} }, $$data; if (defined(my $anchor = $last->{event}->{anchor})) { $self->anchors->{ $anchor }->{finished} = 1; } return; } sub sequence_start_event { my ($self, $event) = @_; my ($data, $on_data) = $self->schema->create_sequence($self, $event); my $ref = { type => 'sequence', ref => [], data => \$data, event => $event, on_data => $on_data, }; my $stack = $self->stack; my $preserve_style = $self->preserve_flow_style; my $preserve_alias = $self->preserve_alias; if ($preserve_style or $preserve_alias and not tied(@$data)) { tie @$data, 'YAML::PP::Preserve::Array', @$data; my $t = tied @$data; $t->{style} = $event->{style}; } push @$stack, $ref; if (defined(my $anchor = $event->{anchor})) { if ($preserve_alias) { my $t = tied @$data; unless (exists $self->anchors->{ $anchor }) { # Repeated anchors cannot be preserved $t->{alias} = $anchor; } } $self->anchors->{ $anchor } = { data => $ref->{data} }; } } sub sequence_end_event { my ($self, $event) = @_; my $stack = $self->stack; my $last = pop @$stack; $last->{type} eq 'sequence' or die "Expected mapping, but got $last->{type}"; my ($ref, $data) = @{ $last }{qw/ ref data /}; my $on_data = $last->{on_data} || sub { my ($self, $array, $items) = @_; push @$$array, @$items; }; $on_data->($self, $data, $ref); push @{ $stack->[-1]->{ref} }, $$data; if (defined(my $anchor = $last->{event}->{anchor})) { my $test = $self->anchors->{ $anchor }; $self->anchors->{ $anchor }->{finished} = 1; } return; } sub stream_start_event {} sub stream_end_event {} sub scalar_event { my ($self, $event) = @_; DEBUG and warn "CONTENT $event->{value} ($event->{style})\n"; my $value = $self->schema->load_scalar($self, $event); my $last = $self->stack->[-1]; my $preserve_alias = $self->preserve_alias; my $preserve_style = $self->preserve_scalar_style; if (($preserve_style or $preserve_alias) and not ref $value) { my %args = ( value => $value, tag => $event->{tag}, ); if ($preserve_style) { $args{style} = $event->{style}; } if ($preserve_alias and defined $event->{anchor}) { my $anchor = $event->{anchor}; unless (exists $self->anchors->{ $anchor }) { # Repeated anchors cannot be preserved $args{alias} = $event->{anchor}; } } $value = YAML::PP::Preserve::Scalar->new( %args ); } if (defined (my $name = $event->{anchor})) { $self->anchors->{ $name } = { data => \$value, finished => 1 }; } push @{ $last->{ref} }, $value; } sub alias_event { my ($self, $event) = @_; my $value; my $name = $event->{value}; if (my $anchor = $self->anchors->{ $name }) { # We know this is a cyclic ref since the node hasn't # been constructed completely yet unless ($anchor->{finished} ) { my $cyclic_refs = $self->cyclic_refs; if ($cyclic_refs ne 'allow') { if ($cyclic_refs eq 'fatal') { croak "Found cyclic ref for alias '$name'"; } if ($cyclic_refs eq 'warn') { $anchor = { data => \undef }; warn "Found cyclic ref for alias '$name'"; } elsif ($cyclic_refs eq 'ignore') { $anchor = { data => \undef }; } } } $value = $anchor->{data}; } else { croak "No anchor defined for alias '$name'"; } my $last = $self->stack->[-1]; push @{ $last->{ref} }, $$value; } sub stringify_complex { my ($self, $data) = @_; return $data if ( ref $data eq 'YAML::PP::Preserve::Scalar' and ($self->preserve_scalar_style or $self->preserve_alias) ); require Data::Dumper; local $Data::Dumper::Quotekeys = 0; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; local $Data::Dumper::Useqq = 0; local $Data::Dumper::Sortkeys = 1; my $string = Data::Dumper->Dump([$data], ['data']); $string =~ s/^\$data = //; return $string; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Constructor - Constructing data structure from parsing events =head1 METHODS =over =item new The Constructor constructor my $constructor = YAML::PP::Constructor->new( schema => $schema, cyclic_refs => $cyclic_refs, ); =item init Resets any data being used during construction. $constructor->init; =item document_start_event, document_end_event, mapping_start_event, mapping_end_event, sequence_start_event, sequence_end_event, scalar_event, alias_event, stream_start_event, stream_end_event These methods are called from L<YAML::PP::Parser>: $constructor->document_start_event($event); =item anchors, set_anchors Helper for storing anchors during construction =item docs, set_docs Helper for storing resulting documents during construction =item stack, set_stack Helper for storing data during construction =item cyclic_refs, set_cyclic_refs Option for controlling the behaviour when finding circular references =item schema, set_schema Holds a L<YAML::PP::Schema> object =item stringify_complex When constructing a hash and getting a non-scalar key, this method is used to stringify the key. It uses a terse Data::Dumper output. Other modules, like L<YAML::XS>, use the default stringification, C<ARRAY(0x55617c0c7398)> for example. =back =cut 07070100000031000081A40000000000000000000000016616D6BA000020D1000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Dumper.pmuse strict; use warnings; package YAML::PP::Dumper; our $VERSION = '0.000'; # VERSION use Scalar::Util qw/ blessed refaddr reftype /; use YAML::PP; use YAML::PP::Emitter; use YAML::PP::Representer; use YAML::PP::Writer; use YAML::PP::Writer::File; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_ANY_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE YAML_BLOCK_MAPPING_STYLE YAML_BLOCK_SEQUENCE_STYLE /; sub new { my ($class, %args) = @_; my $header = delete $args{header}; $header = 1 unless defined $header; my $footer = delete $args{footer}; $footer = 0 unless defined $footer; my $version_directive = delete $args{version_directive}; my $preserve = delete $args{preserve}; my $schema = delete $args{schema} || YAML::PP->default_schema( boolean => 'perl', ); my $emitter = delete $args{emitter} || YAML::PP::Emitter->new; unless (blessed($emitter)) { $emitter = YAML::PP::Emitter->new( %$emitter ); } if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } my $self = bless { representer => YAML::PP::Representer->new( schema => $schema, preserve => $preserve, ), version_directive => $version_directive, emitter => $emitter, seen => {}, anchors => {}, anchor_num => 0, header => $header, footer => $footer, }, $class; return $self; } sub clone { my ($self) = @_; my $clone = { representer => $self->representer->clone, emitter => $self->emitter->clone, version_directive => $self->version_directive, seen => {}, anchors => {}, anchor_num => 0, header => $self->header, footer => $self->footer, }; return bless $clone, ref $self; } sub init { my ($self) = @_; $self->{seen} = {}; $self->{anchors} = {}; $self->{anchor_num} = 0; } sub emitter { return $_[0]->{emitter} } sub representer { return $_[0]->{representer} } sub set_representer { $_[0]->{representer} = $_[1] } sub header { return $_[0]->{header} } sub footer { return $_[0]->{footer} } sub version_directive { return $_[0]->{version_directive} } sub dump { my ($self, @docs) = @_; $self->emitter->init; $self->emitter->stream_start_event({}); for my $i (0 .. $#docs) { my $header_implicit = ($i == 0 and not $self->header); my %args = ( implicit => $header_implicit, ); if ($self->version_directive) { my ($major, $minor) = split m/\./, $self->representer->schema->yaml_version; $args{version_directive} = { major => $major, minor => $minor }; } $self->emitter->document_start_event( \%args ); $self->init; $self->_check_references($docs[ $i ]); $self->_dump_node($docs[ $i ]); my $footer_implicit = (not $self->footer); $self->emitter->document_end_event({ implicit => $footer_implicit }); } $self->emitter->stream_end_event({}); my $output = $self->emitter->writer->output; $self->emitter->finish; return $output; } sub _dump_node { my ($self, $value) = @_; my $node = { value => $value, }; if (ref $value) { my $seen = $self->{seen}; my $refaddr = refaddr $value; if ($seen->{ $refaddr } and $seen->{ $refaddr } > 1) { my $anchor = $self->{anchors}->{ $refaddr }; unless (defined $anchor) { if ($self->representer->preserve_alias) { if (ref $node->{value} eq 'YAML::PP::Preserve::Scalar') { if (defined $node->{value}->alias) { $node->{anchor} = $node->{value}->alias; $self->{anchors}->{ $refaddr } = $node->{value}->alias; } } elsif (reftype $node->{value} eq 'HASH') { if (my $tied = tied %{ $node->{value} } ) { if (defined $tied->{alias}) { $node->{anchor} = $tied->{alias}; $self->{anchors}->{ $refaddr } = $node->{anchor}; } } } elsif (reftype $node->{value} eq 'ARRAY') { if (my $tied = tied @{ $node->{value} } ) { if (defined $tied->{alias}) { $node->{anchor} = $tied->{alias}; $self->{anchors}->{ $refaddr } = $node->{anchor}; } } } } unless (defined $node->{anchor}) { my $num = ++$self->{anchor_num}; $self->{anchors}->{ $refaddr } = $num; $node->{anchor} = $num; } } else { $node->{value} = $anchor; $self->_emit_node([ alias => $node ]); return; } } } $node = $self->representer->represent_node($node); $self->_emit_node($node); } sub _emit_node { my ($self, $item) = @_; my ($type, $node, %args) = @$item; if ($type eq 'alias') { $self->emitter->alias_event({ value => $node->{value} }); return; } if ($type eq 'mapping') { my $style = $args{style} || YAML_BLOCK_MAPPING_STYLE; # TODO if ($node->{items} and @{ $node->{items} } == 0) { # $style = YAML_FLOW_MAPPING_STYLE; } $self->emitter->mapping_start_event({ anchor => $node->{anchor}, style => $style, tag => $node->{tag}, }); for (@{ $node->{items} }) { $self->_dump_node($_); } $self->emitter->mapping_end_event; return; } if ($type eq 'sequence') { my $style = $args{style} || YAML_BLOCK_SEQUENCE_STYLE; if (@{ $node->{items} } == 0) { # $style = YAML_FLOW_SEQUENCE_STYLE; } $self->emitter->sequence_start_event({ anchor => $node->{anchor}, style => $style, tag => $node->{tag}, }); for (@{ $node->{items} }) { $self->_dump_node($_); } $self->emitter->sequence_end_event; return; } $self->emitter->scalar_event({ value => $node->{items}->[0], style => $node->{style}, anchor => $node->{anchor}, tag => $node->{tag}, }); } sub dump_string { my ($self, @docs) = @_; my $writer = YAML::PP::Writer->new; $self->emitter->set_writer($writer); my $output = $self->dump(@docs); return $output; } sub dump_file { my ($self, $file, @docs) = @_; my $writer = YAML::PP::Writer::File->new(output => $file); $self->emitter->set_writer($writer); my $output = $self->dump(@docs); return $output; } my %_reftypes = ( HASH => 1, ARRAY => 1, Regexp => 1, REGEXP => 1, CODE => 1, SCALAR => 1, REF => 1, GLOB => 1, ); sub _check_references { my ($self, $doc) = @_; my $reftype = reftype $doc or return; my $seen = $self->{seen}; # check which references are used more than once if ($reftype eq 'SCALAR' and grep { ref $doc eq $_ } @{ $self->representer->schema->bool_class || [] }) { # JSON::PP and boolean.pm always return the same reference for booleans # Avoid printing *aliases in those case if (ref $doc eq 'boolean' or ref $doc eq 'JSON::PP::Boolean') { return; } } if (++$seen->{ refaddr $doc } > 1) { # seen already return; } unless ($_reftypes{ $reftype }) { die sprintf "Reference %s not implemented", $reftype; } if ($reftype eq 'HASH') { $self->_check_references($doc->{ $_ }) for keys %$doc; } elsif ($reftype eq 'ARRAY') { $self->_check_references($_) for @$doc; } elsif ($reftype eq 'REF') { $self->_check_references($$doc); } } 1; 07070100000032000081A40000000000000000000000016616D6BA00007A53000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Emitter.pmuse strict; use warnings; package YAML::PP::Emitter; our $VERSION = '0.000'; # VERSION use Data::Dumper; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE /; use constant DEBUG => $ENV{YAML_PP_EMIT_DEBUG} ? 1 : 0; use constant DEFAULT_WIDTH => 80; sub new { my ($class, %args) = @_; my $self = bless { indent => $args{indent} || 2, writer => $args{writer}, width => $args{width} || DEFAULT_WIDTH, }, $class; $self->init; return $self; } sub clone { my ($self) = @_; my $clone = { indent => $self->indent, }; return bless $clone, ref $self; } sub event_stack { return $_[0]->{event_stack} } sub set_event_stack { $_[0]->{event_stack} = $_[1] } sub indent { return $_[0]->{indent} } sub width { return $_[0]->{width} } sub line { return $_[0]->{line} } sub column { return $_[0]->{column} } sub set_indent { $_[0]->{indent} = $_[1] } sub writer { $_[0]->{writer} } sub set_writer { $_[0]->{writer} = $_[1] } sub tagmap { return $_[0]->{tagmap} } sub set_tagmap { $_[0]->{tagmap} = $_[1] } sub init { my ($self) = @_; unless ($self->writer) { $self->set_writer(YAML::PP::Writer->new); } $self->set_tagmap({ 'tag:yaml.org,2002:' => '!!', }); $self->{open_ended} = 0; $self->{line} = 0; $self->{column} = 0; $self->writer->init; } sub mapping_start_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ mapping_start_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = $stack->[-1]; my $indent = $last->{indent}; my $new_indent = $indent; my $yaml = ''; my $props = ''; my $anchor = $info->{anchor}; my $tag = $info->{tag}; if (defined $anchor) { $anchor = "&$anchor"; } if (defined $tag) { $tag = $self->_emit_tag('map', $tag); } $props = join ' ', grep defined, ($anchor, $tag); my $flow = $last->{flow} || 0; $flow++ if ($info->{style} || 0) eq YAML_FLOW_MAPPING_STYLE; my $newline = 0; if ($flow > 1) { if ($last->{type} eq 'SEQ') { if ($last->{newline}) { $yaml .= ' '; } if ($last->{index} == 0) { $yaml .= "["; } else { $yaml .= ","; } } elsif ($last->{type} eq 'MAP') { if ($last->{newline}) { $yaml .= ' '; } if ($last->{index} == 0) { $yaml .= "{"; } else { $yaml .= ","; } } elsif ($last->{type} eq 'MAPVALUE') { if ($last->{index} == 0) { die "Should not happen (index 0 in MAPVALUE)"; } $yaml .= ": "; } if ($props) { $yaml .= " $props "; } $new_indent .= ' ' x $self->indent; } else { if ($last->{type} eq 'DOC') { $newline = $last->{newline}; } else { if ($last->{newline}) { $yaml .= "\n"; $last->{column} = 0; } if ($last->{type} eq 'MAPVALUE') { $new_indent .= ' ' x $self->indent; $newline = 1; } else { $new_indent = $indent; if (not $props and $self->indent == 1) { $new_indent .= ' ' x 2; } else { $new_indent .= ' ' x $self->indent; } if ($last->{column}) { my $space = $self->indent > 1 ? ' ' x ($self->indent - 1) : ' '; $yaml .= $space; } else { $yaml .= $indent; } if ($last->{type} eq 'SEQ') { $yaml .= '-'; } elsif ($last->{type} eq 'MAP') { $yaml .= "?"; $last->{type} = 'COMPLEX'; } elsif ($last->{type} eq 'COMPLEXVALUE') { $yaml .= ":"; } else { die "Should not happen ($last->{type} in mapping_start)"; } $last->{column} = 1; } $last->{newline} = 0; } if ($props) { $yaml .= $last->{column} ? ' ' : $indent; $yaml .= $props; $newline = 1; } } $self->_write($yaml); my $new_info = { index => 0, indent => $new_indent, info => $info, newline => $newline, column => $self->column, flow => $flow, }; $new_info->{type} = 'MAP'; push @{ $stack }, $new_info; $last->{index}++; $self->{open_ended} = 0; } sub mapping_end_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ mapping_end_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = pop @{ $stack }; if ($last->{index} == 0) { my $indent = $last->{indent}; my $zero_indent = $last->{zero_indent}; if ($last->{zero_indent}) { $indent .= ' ' x $self->indent; } if ($self->column) { $self->_write(" {}\n"); } else { $self->_write("$indent\{}\n"); } } elsif ($last->{flow}) { my $yaml = "}"; if ($last->{flow} == 1) { $yaml .= "\n"; } $self->_write("$yaml"); } $last = $stack->[-1]; $last->{column} = $self->column; if ($last->{type} eq 'SEQ') { } elsif ($last->{type} eq 'MAP') { $last->{type} = 'MAPVALUE'; } elsif ($last->{type} eq 'MAPVALUE') { $last->{type} = 'MAP'; } elsif ($last->{type} eq 'COMPLEX') { $last->{type} = 'COMPLEXVALUE'; } elsif ($last->{type} eq 'COMPLEXVALUE') { $last->{type} = 'MAP'; } } sub sequence_start_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ sequence_start_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = $stack->[-1]; my $indent = $last->{indent}; my $new_indent = $indent; my $yaml = ''; my $props = ''; my $anchor = $info->{anchor}; my $tag = $info->{tag}; if (defined $anchor) { $anchor = "&$anchor"; } if (defined $tag) { $tag = $self->_emit_tag('seq', $tag); } $props = join ' ', grep defined, ($anchor, $tag); my $flow = $last->{flow} || 0; $flow++ if $flow or ($info->{style} || 0) eq YAML_FLOW_SEQUENCE_STYLE; my $newline = 0; my $zero_indent = 0; if ($flow > 1) { if ($last->{type} eq 'SEQ') { if ($last->{newline}) { $yaml .= ' '; } if ($last->{index} == 0) { $yaml .= "["; } else { $yaml .= ","; } } elsif ($last->{type} eq 'MAP') { if ($last->{newline}) { $yaml .= ' '; } if ($last->{index} == 0) { $yaml .= "{"; } else { $yaml .= ","; } } elsif ($last->{type} eq 'MAPVALUE') { if ($last->{index} == 0) { die "Should not happen (index 0 in MAPVALUE)"; } $yaml .= ": "; } if ($props) { $yaml .= " $props "; } $new_indent .= ' ' x $self->indent; } else { if ($last->{type} eq 'DOC') { $newline = $last->{newline}; } else { if ($last->{newline}) { $yaml .= "\n"; $last->{column} = 0; } if ($last->{type} eq 'MAPVALUE') { $zero_indent = 1; $newline = 1; } else { if (not $props and $self->indent == 1) { $new_indent .= ' ' x 2; } else { $new_indent .= ' ' x $self->indent; } if ($last->{column}) { my $space = $self->indent > 1 ? ' ' x ($self->indent - 1) : ' '; $yaml .= $space; } else { $yaml .= $indent; } if ($last->{type} eq 'SEQ') { $yaml .= "-"; } elsif ($last->{type} eq 'MAP') { $last->{type} = 'COMPLEX'; $zero_indent = 1; $yaml .= "?"; } elsif ($last->{type} eq 'COMPLEXVALUE') { $yaml .= ":"; $zero_indent = 1; } else { die "Should not happen ($last->{type} in sequence_start)"; } $last->{column} = 1; } $last->{newline} = 0; } if ($props) { $yaml .= $last->{column} ? ' ' : $indent; $yaml .= $props; $newline = 1; } } $self->_write($yaml); $last->{index}++; my $new_info = { index => 0, indent => $new_indent, info => $info, zero_indent => $zero_indent, newline => $newline, column => $self->column, flow => $flow, }; $new_info->{type} = 'SEQ'; push @{ $stack }, $new_info; $self->{open_ended} = 0; } sub sequence_end_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ sequence_end_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = pop @{ $stack }; if ($last->{index} == 0) { my $indent = $last->{indent}; my $zero_indent = $last->{zero_indent}; if ($last->{zero_indent}) { $indent .= ' ' x $self->indent; } my $yaml .= $self->column ? ' ' : $indent; $yaml .= "[]"; if ($last->{flow} < 2) { $yaml .= "\n"; } $self->_write($yaml); } elsif ($last->{flow}) { my $yaml = "]"; if ($last->{flow} == 1) { $yaml .= "\n"; } $self->_write($yaml); } $last = $stack->[-1]; $last->{column} = $self->column; if ($last->{type} eq 'SEQ') { } elsif ($last->{type} eq 'MAP') { $last->{type} = 'MAPVALUE'; } elsif ($last->{type} eq 'MAPVALUE') { $last->{type} = 'MAP'; } elsif ($last->{type} eq 'COMPLEX') { $last->{type} = 'COMPLEXVALUE'; } elsif ($last->{type} eq 'COMPLEXVALUE') { $last->{type} = 'MAP'; } } my %forbidden_first = (qw/ ! 1 & 1 * 1 { 1 } 1 [ 1 ] 1 | 1 > 1 @ 1 ` 1 " 1 ' 1 /, '#' => 1, '%' => 1, ',' => 1, " " => 1); my %forbidden_first_plus_space = (qw/ ? 1 - 1 : 1 /); my %control = ( "\x00" => '\0', "\x01" => '\x01', "\x02" => '\x02', "\x03" => '\x03', "\x04" => '\x04', "\x05" => '\x05', "\x06" => '\x06', "\x07" => '\a', "\x08" => '\b', "\x0b" => '\v', "\x0c" => '\f', "\x0e" => '\x0e', "\x0f" => '\x0f', "\x10" => '\x10', "\x11" => '\x11', "\x12" => '\x12', "\x13" => '\x13', "\x14" => '\x14', "\x15" => '\x15', "\x16" => '\x16', "\x17" => '\x17', "\x18" => '\x18', "\x19" => '\x19', "\x1a" => '\x1a', "\x1b" => '\e', "\x1c" => '\x1c', "\x1d" => '\x1d', "\x1e" => '\x1e', "\x1f" => '\x1f', "\x7f" => '\x7f', "\x80" => '\x80', "\x81" => '\x81', "\x82" => '\x82', "\x83" => '\x83', "\x84" => '\x84', "\x86" => '\x86', "\x87" => '\x87', "\x88" => '\x88', "\x89" => '\x89', "\x8a" => '\x8a', "\x8b" => '\x8b', "\x8c" => '\x8c', "\x8d" => '\x8d', "\x8e" => '\x8e', "\x8f" => '\x8f', "\x90" => '\x90', "\x91" => '\x91', "\x92" => '\x92', "\x93" => '\x93', "\x94" => '\x94', "\x95" => '\x95', "\x96" => '\x96', "\x97" => '\x97', "\x98" => '\x98', "\x99" => '\x99', "\x9a" => '\x9a', "\x9b" => '\x9b', "\x9c" => '\x9c', "\x9d" => '\x9d', "\x9e" => '\x9e', "\x9f" => '\x9f', "\x{2029}" => '\P', "\x{2028}" => '\L', "\x85" => '\N', "\xa0" => '\_', ); my $control_re = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x84\x86-\x9f\x{d800}-\x{dfff}\x{fffe}\x{ffff}\x{2028}\x{2029}\x85\xa0'; my %to_escape = ( "\n" => '\n', "\t" => '\t', "\r" => '\r', '\\' => '\\\\', '"' => '\\"', %control, ); my $escape_re = $control_re . '\n\t\r'; my $escape_re_without_lb = $control_re . '\t\r'; sub scalar_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ scalar_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = $stack->[-1]; my $indent = $last->{indent}; my $value = $info->{value}; my $flow = $last->{flow}; my $props = ''; my $anchor = $info->{anchor}; my $tag = $info->{tag}; if (defined $anchor) { $anchor = "&$anchor"; } if (defined $tag) { $tag = $self->_emit_tag('scalar', $tag); } $props = join ' ', grep defined, ($anchor, $tag); DEBUG and local $Data::Dumper::Useqq = 1; $value = '' unless defined $value; my $style = $self->_find_best_scalar_style( info => $info, value => $value, ); my $open_ended = 0; if ($style == YAML_PLAIN_SCALAR_STYLE) { $value =~ s/\n/\n\n/g; } elsif ($style == YAML_SINGLE_QUOTED_SCALAR_STYLE) { my $new_indent = $last->{indent} . (' ' x $self->indent); $value =~ s/(\n+)/"\n" x (1 + (length $1))/eg; my @lines = split m/\n/, $value, -1; if (@lines > 1) { for my $line (@lines[1 .. $#lines]) { $line = $new_indent . $line if length $line; } } $value = join "\n", @lines; $value =~ s/'/''/g; $value = "'" . $value . "'"; } elsif ($style == YAML_LITERAL_SCALAR_STYLE) { DEBUG and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$value], ['value']); my $indicators = ''; if ($value =~ m/\A\n* +/) { $indicators .= $self->indent; } my $indent = $indent . ' ' x $self->indent; if ($value !~ m/\n\z/) { $indicators .= '-'; $value .= "\n"; } elsif ($value =~ m/(\n|\A)\n\z/) { $indicators .= '+'; $open_ended = 1; } $value =~ s/^(?=.)/$indent/gm; $value = "|$indicators\n$value"; } elsif ($style == YAML_FOLDED_SCALAR_STYLE) { DEBUG and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$value], ['value']); my @lines = split /\n/, $value, -1; DEBUG and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\@lines], ['lines']); my $trailing = -1; while (@lines) { last if $lines[-1] ne ''; pop @lines; $trailing++; } my %start_with_space; for my $i (0 .. $#lines) { if ($lines[ $i ] =~ m/^[ \t]+/) { $start_with_space{ $i } = 1; } } my $indicators = ''; if ($value =~ m/\A\n* +/) { $indicators .= $self->indent; } my $indent = $indent . ' ' x $self->indent; if ($trailing > 0) { $indicators .= '+'; $open_ended = 1; } elsif ($trailing < 0) { $indicators .= '-'; } $value = ">$indicators\n"; my $got_content = 0; for my $i (0 .. $#lines) { my $line = $lines[ $i ]; my $sp = $start_with_space{ $i } || 0; my $spnext = $i == $#lines ? 1 : $start_with_space{ $i+1 } || 0; my $spprev = $i == 0 ? 1 : $start_with_space{ $i-1 } || 0; my $empty = length $line ? 0 : 1; my $emptynext = $i == $#lines ? '' : length $lines[$i+1] ? 0 : 1; my $nl = 0; if ($empty) { if ($spnext and $spprev) { $nl = 1; } elsif (not $spnext) { $nl = 1; } elsif (not $got_content) { $nl = 1; } } else { $got_content = 1; $value .= "$indent$line\n"; if (not $sp and not $spnext) { $nl = 1; } } if ($nl) { $value .= "\n"; } } $value .= "\n" x ($trailing) if $trailing > 0; } else { $value =~ s/([$escape_re"\\])/$to_escape{ $1 } || sprintf '\\u%04x', ord($1)/eg; $value = '"' . $value . '"'; } DEBUG and warn __PACKAGE__.':'.__LINE__.": (@$stack)\n"; my $yaml = $self->_emit_scalar( indent => $indent, props => $props, value => $value, style => $style, ); $last->{index}++; $last->{newline} = 0; $self->_write($yaml); $last->{column} = $self->column; $self->{open_ended} = $open_ended; } sub _find_best_scalar_style { my ($self, %args) = @_; my $info = $args{info}; my $style = $info->{style}; my $value = $args{value}; my $stack = $self->event_stack; my $last = $stack->[-1]; my $flow = $last->{flow}; my $first = substr($value, 0, 1); if ($value eq '') { if ($flow and $last->{type} ne 'MAPVALUE' and $last->{type} ne 'MAP') { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif (not $style) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } } # no control characters anywhere elsif ($value =~ m/[$control_re]/) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } $style ||= YAML_PLAIN_SCALAR_STYLE; if ($style == YAML_SINGLE_QUOTED_SCALAR_STYLE) { if ($value =~ m/ \n/ or $value =~ m/\n / or $value =~ m/^\n/ or $value =~ m/\n$/) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } elsif ($value eq "\n") { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } } elsif ($style == YAML_LITERAL_SCALAR_STYLE or $style == YAML_FOLDED_SCALAR_STYLE) { if ($value eq '') { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } elsif ($flow) { # no block scalars in flow if ($value =~ tr/\n//) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } else { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } } } elsif ($style == YAML_PLAIN_SCALAR_STYLE) { if (not length $value) { } elsif ($value =~ m/[$escape_re_without_lb]/) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } elsif ($value eq "\n") { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } elsif ($value !~ tr/ //c) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($value !~ tr/ \n//c) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } elsif ($value =~ tr/\n//) { $style = $flow ? YAML_DOUBLE_QUOTED_SCALAR_STYLE : YAML_LITERAL_SCALAR_STYLE; } elsif ($forbidden_first{ $first }) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($flow and $value =~ tr/,[]{}//) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif (substr($value, 0, 3) =~ m/^(?:---|\.\.\.)/) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($value =~ m/: /) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($value =~ m/ #/) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($value =~ m/[: \t]\z/) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($value =~ m/[^\x20-\x3A\x3B-\x7E\x85\xA0-\x{D7FF}\x{E000}-\x{FEFE}\x{FF00}-\x{FFFD}\x{10000}-\x{10FFFF}]/) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } elsif ($forbidden_first_plus_space{ $first }) { if (length ($value) == 1 or substr($value, 1, 1) =~ m/^\s/) { $style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } } } if ($style == YAML_SINGLE_QUOTED_SCALAR_STYLE and not $info->{style}) { if ($value =~ tr/'// and $value !~ tr/"//) { $style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; } } return $style; } sub _emit_scalar { my ($self, %args) = @_; my $props = $args{props}; my $value = $args{value}; my $style = $args{style}; my $stack = $self->event_stack; my $last = $stack->[-1]; my $flow = $last->{flow}; my $yaml = ''; my $pvalue = $props; if ($props and length $value) { $pvalue .= " $value"; } elsif (length $value) { $pvalue .= $value; } if ($flow) { if ($props and not length $value) { $pvalue .= ' '; } $yaml = $self->_emit_flow_scalar( value => $value, pvalue => $pvalue, style => $args{style}, ); } else { $yaml = $self->_emit_block_scalar( props => $props, value => $value, pvalue => $pvalue, indent => $args{indent}, style => $args{style}, ); } return $yaml; } sub _emit_block_scalar { my ($self, %args) = @_; my $props = $args{props}; my $value = $args{value}; my $pvalue = $args{pvalue}; my $indent = $args{indent}; my $style = $args{style}; my $stack = $self->event_stack; my $last = $stack->[-1]; my $yaml; if ($last->{type} eq 'MAP' or $last->{type} eq 'SEQ') { if ($last->{index} == 0 and $last->{newline}) { $yaml .= "\n"; $last->{column} = 0; $last->{newline} = 0; } } my $space = ' '; my $multiline = ($style == YAML_LITERAL_SCALAR_STYLE or $style == YAML_FOLDED_SCALAR_STYLE); if ($last->{type} eq 'MAP') { if ($last->{column}) { my $space = $self->indent > 1 ? ' ' x ($self->indent - 1) : ' '; $yaml .= $space; } else { $yaml .= $indent; } if ($props and not length $value) { $pvalue .= ' '; } $last->{type} = 'MAPVALUE'; if ($multiline) { # oops, a complex key $yaml .= "? "; $last->{type} = 'COMPLEXVALUE'; } if (not $multiline) { $pvalue .= ":"; } } else { if ($last->{type} eq 'MAPVALUE') { $last->{type} = 'MAP'; } elsif ($last->{type} eq 'DOC') { } else { if ($last->{column}) { my $space = $self->indent > 1 ? ' ' x ($self->indent - 1) : ' '; $yaml .= $space; } else { $yaml .= $indent; } if ($last->{type} eq 'COMPLEXVALUE') { $last->{type} = 'MAP'; $yaml .= ":"; } elsif ($last->{type} eq 'SEQ') { $yaml .= "-"; } else { die "Should not happen ($last->{type} in scalar_event)"; } $last->{column} = 1; } if (length $pvalue) { if ($last->{column}) { $pvalue = "$space$pvalue"; } } if (not $multiline) { $pvalue .= "\n"; } } $yaml .= $pvalue; return $yaml; } sub _emit_flow_scalar { my ($self, %args) = @_; my $value = $args{value}; my $pvalue = $args{pvalue}; my $stack = $self->event_stack; my $last = $stack->[-1]; my $yaml; if ($last->{type} eq 'SEQ') { if ($last->{index} == 0) { if ($self->column) { $yaml .= ' '; } $yaml .= "["; } else { $yaml .= ", "; } } elsif ($last->{type} eq 'MAP') { if ($last->{index} == 0) { if ($self->column) { $yaml .= ' '; } $yaml .= "{"; } else { $yaml .= ", "; } $last->{type} = 'MAPVALUE'; } elsif ($last->{type} eq 'MAPVALUE') { if ($last->{index} == 0) { die "Should not happen (index 0 in MAPVALUE)"; } $yaml .= ": "; $last->{type} = 'MAP'; } if ($self->column + length $pvalue > $self->width) { $yaml .= "\n"; $yaml .= $last->{indent}; $yaml .= ' ' x $self->indent; } $yaml .= $pvalue; return $yaml; } sub alias_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ alias_event\n"; my ($self, $info) = @_; my $stack = $self->event_stack; my $last = $stack->[-1]; my $indent = $last->{indent}; my $flow = $last->{flow}; my $alias = '*' . $info->{value}; my $yaml = ''; if ($last->{type} eq 'MAP' or $last->{type} eq 'SEQ') { if ($last->{index} == 0 and $last->{newline}) { $yaml .= "\n"; $last->{column} = 0; $last->{newline} = 0; } } $yaml .= $last->{column} ? ' ' : $indent; if ($flow) { my $space = ''; if ($last->{type} eq 'SEQ') { if ($last->{index} == 0) { if ($flow == 1) { $yaml .= ' '; } $yaml .= "["; } else { $yaml .= ", "; } } elsif ($last->{type} eq 'MAP') { if ($last->{index} == 0) { if ($flow == 1) { $yaml .= ' '; } $yaml .= "{"; } else { $yaml .= ", "; } $last->{type} = 'MAPVALUE'; $space = ' '; } elsif ($last->{type} eq 'MAPVALUE') { if ($last->{index} == 0) { die 23; if ($flow == 1) { $yaml .= ' '; } $yaml .= "{"; } else { $yaml .= ": "; } $last->{type} = 'MAP'; } $yaml .= "$alias$space"; } else { if ($last->{type} eq 'MAP') { $yaml .= "$alias :"; $last->{type} = 'MAPVALUE'; } else { if ($last->{type} eq 'MAPVALUE') { $last->{type} = 'MAP'; } elsif ($last->{type} eq 'DOC') { # TODO an alias at document level isn't actually valid } else { if ($last->{type} eq 'COMPLEXVALUE') { $last->{type} = 'MAP'; $yaml .= ": "; } elsif ($last->{type} eq 'COMPLEX') { $yaml .= ": "; } elsif ($last->{type} eq 'SEQ') { $yaml .= "- "; } else { die "Unexpected"; } } $yaml .= "$alias\n"; } } $self->_write("$yaml"); $last->{index}++; $last->{column} = $self->column; $self->{open_ended} = 0; } sub document_start_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ document_start_event\n"; my ($self, $info) = @_; my $newline = 0; my $implicit = $info->{implicit}; if ($info->{version_directive}) { if ($self->{open_ended}) { $self->_write("...\n"); } $self->_write("%YAML $info->{version_directive}->{major}.$info->{version_directive}->{minor}\n"); $self->{open_ended} = 0; $implicit = 0; # we need --- } unless ($implicit) { $newline = 1; $self->_write("---"); } $self->set_event_stack([ { type => 'DOC', index => 0, indent => '', info => $info, newline => $newline, column => $self->column, } ]); } sub document_end_event { DEBUG and warn __PACKAGE__.':'.__LINE__.": +++ document_end_event\n"; my ($self, $info) = @_; $self->set_event_stack([]); if ($self->{open_ended} or not $info->{implicit}) { $self->_write("...\n"); $self->{open_ended} = 0; } else { $self->{open_ended} = 1; } } sub stream_start_event { } sub stream_end_event { } sub _emit_tag { my ($self, $type, $tag) = @_; my $map = $self->tagmap; for my $key (sort keys %$map) { if ($tag =~ m/^\Q$key\E(.*)/) { $tag = $map->{ $key } . $1; return $tag; } } if ($tag =~ m/^(!.*)/) { $tag = "$1"; } else { $tag = "!<$tag>"; } return $tag; } sub finish { my ($self) = @_; $self->writer->finish; } sub _write { my ($self, $yaml) = @_; return unless length $yaml; my @lines = split m/\n/, $yaml, -1; my $newlines = @lines - 1; $self->{line} += $newlines; if (length $lines[-1]) { if ($newlines) { $self->{column} = length $lines[-1]; } else { $self->{column} += length $lines[-1]; } } else { $self->{column} = 0; } $self->writer->write($yaml); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Emitter - Emitting events =head1 SYNOPSIS my $emitter = YAML::PP::Emitter->new( indent => 4, ); $emitter->init; $emitter->stream_start_event; $emitter->document_start_event({ implicit => 1 }); $emitter->sequence_start_event; $emitter->scalar_event({ value => $input, style => $style }); $emitter->sequence_end_event; $emitter->document_end_event({ implicit => 1 }); $emitter->stream_end_event; my $yaml = $emitter->writer->output; $emitter->finish; =head1 DESCRIPTION The emitter emits events to YAML. It provides methods for each event type. The arguments are mostly the same as the events from L<YAML::PP::Parser>. =head1 METHODS =over =item new my $emitter = YAML::PP::Emitter->new( indent => 4, ); Constructor. Currently takes these options: =over =item indent =item writer =back =item stream_start_event, stream_end_event, document_start_event, document_end_event, sequence_start_event, sequence_end_event, mapping_start_event, mapping_end_event, scalar_event, alias_event =item indent, set_indent Getter/setter for number of indentation spaces. TODO: Currently sequences are always zero-indented. =item writer, set_writer Getter/setter for the writer object. By default L<YAML::PP::Writer>. You can pass your own writer if you want to output the resulting YAML yourself. =item init Initialize =item finish =back =cut 07070100000033000081A40000000000000000000000016616D6BA00000783000000000000000000000000000000000000003E00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Exception.pmuse strict; use warnings; package YAML::PP::Exception; our $VERSION = '0.000'; # VERSION use overload '""' => \&to_string; sub new { my ($class, %args) = @_; my $self = bless { line => $args{line}, msg => $args{msg}, next => $args{next}, where => $args{where}, yaml => $args{yaml}, got => $args{got}, expected => $args{expected}, column => $args{column}, }, $class; return $self; } sub to_string { my ($self) = @_; my $next = $self->{next}; my $line = $self->{line}; my $column = $self->{column}; my $yaml = ''; for my $token (@$next) { last if $token->{name} eq 'EOL'; $yaml .= $token->{value}; } $column = '???' unless defined $column; my $remaining_yaml = $self->{yaml}; $remaining_yaml = '' unless defined $remaining_yaml; $yaml .= $remaining_yaml; { local $@; # avoid bug in old Data::Dumper require Data::Dumper; local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; $yaml = Data::Dumper->Dump([$yaml], ['yaml']); chomp $yaml; } my $lines = 5; my @fields; if ($self->{got} and $self->{expected}) { $lines = 6; $line = $self->{got}->{line}; $column = $self->{got}->{column} + 1; @fields = ( "Line" => $line, "Column" => $column, "Expected", join(" ", @{ $self->{expected} }), "Got", $self->{got}->{name}, "Where", $self->{where}, "YAML", $yaml, ); } else { @fields = ( "Line" => $line, "Column" => $column, "Message", $self->{msg}, "Where", $self->{where}, "YAML", $yaml, ); } my $fmt = join "\n", ("%-10s: %s") x $lines; my $string = sprintf $fmt, @fields; return $string; } 1; 07070100000034000081A40000000000000000000000016616D6BA0000BC43000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Grammar.pmuse strict; use warnings; package YAML::PP::Grammar; our $VERSION = '0.000'; # VERSION use base 'Exporter'; our @EXPORT_OK = qw/ $GRAMMAR /; our $GRAMMAR = {}; # START OF GRAMMAR INLINE # DO NOT CHANGE THIS # This grammar is automatically generated from etc/grammar.yaml $GRAMMAR = { 'DIRECTIVE' => { 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_doc_start_explicit' }, 'EOL' => { 'new' => 'DIRECTIVE' }, 'RESERVED_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_reserved_directive' }, 'TAG_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_tag_directive' }, 'YAML_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_set_yaml_version_directive' } }, 'DOCUMENT_END' => { 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document' }, 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_end_doc_start_document' }, 'EOL' => { 'new' => 'DOCUMENT_END' } }, 'END_FLOW' => { 'EOL' => { 'match' => 'cb_end_outer_flow', 'return' => 1 } }, 'FLOWMAP' => { 'ANCHOR' => { 'DEFAULT' => { 'new' => 'NEWFLOWMAP_ANCHOR' }, 'EOL' => { 'new' => 'NEWFLOWMAP_ANCHOR_SPC' }, 'WS' => { 'new' => 'NEWFLOWMAP_ANCHOR_SPC' }, 'match' => 'cb_anchor' }, 'COLON' => { 'EOL' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'DEFAULT' => { 'new' => 'FLOWMAP_CONTENT' }, 'EOL' => { 'new' => 'FLOWMAP' }, 'FLOWMAP_END' => { 'match' => 'cb_end_flowmap', 'return' => 1 }, 'TAG' => { 'DEFAULT' => { 'new' => 'NEWFLOWMAP_TAG' }, 'EOL' => { 'new' => 'NEWFLOWMAP_TAG_SPC' }, 'WS' => { 'new' => 'NEWFLOWMAP_TAG_SPC' }, 'match' => 'cb_tag' }, 'WS' => { 'new' => 'FLOWMAP' } }, 'FLOWMAP_CONTENT' => { 'ALIAS' => { 'match' => 'cb_send_alias', 'return' => 1 }, 'COLON' => { 'EOL' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'PLAIN' => { 'match' => 'cb_flowkey_plain', 'return' => 1 }, 'PLAIN_MULTI' => { 'match' => 'cb_send_plain_multi', 'return' => 1 }, 'QUOTED' => { 'match' => 'cb_flowkey_quoted', 'return' => 1 }, 'QUOTED_MULTILINE' => { 'match' => 'cb_quoted_multiline', 'return' => 1 } }, 'FLOWMAP_EMPTYKEY' => { 'FLOWMAP_END' => { 'match' => 'cb_end_empty_flowmap_key_value', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowmap_key_value', 'return' => 1 } }, 'FLOWMAP_EXPLICIT_KEY' => { 'DEFAULT' => { 'new' => 'FLOWMAP' }, 'EOL' => { 'new' => 'FLOWMAP_EXPLICIT_KEY' }, 'FLOWMAP_END' => { 'match' => 'cb_end_empty_flowmap_key_value', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowmap_key_value', 'return' => 1 }, 'WS' => { 'new' => 'FLOWMAP_EXPLICIT_KEY' } }, 'FLOWMAP_PROPS' => { 'COLON' => { 'EOL' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_empty_flow_mapkey', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'FLOWMAP_END' => { 'match' => 'cb_end_empty_flowmap_key_value', 'return' => 1 }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowmap_key_value', 'return' => 1 }, 'PLAIN' => { 'match' => 'cb_flowkey_plain', 'return' => 1 }, 'PLAIN_MULTI' => { 'match' => 'cb_send_plain_multi', 'return' => 1 }, 'QUOTED' => { 'match' => 'cb_flowkey_quoted', 'return' => 1 }, 'QUOTED_MULTILINE' => { 'match' => 'cb_quoted_multiline', 'return' => 1 } }, 'FLOWSEQ' => { 'ALIAS' => { 'match' => 'cb_send_flow_alias', 'new' => 'FLOWSEQ_NEXT' }, 'COLON' => { 'EOL' => { 'match' => 'cb_insert_empty_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_insert_empty_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'PLAIN' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_MAYBE_KEY' }, 'EOL' => { 'match' => 'cb_send_scalar', 'new' => 'FLOWSEQ_NEXT' }, 'match' => 'cb_start_plain' }, 'PLAIN_MULTI' => { 'match' => 'cb_send_plain_multi', 'new' => 'FLOWSEQ_NEXT' }, 'QUOTED' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_MAYBE_KEY' }, 'EOL' => { 'match' => 'cb_send_scalar', 'new' => 'FLOWSEQ_NEXT' }, 'match' => 'cb_take_quoted' }, 'QUOTED_MULTILINE' => { 'match' => 'cb_quoted_multiline', 'new' => 'FLOWSEQ_NEXT' } }, 'FLOWSEQ_EMPTY' => { 'FLOWSEQ_END' => { 'match' => 'cb_empty_flowseq_end', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowseq_comma', 'return' => 1 } }, 'FLOWSEQ_MAYBE_KEY' => { 'COLON' => { 'DEFAULT' => { 'match' => 'cb_insert_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' }, 'EOL' => { 'match' => 'cb_insert_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_insert_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'DEFAULT' => { 'new' => 'FLOWSEQ_NEXT' }, 'WS' => { 'new' => 'FLOWSEQ_MAYBE_KEY' } }, 'FLOWSEQ_NEXT' => { 'EOL' => { 'new' => 'FLOWSEQ_NEXT' }, 'FLOWSEQ_END' => { 'match' => 'cb_end_flowseq', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_flow_comma', 'return' => 1 }, 'WS' => { 'new' => 'FLOWSEQ_NEXT' } }, 'FLOWSEQ_PROPS' => { 'COLON' => { 'EOL' => { 'match' => 'cb_insert_empty_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'match' => 'cb_insert_empty_implicit_flowseq_map', 'new' => 'RULE_FULLFLOWSCALAR' } }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_END' => { 'match' => 'cb_empty_flowseq_end', 'return' => 1 }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowseq_comma', 'return' => 1 }, 'PLAIN' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_MAYBE_KEY' }, 'EOL' => { 'match' => 'cb_send_scalar', 'new' => 'FLOWSEQ_NEXT' }, 'match' => 'cb_start_plain' }, 'PLAIN_MULTI' => { 'match' => 'cb_send_plain_multi', 'new' => 'FLOWSEQ_NEXT' }, 'QUOTED' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_MAYBE_KEY' }, 'EOL' => { 'match' => 'cb_send_scalar', 'new' => 'FLOWSEQ_NEXT' }, 'match' => 'cb_take_quoted' }, 'QUOTED_MULTILINE' => { 'match' => 'cb_quoted_multiline', 'new' => 'FLOWSEQ_NEXT' } }, 'FULLMAPVALUE_INLINE' => { 'ANCHOR' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_ANCHOR' }, 'WS' => { 'DEFAULT' => { 'new' => 'NODETYPE_MAPVALUE_INLINE' }, 'TAG' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'new' => 'NODETYPE_MAPVALUE_INLINE' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_MAPVALUE_INLINE' }, 'TAG' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG' }, 'WS' => { 'ANCHOR' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'new' => 'NODETYPE_MAPVALUE_INLINE' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_MAPVALUE_INLINE' } }, 'match' => 'cb_tag' } }, 'FULLNODE' => { 'ANCHOR' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_ANCHOR' }, 'WS' => { 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'TAG' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_NODE' }, 'EOL' => { 'new' => 'FULLNODE' }, 'TAG' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG' }, 'WS' => { 'ANCHOR' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' } }, 'match' => 'cb_tag' } }, 'FULLNODE_ANCHOR' => { 'ANCHOR' => { 'WS' => { 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'TAG' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_NODE' }, 'EOL' => { 'new' => 'FULLNODE_ANCHOR' }, 'TAG' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'ANCHOR' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' } }, 'match' => 'cb_tag' } }, 'FULLNODE_TAG' => { 'ANCHOR' => { 'EOL' => { 'match' => 'cb_property_eol', 'new' => 'FULLNODE_TAG_ANCHOR' }, 'WS' => { 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'TAG' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_NODE' }, 'EOL' => { 'new' => 'FULLNODE_TAG' }, 'TAG' => { 'WS' => { 'ANCHOR' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' } }, 'match' => 'cb_tag' } }, 'FULLNODE_TAG_ANCHOR' => { 'ANCHOR' => { 'WS' => { 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'TAG' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_NODE' }, 'EOL' => { 'new' => 'FULLNODE_TAG_ANCHOR' }, 'TAG' => { 'WS' => { 'ANCHOR' => { 'WS' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' } }, 'match' => 'cb_tag' } }, 'NEWFLOWMAP' => { 'DEFAULT' => { 'new' => 'FLOWMAP' }, 'EOL' => { 'new' => 'NEWFLOWMAP' }, 'QUESTION' => { 'match' => 'cb_flow_question', 'new' => 'FLOWMAP_EXPLICIT_KEY' }, 'WS' => { 'new' => 'NEWFLOWMAP' } }, 'NEWFLOWMAP_ANCHOR' => { 'DEFAULT' => { 'new' => 'FLOWMAP_EMPTYKEY' } }, 'NEWFLOWMAP_ANCHOR_SPC' => { 'DEFAULT' => { 'new' => 'FLOWMAP_PROPS' }, 'EOL' => { 'new' => 'NEWFLOWMAP_ANCHOR_SPC' }, 'TAG' => { 'DEFAULT' => { 'new' => 'FLOWMAP_EMPTYKEY' }, 'EOL' => { 'new' => 'FLOWMAP_PROPS' }, 'WS' => { 'new' => 'FLOWMAP_PROPS' }, 'match' => 'cb_tag' }, 'WS' => { 'new' => 'NEWFLOWMAP_ANCHOR_SPC' } }, 'NEWFLOWMAP_TAG' => { 'DEFAULT' => { 'new' => 'FLOWMAP_EMPTYKEY' } }, 'NEWFLOWMAP_TAG_SPC' => { 'ANCHOR' => { 'DEFAULT' => { 'new' => 'FLOWMAP_EMPTYKEY' }, 'EOL' => { 'new' => 'FLOWMAP_PROPS' }, 'WS' => { 'new' => 'FLOWMAP_PROPS' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'FLOWMAP_PROPS' }, 'EOL' => { 'new' => 'NEWFLOWMAP_TAG_SPC' }, 'WS' => { 'new' => 'NEWFLOWMAP_TAG_SPC' } }, 'NEWFLOWSEQ' => { 'ANCHOR' => { 'DEFAULT' => { 'new' => 'NEWFLOWSEQ_ANCHOR' }, 'EOL' => { 'new' => 'NEWFLOWSEQ_ANCHOR_SPC' }, 'WS' => { 'new' => 'NEWFLOWSEQ_ANCHOR_SPC' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'FLOWSEQ' }, 'EOL' => { 'new' => 'NEWFLOWSEQ' }, 'FLOWSEQ_END' => { 'match' => 'cb_end_flowseq', 'return' => 1 }, 'TAG' => { 'DEFAULT' => { 'new' => 'NEWFLOWSEQ_TAG' }, 'EOL' => { 'new' => 'NEWFLOWSEQ_TAG_SPC' }, 'WS' => { 'new' => 'NEWFLOWSEQ_TAG_SPC' }, 'match' => 'cb_tag' }, 'WS' => { 'new' => 'NEWFLOWSEQ' } }, 'NEWFLOWSEQ_ANCHOR' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_EMPTY' } }, 'NEWFLOWSEQ_ANCHOR_SPC' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_PROPS' }, 'EOL' => { 'new' => 'NEWFLOWSEQ_ANCHOR_SPC' }, 'TAG' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_EMPTY' }, 'EOL' => { 'new' => 'FLOWSEQ_PROPS' }, 'WS' => { 'new' => 'FLOWSEQ_PROPS' }, 'match' => 'cb_tag' }, 'WS' => { 'new' => 'NEWFLOWSEQ_ANCHOR_SPC' } }, 'NEWFLOWSEQ_TAG' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_EMPTY' } }, 'NEWFLOWSEQ_TAG_SPC' => { 'ANCHOR' => { 'DEFAULT' => { 'new' => 'FLOWSEQ_EMPTY' }, 'EOL' => { 'new' => 'FLOWSEQ_PROPS' }, 'WS' => { 'new' => 'FLOWSEQ_PROPS' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'FLOWSEQ_PROPS' }, 'EOL' => { 'new' => 'NEWFLOWSEQ_TAG_SPC' }, 'WS' => { 'new' => 'NEWFLOWSEQ_TAG_SPC' } }, 'NODETYPE_COMPLEX' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_complexcolon' }, 'DEFAULT' => { 'match' => 'cb_empty_complexvalue', 'new' => 'NODETYPE_MAP' }, 'EOL' => { 'new' => 'NODETYPE_COMPLEX' } }, 'NODETYPE_FLOWMAP' => { 'DEFAULT' => { 'new' => 'NEWFLOWMAP' }, 'EOL' => { 'new' => 'NODETYPE_FLOWMAP' }, 'FLOWMAP_END' => { 'match' => 'cb_end_flowmap', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_flow_comma', 'new' => 'NEWFLOWMAP' }, 'WS' => { 'new' => 'NODETYPE_FLOWMAP' } }, 'NODETYPE_FLOWMAPVALUE' => { 'COLON' => { 'DEFAULT' => { 'new' => 'RULE_FULLFLOWSCALAR' }, 'EOL' => { 'new' => 'RULE_FULLFLOWSCALAR' }, 'WS' => { 'new' => 'RULE_FULLFLOWSCALAR' }, 'match' => 'cb_flow_colon' }, 'EOL' => { 'new' => 'NODETYPE_FLOWMAPVALUE' }, 'FLOWMAP_END' => { 'match' => 'cb_end_flowmap_empty', 'return' => 1 }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flowmap_value', 'return' => 1 }, 'WS' => { 'new' => 'NODETYPE_FLOWMAPVALUE' } }, 'NODETYPE_FLOWSEQ' => { 'DEFAULT' => { 'new' => 'NEWFLOWSEQ' }, 'EOL' => { 'new' => 'NODETYPE_FLOWSEQ' }, 'FLOWSEQ_END' => { 'match' => 'cb_end_flowseq', 'return' => 1 }, 'WS' => { 'new' => 'NODETYPE_FLOWSEQ' } }, 'NODETYPE_MAP' => { 'ANCHOR' => { 'WS' => { 'DEFAULT' => { 'new' => 'RULE_MAPKEY' }, 'TAG' => { 'WS' => { 'new' => 'RULE_MAPKEY' }, 'match' => 'cb_tag' } }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'RULE_MAPKEY' }, 'TAG' => { 'WS' => { 'ANCHOR' => { 'WS' => { 'new' => 'RULE_MAPKEY' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'RULE_MAPKEY' } }, 'match' => 'cb_tag' } }, 'NODETYPE_MAPVALUE_INLINE' => { 'ALIAS' => { 'EOL' => {}, 'match' => 'cb_send_alias' }, 'BLOCK_SCALAR' => { 'EOL' => {}, 'match' => 'cb_send_block_scalar' }, 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document' }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'PLAIN' => { 'EOL' => { 'match' => 'cb_send_scalar' }, 'match' => 'cb_start_plain' }, 'PLAIN_MULTI' => { 'EOL' => {}, 'match' => 'cb_send_plain_multi' }, 'QUOTED' => { 'EOL' => { 'match' => 'cb_send_scalar' }, 'match' => 'cb_take_quoted' }, 'QUOTED_MULTILINE' => { 'EOL' => {}, 'match' => 'cb_quoted_multiline' } }, 'NODETYPE_NODE' => { 'DASH' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_seqstart' }, 'DEFAULT' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' } }, 'NODETYPE_SCALAR_OR_MAP' => { 'ALIAS' => { 'EOL' => { 'match' => 'cb_send_alias_from_stack' }, 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_map_alias' } }, 'match' => 'cb_alias' }, 'BLOCK_SCALAR' => { 'EOL' => {}, 'match' => 'cb_send_block_scalar' }, 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_empty_map' }, 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document' }, 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_end_doc_start_document' }, 'EOL' => { 'new' => 'NODETYPE_SCALAR_OR_MAP' }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'PLAIN' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_map' }, 'EOL' => { 'match' => 'cb_send_scalar' }, 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_map' } }, 'match' => 'cb_start_plain' }, 'PLAIN_MULTI' => { 'EOL' => {}, 'match' => 'cb_send_plain_multi' }, 'QUESTION' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_questionstart' }, 'QUOTED' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_map' }, 'EOL' => { 'match' => 'cb_send_scalar' }, 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_insert_map' } }, 'match' => 'cb_take_quoted' }, 'QUOTED_MULTILINE' => { 'EOL' => {}, 'match' => 'cb_quoted_multiline' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' } }, 'NODETYPE_SEQ' => { 'DASH' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_seqitem' }, 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document' }, 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_end_doc_start_document' }, 'EOL' => { 'new' => 'NODETYPE_SEQ' } }, 'RULE_FLOWSCALAR' => { 'ALIAS' => { 'match' => 'cb_send_alias', 'return' => 1 }, 'FLOWMAP_END' => { 'match' => 'cb_end_flowmap_empty', 'return' => 1 }, 'FLOWMAP_START' => { 'match' => 'cb_start_flowmap', 'new' => 'NEWFLOWMAP' }, 'FLOWSEQ_START' => { 'match' => 'cb_start_flowseq', 'new' => 'NEWFLOWSEQ' }, 'FLOW_COMMA' => { 'match' => 'cb_empty_flow_mapkey', 'return' => 1 }, 'PLAIN' => { 'DEFAULT' => { 'match' => 'cb_send_scalar', 'return' => 1 }, 'EOL' => { 'match' => 'cb_send_scalar' }, 'match' => 'cb_start_plain' }, 'PLAIN_MULTI' => { 'match' => 'cb_send_plain_multi', 'return' => 1 }, 'QUOTED' => { 'DEFAULT' => { 'match' => 'cb_send_scalar', 'return' => 1 }, 'EOL' => { 'match' => 'cb_send_scalar' }, 'WS' => { 'match' => 'cb_send_scalar', 'return' => 1 }, 'match' => 'cb_take_quoted' }, 'QUOTED_MULTILINE' => { 'match' => 'cb_quoted_multiline', 'return' => 1 } }, 'RULE_FULLFLOWSCALAR' => { 'ANCHOR' => { 'DEFAULT' => { 'new' => 'RULE_FULLFLOWSCALAR_ANCHOR' }, 'EOL' => { 'new' => 'RULE_FULLFLOWSCALAR_ANCHOR' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'RULE_FLOWSCALAR' }, 'TAG' => { 'DEFAULT' => { 'new' => 'RULE_FULLFLOWSCALAR_TAG' }, 'EOL' => { 'new' => 'RULE_FULLFLOWSCALAR_TAG' }, 'match' => 'cb_tag' } }, 'RULE_FULLFLOWSCALAR_ANCHOR' => { 'DEFAULT' => { 'new' => 'RULE_FLOWSCALAR' }, 'TAG' => { 'EOL' => { 'new' => 'RULE_FLOWSCALAR' }, 'WS' => { 'new' => 'RULE_FLOWSCALAR' }, 'match' => 'cb_tag' }, 'WS' => { 'new' => 'RULE_FULLFLOWSCALAR_ANCHOR' } }, 'RULE_FULLFLOWSCALAR_TAG' => { 'ANCHOR' => { 'EOL' => { 'new' => 'RULE_FLOWSCALAR' }, 'WS' => { 'new' => 'RULE_FLOWSCALAR' }, 'match' => 'cb_anchor' }, 'DEFAULT' => { 'new' => 'RULE_FLOWSCALAR' }, 'WS' => { 'new' => 'RULE_FULLFLOWSCALAR_TAG' } }, 'RULE_MAPKEY' => { 'ALIAS' => { 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' } } }, 'match' => 'cb_send_alias_key' }, 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_empty_mapkey' }, 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document' }, 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_end_doc_start_document' }, 'EOL' => { 'new' => 'RULE_MAPKEY' }, 'PLAIN' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_send_mapkey' }, 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' }, 'match' => 'cb_send_mapkey' } }, 'match' => 'cb_mapkey' }, 'QUESTION' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_question' }, 'QUOTED' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' } }, 'WS' => { 'COLON' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLMAPVALUE_INLINE' } } }, 'match' => 'cb_take_quoted_key' } }, 'STREAM' => { 'DEFAULT' => { 'match' => 'cb_doc_start_implicit', 'new' => 'FULLNODE' }, 'DOC_END' => { 'EOL' => {}, 'match' => 'cb_end_document_empty' }, 'DOC_START' => { 'EOL' => { 'new' => 'FULLNODE' }, 'WS' => { 'new' => 'FULLNODE' }, 'match' => 'cb_doc_start_explicit' }, 'EOL' => { 'new' => 'STREAM' }, 'RESERVED_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_reserved_directive' }, 'TAG_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_tag_directive' }, 'YAML_DIRECTIVE' => { 'EOL' => { 'new' => 'DIRECTIVE' }, 'WS' => { 'new' => 'DIRECTIVE' }, 'match' => 'cb_set_yaml_version_directive' } } }; # END OF GRAMMAR INLINE 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Grammar - YAML grammar =head1 GRAMMAR This is the Grammar in YAML # START OF YAML INLINE # DO NOT CHANGE THIS # This grammar is automatically generated from etc/grammar.yaml --- NODETYPE_NODE: DASH: match: cb_seqstart EOL: { new: FULLNODE } WS: { new: FULLNODE } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } NODETYPE_SCALAR_OR_MAP: # Flow nodes can follow tabs WS: { new: FULLMAPVALUE_INLINE } ALIAS: match: cb_alias EOL: { match: cb_send_alias_from_stack } WS: COLON: match: cb_insert_map_alias EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUESTION: match: cb_questionstart EOL: { new: FULLNODE } WS: { new: FULLNODE } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } WS: COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUOTED_MULTILINE: match: cb_quoted_multiline EOL: { } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar WS: COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_insert_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } PLAIN_MULTI: match: cb_send_plain_multi EOL: { } COLON: match: cb_insert_empty_map EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } BLOCK_SCALAR: match: cb_send_block_scalar EOL: { } FLOWSEQ_START: match: cb_start_flowseq new: NEWFLOWSEQ FLOWMAP_START: match: cb_start_flowmap new: NEWFLOWMAP DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: NODETYPE_SCALAR_OR_MAP NODETYPE_COMPLEX: COLON: match: cb_complexcolon EOL: { new: FULLNODE } WS: { new: FULLNODE } DEFAULT: match: cb_empty_complexvalue new: NODETYPE_MAP EOL: new: NODETYPE_COMPLEX RULE_FULLFLOWSCALAR: ANCHOR: match: cb_anchor EOL: { new: RULE_FULLFLOWSCALAR_ANCHOR } DEFAULT: { new: RULE_FULLFLOWSCALAR_ANCHOR } TAG: match: cb_tag EOL: { new: RULE_FULLFLOWSCALAR_TAG } DEFAULT: { new: RULE_FULLFLOWSCALAR_TAG } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FULLFLOWSCALAR_ANCHOR: WS: { new: RULE_FULLFLOWSCALAR_ANCHOR } TAG: match: cb_tag WS: { new: RULE_FLOWSCALAR } EOL: { new: RULE_FLOWSCALAR } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FULLFLOWSCALAR_TAG: WS: { new: RULE_FULLFLOWSCALAR_TAG } ANCHOR: match: cb_anchor WS: { new: RULE_FLOWSCALAR } EOL: { new: RULE_FLOWSCALAR } DEFAULT: { new: RULE_FLOWSCALAR } RULE_FLOWSCALAR: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_alias, return: 1 } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } WS: { match: cb_send_scalar, return: 1 } DEFAULT: { match: cb_send_scalar, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } PLAIN: match: cb_start_plain EOL: { match: cb_send_scalar } DEFAULT: { match: cb_send_scalar, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } FLOW_COMMA: { match: cb_empty_flow_mapkey, return: 1 } FLOWMAP_END: match: cb_end_flowmap_empty return: 1 FLOWSEQ: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_flow_alias, new: FLOWSEQ_NEXT } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY PLAIN_MULTI: { match: cb_send_plain_multi, new: FLOWSEQ_NEXT } QUOTED: match: cb_take_quoted EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY QUOTED_MULTILINE: { match: cb_quoted_multiline, new: FLOWSEQ_NEXT } COLON: WS: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR FLOWSEQ_PROPS: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY PLAIN_MULTI: { match: cb_send_plain_multi, new: FLOWSEQ_NEXT } QUOTED: match: cb_take_quoted EOL: match: cb_send_scalar new: FLOWSEQ_NEXT DEFAULT: new: FLOWSEQ_MAYBE_KEY QUOTED_MULTILINE: { match: cb_quoted_multiline, new: FLOWSEQ_NEXT } FLOW_COMMA: match: cb_empty_flowseq_comma return: 1 FLOWSEQ_END: match: cb_empty_flowseq_end return: 1 COLON: WS: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_empty_implicit_flowseq_map new: RULE_FULLFLOWSCALAR FLOWSEQ_EMPTY: FLOW_COMMA: match: cb_empty_flowseq_comma return: 1 FLOWSEQ_END: match: cb_empty_flowseq_end return: 1 FLOWSEQ_NEXT: WS: { new: FLOWSEQ_NEXT } EOL: { new: FLOWSEQ_NEXT } FLOW_COMMA: match: cb_flow_comma return: 1 FLOWSEQ_END: match: cb_end_flowseq return: 1 FLOWSEQ_MAYBE_KEY: WS: { new: FLOWSEQ_MAYBE_KEY } COLON: WS: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR EOL: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR DEFAULT: match: cb_insert_implicit_flowseq_map new: RULE_FULLFLOWSCALAR DEFAULT: new: FLOWSEQ_NEXT FLOWMAP_CONTENT: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } ALIAS: { match: cb_send_alias, return: 1 } PLAIN: { match: cb_flowkey_plain, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } QUOTED: { match: cb_flowkey_quoted, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR FLOWMAP_PROPS: FLOWSEQ_START: { match: cb_start_flowseq, new: NEWFLOWSEQ } FLOWMAP_START: { match: cb_start_flowmap, new: NEWFLOWMAP } PLAIN: { match: cb_flowkey_plain, return: 1 } PLAIN_MULTI: { match: cb_send_plain_multi, return: 1 } QUOTED: { match: cb_flowkey_quoted, return: 1 } QUOTED_MULTILINE: { match: cb_quoted_multiline, return: 1 } COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 FLOWMAP_EMPTYKEY: FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 NEWFLOWSEQ: EOL: { new: NEWFLOWSEQ } WS: { new: NEWFLOWSEQ } ANCHOR: match: cb_anchor WS: { new: NEWFLOWSEQ_ANCHOR_SPC } EOL: { new: NEWFLOWSEQ_ANCHOR_SPC } DEFAULT: { new: NEWFLOWSEQ_ANCHOR } TAG: match: cb_tag WS: { new: NEWFLOWSEQ_TAG_SPC } EOL: { new: NEWFLOWSEQ_TAG_SPC } DEFAULT: { new: NEWFLOWSEQ_TAG } FLOWSEQ_END: match: cb_end_flowseq return: 1 DEFAULT: { new: FLOWSEQ } NODETYPE_FLOWSEQ: EOL: { new: NODETYPE_FLOWSEQ } WS: { new: NODETYPE_FLOWSEQ } FLOWSEQ_END: match: cb_end_flowseq return: 1 DEFAULT: { new: NEWFLOWSEQ } NODETYPE_FLOWMAPVALUE: WS: { new: NODETYPE_FLOWMAPVALUE } EOL: { new: NODETYPE_FLOWMAPVALUE } COLON: match: cb_flow_colon WS: { new: RULE_FULLFLOWSCALAR } EOL: { new: RULE_FULLFLOWSCALAR } DEFAULT: { new: RULE_FULLFLOWSCALAR } FLOW_COMMA: match: cb_empty_flowmap_value return: 1 FLOWMAP_END: match: cb_end_flowmap_empty return: 1 NEWFLOWSEQ_ANCHOR: DEFAULT: { new: FLOWSEQ_EMPTY } NEWFLOWSEQ_TAG: DEFAULT: { new: FLOWSEQ_EMPTY } NEWFLOWSEQ_ANCHOR_SPC: WS: { new: NEWFLOWSEQ_ANCHOR_SPC } EOL: { new: NEWFLOWSEQ_ANCHOR_SPC } TAG: match: cb_tag WS: { new: FLOWSEQ_PROPS } EOL: { new: FLOWSEQ_PROPS } DEFAULT: { new: FLOWSEQ_EMPTY } DEFAULT: { new: FLOWSEQ_PROPS } NEWFLOWSEQ_TAG_SPC: WS: { new: NEWFLOWSEQ_TAG_SPC } EOL: { new: NEWFLOWSEQ_TAG_SPC } ANCHOR: match: cb_anchor WS: { new: FLOWSEQ_PROPS } EOL: { new: FLOWSEQ_PROPS } DEFAULT: { new: FLOWSEQ_EMPTY } DEFAULT: { new: FLOWSEQ_PROPS } NEWFLOWMAP_ANCHOR: DEFAULT: { new: FLOWMAP_EMPTYKEY } NEWFLOWMAP_TAG: DEFAULT: { new: FLOWMAP_EMPTYKEY } NEWFLOWMAP_ANCHOR_SPC: WS: { new: NEWFLOWMAP_ANCHOR_SPC } EOL: { new: NEWFLOWMAP_ANCHOR_SPC } TAG: match: cb_tag WS: { new: FLOWMAP_PROPS } EOL: { new: FLOWMAP_PROPS } DEFAULT: { new: FLOWMAP_EMPTYKEY } DEFAULT: { new: FLOWMAP_PROPS } NEWFLOWMAP_TAG_SPC: WS: { new: NEWFLOWMAP_TAG_SPC } EOL: { new: NEWFLOWMAP_TAG_SPC } ANCHOR: match: cb_anchor WS: { new: FLOWMAP_PROPS } EOL: { new: FLOWMAP_PROPS } DEFAULT: { new: FLOWMAP_EMPTYKEY } DEFAULT: { new: FLOWMAP_PROPS } NEWFLOWMAP: EOL: { new: NEWFLOWMAP } WS: { new: NEWFLOWMAP } QUESTION: { match: cb_flow_question, new: FLOWMAP_EXPLICIT_KEY } DEFAULT: { new: FLOWMAP } FLOWMAP_EXPLICIT_KEY: WS: { new: FLOWMAP_EXPLICIT_KEY } EOL: { new: FLOWMAP_EXPLICIT_KEY } FLOWMAP_END: match: cb_end_empty_flowmap_key_value return: 1 FLOW_COMMA: match: cb_empty_flowmap_key_value return: 1 DEFAULT: { new: FLOWMAP } FLOWMAP: EOL: { new: FLOWMAP } WS: { new: FLOWMAP } ANCHOR: match: cb_anchor WS: { new: NEWFLOWMAP_ANCHOR_SPC } EOL: { new: NEWFLOWMAP_ANCHOR_SPC } DEFAULT: { new: NEWFLOWMAP_ANCHOR } TAG: match: cb_tag WS: { new: NEWFLOWMAP_TAG_SPC } EOL: { new: NEWFLOWMAP_TAG_SPC } DEFAULT: { new: NEWFLOWMAP_TAG } FLOWMAP_END: match: cb_end_flowmap return: 1 COLON: WS: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR EOL: match: cb_empty_flow_mapkey new: RULE_FULLFLOWSCALAR DEFAULT: { new: FLOWMAP_CONTENT } NODETYPE_FLOWMAP: EOL: { new: NODETYPE_FLOWMAP } WS: { new: NODETYPE_FLOWMAP } FLOWMAP_END: match: cb_end_flowmap return: 1 FLOW_COMMA: { match: cb_flow_comma, new: NEWFLOWMAP } DEFAULT: { new: NEWFLOWMAP } END_FLOW: EOL: match: cb_end_outer_flow return: 1 RULE_MAPKEY: QUESTION: match: cb_question EOL: { new: FULLNODE } WS: { new: FULLNODE } ALIAS: match: cb_send_alias_key WS: COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } QUOTED: match: cb_take_quoted_key WS: COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } PLAIN: match: cb_mapkey WS: COLON: match: cb_send_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_send_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } COLON: match: cb_empty_mapkey EOL: { new: FULLNODE } WS: { new: FULLMAPVALUE_INLINE } DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: RULE_MAPKEY NODETYPE_SEQ: DASH: match: cb_seqitem EOL: { new: FULLNODE } WS: { new: FULLNODE } DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: NODETYPE_SEQ NODETYPE_MAP: ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } DEFAULT: { new: RULE_MAPKEY } FULLNODE_ANCHOR: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_ANCHOR } DEFAULT: { new: NODETYPE_NODE } FULLNODE_TAG: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP, } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_TAG } DEFAULT: { new: NODETYPE_NODE } FULLNODE_TAG_ANCHOR: ANCHOR: match: cb_anchor WS: TAG: match: cb_tag WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } TAG: match: cb_tag WS: ANCHOR: match: cb_anchor WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE_TAG_ANCHOR } DEFAULT: { new: NODETYPE_NODE } FULLNODE: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_ANCHOR } WS: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG } WS: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_SCALAR_OR_MAP } DEFAULT: { new: NODETYPE_SCALAR_OR_MAP } EOL: { new: FULLNODE } DEFAULT: { new: NODETYPE_NODE } FULLMAPVALUE_INLINE: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_ANCHOR } WS: TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } TAG: match: cb_tag EOL: { match: cb_property_eol, new: FULLNODE_TAG } WS: ANCHOR: match: cb_anchor EOL: { match: cb_property_eol, new: FULLNODE_TAG_ANCHOR } WS: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } DEFAULT: { new: NODETYPE_MAPVALUE_INLINE } NODETYPE_MAPVALUE_INLINE: ALIAS: match: cb_send_alias EOL: { } QUOTED: match: cb_take_quoted EOL: { match: cb_send_scalar } QUOTED_MULTILINE: match: cb_quoted_multiline EOL: { } PLAIN: match: cb_start_plain EOL: match: cb_send_scalar PLAIN_MULTI: match: cb_send_plain_multi EOL: { } BLOCK_SCALAR: match: cb_send_block_scalar EOL: { } FLOWSEQ_START: match: cb_start_flowseq new: NEWFLOWSEQ FLOWMAP_START: match: cb_start_flowmap new: NEWFLOWMAP DOC_END: match: cb_end_document EOL: { } DOCUMENT_END: DOC_END: match: cb_end_document EOL: { } DOC_START: match: cb_end_doc_start_document EOL: { new: FULLNODE } WS: { new: FULLNODE } EOL: new: DOCUMENT_END STREAM: DOC_END: match: cb_end_document_empty EOL: { } DOC_START: match: cb_doc_start_explicit EOL: { new: FULLNODE } WS: { new: FULLNODE } YAML_DIRECTIVE: match: cb_set_yaml_version_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } RESERVED_DIRECTIVE: match: cb_reserved_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } TAG_DIRECTIVE: match: cb_tag_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } EOL: new: STREAM DEFAULT: match: cb_doc_start_implicit new: FULLNODE DIRECTIVE: DOC_START: match: cb_doc_start_explicit EOL: { new: FULLNODE } WS: { new: FULLNODE } YAML_DIRECTIVE: match: cb_set_yaml_version_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } RESERVED_DIRECTIVE: match: cb_reserved_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } TAG_DIRECTIVE: match: cb_tag_directive EOL: { new: DIRECTIVE } WS: { new: DIRECTIVE } EOL: new: DIRECTIVE # END OF YAML INLINE =cut 07070100000035000081A40000000000000000000000016616D6BA000018A3000000000000000000000000000000000000003E00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Highlight.pmuse strict; use warnings; package YAML::PP::Highlight; our $VERSION = '0.000'; # VERSION our @EXPORT_OK = qw/ Dump /; use base 'Exporter'; use YAML::PP; use YAML::PP::Parser; use Encode; sub Dump { my (@docs) = @_; # Dumping objects is safe, so we enable the Perl schema here require YAML::PP::Schema::Perl; my $yp = YAML::PP->new( schema => [qw/ + Perl /] ); my $yaml = $yp->dump_string(@docs); my ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens(string => $yaml); my $highlighted = YAML::PP::Highlight->ansicolored($tokens); encode_utf8 $highlighted; } my %ansicolors = ( ANCHOR => [qw/ green /], ALIAS => [qw/ bold green /], TAG => [qw/ bold blue /], INDENT => [qw/ white on_grey3 /], COMMENT => [qw/ grey12 /], COLON => [qw/ bold magenta /], DASH => [qw/ bold magenta /], QUESTION => [qw/ bold magenta /], YAML_DIRECTIVE => [qw/ cyan /], TAG_DIRECTIVE => [qw/ bold cyan /], SINGLEQUOTE => [qw/ bold green /], SINGLEQUOTED => [qw/ green /], SINGLEQUOTED_LINE => [qw/ green /], DOUBLEQUOTE => [qw/ bold green /], DOUBLEQUOTED => [qw/ green /], DOUBLEQUOTED_LINE => [qw/ green /], LITERAL => [qw/ bold yellow /], FOLDED => [qw/ bold yellow /], DOC_START => [qw/ bold /], DOC_END => [qw/ bold /], BLOCK_SCALAR_CONTENT => [qw/ yellow /], TAB => [qw/ on_blue /], ERROR => [qw/ bold red /], EOL => [qw/ grey12 /], TRAILING_SPACE => [qw/ on_grey6 /], FLOWSEQ_START => [qw/ bold magenta /], FLOWSEQ_END => [qw/ bold magenta /], FLOWMAP_START => [qw/ bold magenta /], FLOWMAP_END => [qw/ bold magenta /], FLOW_COMMA => [qw/ bold magenta /], PLAINKEY => [qw/ bright_blue /], ); sub ansicolored { my ($class, $tokens, %args) = @_; my $expand_tabs = $args{expand_tabs}; $expand_tabs = 1 unless defined $expand_tabs; require Term::ANSIColor; local $Term::ANSIColor::EACHLINE = "\n"; my $ansi = ''; my $highlighted = ''; my @list = $class->transform($tokens); for my $token (@list) { my $name = $token->{name}; my $str = $token->{value}; my $color = $ansicolors{ $name }; if ($color) { $str = Term::ANSIColor::colored($color, $str); } $highlighted .= $str; } if ($expand_tabs) { # Tabs can't be displayed with ansicolors $highlighted =~ s/\t/' ' x 8/eg; } $ansi .= $highlighted; return $ansi; } my %htmlcolors = ( ANCHOR => 'anchor', ALIAS => 'alias', SINGLEQUOTE => 'singlequote', DOUBLEQUOTE => 'doublequote', SINGLEQUOTED => 'singlequoted', DOUBLEQUOTED => 'doublequoted', SINGLEQUOTED_LINE => 'singlequoted', DOUBLEQUOTED_LINE => 'doublequoted', INDENT => 'indent', DASH => 'dash', COLON => 'colon', QUESTION => 'question', YAML_DIRECTIVE => 'yaml_directive', TAG_DIRECTIVE => 'tag_directive', TAG => 'tag', COMMENT => 'comment', LITERAL => 'literal', FOLDED => 'folded', DOC_START => 'doc_start', DOC_END => 'doc_end', BLOCK_SCALAR_CONTENT => 'block_scalar_content', TAB => 'tab', ERROR => 'error', EOL => 'eol', TRAILING_SPACE => 'trailing_space', FLOWSEQ_START => 'flowseq_start', FLOWSEQ_END => 'flowseq_end', FLOWMAP_START => 'flowmap_start', FLOWMAP_END => 'flowmap_end', FLOW_COMMA => 'flow_comma', PLAINKEY => 'plainkey', NOEOL => 'noeol', ); sub htmlcolored { require HTML::Entities; my ($class, $tokens) = @_; my $html = ''; my @list = $class->transform($tokens); for my $token (@list) { my $name = $token->{name}; my $str = $token->{value}; my $colorclass = $htmlcolors{ $name } || 'default'; $str = HTML::Entities::encode_entities($str); $html .= qq{<span class="$colorclass">$str</span>}; } return $html; } sub transform { my ($class, $tokens) = @_; my @list; for my $token (@$tokens) { my @values; my $value = $token->{value}; my $subtokens = $token->{subtokens}; if ($subtokens) { @values = @$subtokens; } else { @values = $token; } for my $token (@values) { my $value = defined $token->{orig} ? $token->{orig} : $token->{value}; if ($token->{name} eq 'EOL' and not length $value) { push @list, { name => 'NOEOL', value => '' }; next; } push @list, map { $_ =~ tr/\t/\t/ ? { name => 'TAB', value => $_ } : { name => $token->{name}, value => $_ } } split m/(\t+)/, $value; } } for my $i (0 .. $#list) { my $token = $list[ $i ]; my $name = $token->{name}; my $str = $token->{value}; my $trailing_space = 0; if ($token->{name} eq 'EOL') { if ($str =~ m/ +([\r\n]|\z)/) { $token->{name} = "TRAILING_SPACE"; } } elsif ($i < $#list) { if ($name eq 'PLAIN') { for my $n ($i+1 .. $#list) { my $next = $list[ $n ]; last if $next->{name} eq 'EOL'; next if $next->{name} =~ m/^(WS|SPACE)$/; if ($next->{name} eq 'COLON') { $token->{name} = 'PLAINKEY'; } } } my $next = $list[ $i + 1]; if ($next->{name} eq 'EOL') { if ($str =~ m/ \z/ and $name =~ m/^(BLOCK_SCALAR_CONTENT|WS|INDENT)$/) { $token->{name} = "TRAILING_SPACE"; } } } } return @list; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Highlight - Syntax highlighting utilities =head1 SYNOPSIS use YAML::PP::Highlight qw/ Dump /; my $highlighted = Dump $data; =head1 FUNCTIONS =over =item Dump =back use YAML::PP::Highlight qw/ Dump /; my $highlighted = Dump $data; my $highlighted = Dump @docs; It will dump the given data, and then parse it again to create tokens, which are then highlighted with ansi colors. The return value is ansi colored YAML. 07070100000036000081A40000000000000000000000016616D6BA0000773A000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Lexer.pmuse strict; use warnings; package YAML::PP::Lexer; our $VERSION = '0.000'; # VERSION use constant TRACE => $ENV{YAML_PP_TRACE} ? 1 : 0; use constant DEBUG => ($ENV{YAML_PP_DEBUG} || $ENV{YAML_PP_TRACE}) ? 1 : 0; use YAML::PP::Grammar qw/ $GRAMMAR /; use Carp qw/ croak /; sub new { my ($class, %args) = @_; my $self = bless { reader => $args{reader}, }, $class; $self->init; return $self; } sub init { my ($self) = @_; $self->{next_tokens} = []; $self->{next_line} = undef; $self->{line} = 0; $self->{offset} = 0; $self->{flowcontext} = 0; } sub next_line { return $_[0]->{next_line} } sub set_next_line { $_[0]->{next_line} = $_[1] } sub reader { return $_[0]->{reader} } sub set_reader { $_[0]->{reader} = $_[1] } sub next_tokens { return $_[0]->{next_tokens} } sub line { return $_[0]->{line} } sub set_line { $_[0]->{line} = $_[1] } sub offset { return $_[0]->{offset} } sub set_offset { $_[0]->{offset} = $_[1] } sub inc_line { return $_[0]->{line}++ } sub context { return $_[0]->{context} } sub set_context { $_[0]->{context} = $_[1] } sub flowcontext { return $_[0]->{flowcontext} } sub set_flowcontext { $_[0]->{flowcontext} = $_[1] } sub block { return $_[0]->{block} } sub set_block { $_[0]->{block} = $_[1] } my $RE_WS = '[\t ]'; my $RE_LB = '[\r\n]'; my $RE_DOC_END = qr/\A(\.\.\.)(?=$RE_WS|$)/m; my $RE_DOC_START = qr/\A(---)(?=$RE_WS|$)/m; my $RE_EOL = qr/\A($RE_WS+#.*|$RE_WS+)\z/; #my $RE_COMMENT_EOL = qr/\A(#.*)?(?:$RE_LB|\z)/; #ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” my $RE_NS_WORD_CHAR = '[0-9A-Za-z-]'; my $RE_URI_CHAR = '(?:' . '%[0-9a-fA-F]{2}' .'|'. q{[0-9A-Za-z#;/?:@&=+$,_.!*'\(\)\[\]-]} . ')'; my $RE_NS_TAG_CHAR = '(?:' . '%[0-9a-fA-F]{2}' .'|'. q{[0-9A-Za-z#;/?:@&=+$_.~*'\(\)-]} . ')'; # [#x21-#x7E] /* 8 bit */ # | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] /* 16 bit */ # | [#x10000-#x10FFFF] /* 32 bit */ #nb-char ::= c-printable - b-char - c-byte-order-mark #my $RE_NB_CHAR = '[\x21-\x7E]'; my $RE_ANCHOR_CAR = '[\x21-\x2B\x2D-\x5A\x5C\x5E-\x7A\x7C\x7E\xA0-\xFF\x{100}-\x{10FFFF}]'; my $RE_PLAIN_START = '[\x21\x22\x24-\x39\x3B-\x7E\xA0-\xFF\x{100}-\x{10FFFF}]'; my $RE_PLAIN_END = '[\x21-\x39\x3B-\x7E\x85\xA0-\x{D7FF}\x{E000}-\x{FEFE}\x{FF00}-\x{FFFD}\x{10000}-\x{10FFFF}]'; my $RE_PLAIN_FIRST = '[\x24\x28-\x29\x2B\x2E-\x39\x3B-\x3D\x41-\x5A\x5C\x5E-\x5F\x61-\x7A\x7E\xA0-\xFF\x{100}-\x{10FFFF}]'; my $RE_PLAIN_START_FLOW = '[\x21\x22\x24-\x2B\x2D-\x39\x3B-\x5A\x5C\x5E-\x7A\x7C\x7E\xA0-\xFF\x{100}-\x{10FFFF}]'; my $RE_PLAIN_END_FLOW = '[\x21-\x2B\x2D-\x39\x3B-\x5A\x5C\x5E-\x7A\x7C\x7E\x85\xA0-\x{D7FF}\x{E000}-\x{FEFE}\x{FF00}-\x{FFFD}\x{10000}-\x{10FFFF}]'; my $RE_PLAIN_FIRST_FLOW = '[\x24\x28-\x29\x2B\x2E-\x39\x3B-\x3D\x41-\x5A\x5C\x5E-\x5F\x61-\x7A\x7C\x7E\xA0-\xFF\x{100}-\x{10FFFF}]'; # c-indicators #! 21 #" 22 ## 23 #% 25 #& 26 #' 27 #* 2A #, 2C FLOW #- 2D XX #: 3A XX #> 3E #? 3F XX #@ 40 #[ 5B FLOW #] 5D FLOW #` 60 #{ 7B FLOW #| 7C #} 7D FLOW my $RE_PLAIN_WORD = "(?::+$RE_PLAIN_END|$RE_PLAIN_START)(?::+$RE_PLAIN_END|$RE_PLAIN_END)*"; my $RE_PLAIN_FIRST_WORD = "(?:[:?-]+$RE_PLAIN_END|$RE_PLAIN_FIRST)(?::+$RE_PLAIN_END|$RE_PLAIN_END)*"; my $RE_PLAIN_WORDS = "(?:$RE_PLAIN_FIRST_WORD(?:$RE_WS+$RE_PLAIN_WORD)*)"; my $RE_PLAIN_WORDS2 = "(?:$RE_PLAIN_WORD(?:$RE_WS+$RE_PLAIN_WORD)*)"; my $RE_PLAIN_WORD_FLOW = "(?::+$RE_PLAIN_END_FLOW|$RE_PLAIN_START_FLOW)(?::+$RE_PLAIN_END_FLOW|$RE_PLAIN_END_FLOW)*"; my $RE_PLAIN_FIRST_WORD_FLOW = "(?:[:?-]+$RE_PLAIN_END_FLOW|$RE_PLAIN_FIRST_FLOW)(?::+$RE_PLAIN_END_FLOW|$RE_PLAIN_END_FLOW)*"; my $RE_PLAIN_WORDS_FLOW = "(?:$RE_PLAIN_FIRST_WORD_FLOW(?:$RE_WS+$RE_PLAIN_WORD_FLOW)*)"; my $RE_PLAIN_WORDS_FLOW2 = "(?:$RE_PLAIN_WORD_FLOW(?:$RE_WS+$RE_PLAIN_WORD_FLOW)*)"; #c-secondary-tag-handle ::= “!” “!” #c-named-tag-handle ::= “!” ns-word-char+ “!” #ns-tag-char ::= ns-uri-char - “!” - c-flow-indicator #ns-global-tag-prefix ::= ns-tag-char ns-uri-char* #c-ns-local-tag-prefix ::= “!” ns-uri-char* my $RE_TAG = "!(?:$RE_NS_WORD_CHAR*!$RE_NS_TAG_CHAR+|$RE_NS_TAG_CHAR+|<$RE_URI_CHAR+>|)"; #c-ns-anchor-property ::= “&” ns-anchor-name #ns-char ::= nb-char - s-white #ns-anchor-char ::= ns-char - c-flow-indicator #ns-anchor-name ::= ns-anchor-char+ my $RE_SEQSTART = qr/\A(-)(?=$RE_WS|$)/m; my $RE_COMPLEX = qr/(\?)(?=$RE_WS|$)/m; my $RE_COMPLEXCOLON = qr/\A(:)(?=$RE_WS|$)/m; my $RE_ANCHOR = "&$RE_ANCHOR_CAR+"; my $RE_ALIAS = "\\*$RE_ANCHOR_CAR+"; my %REGEXES = ( ANCHOR => qr{($RE_ANCHOR)}, TAG => qr{($RE_TAG)}, ALIAS => qr{($RE_ALIAS)}, SINGLEQUOTED => qr{(?:''|[^'\r\n]+)*}, ); sub _fetch_next_line { my ($self) = @_; my $next_line = $self->next_line; if (defined $next_line ) { return $next_line; } my $line = $self->reader->readline; unless (defined $line) { $self->set_next_line(undef); return; } $self->set_block(1); $self->inc_line; $line =~ m/\A( *)([^\r\n]*)([\r\n]|\z)/ or die "Unexpected"; $next_line = [ $1, $2, $3 ]; $self->set_next_line($next_line); # $ESCAPE_CHAR from YAML.pm if ($line =~ tr/\x00-\x08\x0b-\x0c\x0e-\x1f//) { $self->exception("Control characters are not allowed"); } return $next_line; } my %TOKEN_NAMES = ( '"' => 'DOUBLEQUOTE', "'" => 'SINGLEQUOTE', '|' => 'LITERAL', '>' => 'FOLDED', '!' => 'TAG', '*' => 'ALIAS', '&' => 'ANCHOR', ':' => 'COLON', '-' => 'DASH', '?' => 'QUESTION', '[' => 'FLOWSEQ_START', ']' => 'FLOWSEQ_END', '{' => 'FLOWMAP_START', '}' => 'FLOWMAP_END', ',' => 'FLOW_COMMA', '---' => 'DOC_START', '...' => 'DOC_END', ); sub fetch_next_tokens { my ($self) = @_; my $next = $self->next_tokens; return $next if @$next; my $next_line = $self->_fetch_next_line; if (not $next_line) { return []; } my $spaces = $next_line->[0]; my $yaml = \$next_line->[1]; if (not length $$yaml) { $self->_push_tokens([ EOL => join('', @$next_line), $self->line ]); $self->set_next_line(undef); return $next; } if (substr($$yaml, 0, 1) eq '#') { $self->_push_tokens([ EOL => join('', @$next_line), $self->line ]); $self->set_next_line(undef); return $next; } if (not $spaces and substr($$yaml, 0, 1) eq "%") { $self->_fetch_next_tokens_directive($yaml, $next_line->[2]); $self->set_context(0); $self->set_next_line(undef); return $next; } if (not $spaces and $$yaml =~ s/\A(---|\.\.\.)(?=$RE_WS|\z)//) { $self->_push_tokens([ $TOKEN_NAMES{ $1 } => $1, $self->line ]); } elsif ($self->flowcontext and $$yaml =~ m/\A[ \t]+(#.*)?\z/) { $self->_push_tokens([ EOL => join('', @$next_line), $self->line ]); $self->set_next_line(undef); return $next; } else { $self->_push_tokens([ SPACE => $spaces, $self->line ]); } my $partial = $self->_fetch_next_tokens($next_line); unless ($partial) { $self->set_next_line(undef); } return $next; } my %ANCHOR_ALIAS_TAG = ( '&' => 1, '*' => 1, '!' => 1 ); my %BLOCK_SCALAR = ( '|' => 1, '>' => 1 ); my %COLON_DASH_QUESTION = ( ':' => 1, '-' => 1, '?' => 1 ); my %QUOTED = ( '"' => 1, "'" => 1 ); my %FLOW = ( '{' => 1, '[' => 1, '}' => 1, ']' => 1, ',' => 1 ); my %CONTEXT = ( '"' => 1, "'" => 1, '>' => 1, '|' => 1 ); my $RE_ESCAPES = qr{(?: \\([ \\\/_0abefnrtvLNP\t"]) | \\x([0-9a-fA-F]{2}) | \\u([A-Fa-f0-9]{4}) | \\U([A-Fa-f0-9]{4,8}) )}x; my %CONTROL = ( '\\' => '\\', '/' => '/', n => "\n", t => "\t", r => "\r", b => "\b", 'a' => "\a", 'b' => "\b", 'e' => "\e", 'f' => "\f", 'v' => "\x0b", "\t" => "\t", 'P' => "\x{2029}", L => "\x{2028}", 'N' => "\x85", '0' => "\0", '_' => "\xa0", ' ' => ' ', q/"/ => q/"/, ); sub _fetch_next_tokens { TRACE and warn __PACKAGE__.':'.__LINE__.": _fetch_next_tokens\n"; my ($self, $next_line) = @_; my $yaml = \$next_line->[1]; my $eol = $next_line->[2]; my @tokens; while (1) { unless (length $$yaml) { push @tokens, ( EOL => $eol, $self->line ); $self->_push_tokens(\@tokens); return; } my $first = substr($$yaml, 0, 1); my $plain = 0; if ($self->context) { if ($$yaml =~ s/\A($RE_WS*)://) { push @tokens, ( WS => $1, $self->line ) if $1; push @tokens, ( COLON => ':', $self->line ); $self->set_context(0); next; } if ($$yaml =~ s/\A($RE_WS*(?: #.*))\z//) { push @tokens, ( EOL => $1 . $eol, $self->line ); $self->_push_tokens(\@tokens); return; } $self->set_context(0); } if ($CONTEXT{ $first }) { push @tokens, ( CONTEXT => $first, $self->line ); $self->_push_tokens(\@tokens); return 1; } elsif ($COLON_DASH_QUESTION{ $first }) { my $token_name = $TOKEN_NAMES{ $first }; if ($$yaml =~ s/\A\Q$first\E($RE_WS+|\z)//) { my $after = $1; if (not $self->flowcontext and not $self->block) { push @tokens, ERROR => $first . $after, $self->line; $self->_push_tokens(\@tokens); $self->exception("Tabs can not be used for indentation"); } if ($after =~ tr/\t//) { $self->set_block(0); } my $token_name = $TOKEN_NAMES{ $first }; push @tokens, ( $token_name => $first, $self->line ); if (not defined $1) { push @tokens, ( EOL => $eol, $self->line ); $self->_push_tokens(\@tokens); return; } my $ws = $1; if ($$yaml =~ s/\A(#.*|)\z//) { push @tokens, ( EOL => $ws . $1 . $eol, $self->line ); $self->_push_tokens(\@tokens); return; } push @tokens, ( WS => $ws, $self->line ); next; } elsif ($self->flowcontext and $$yaml =~ s/\A:(?=[,\{\}\[\]])//) { push @tokens, ( $token_name => $first, $self->line ); next; } $plain = 1; } elsif ($ANCHOR_ALIAS_TAG{ $first }) { my $token_name = $TOKEN_NAMES{ $first }; my $REGEX = $REGEXES{ $token_name }; if ($$yaml =~ s/\A$REGEX//) { push @tokens, ( $token_name => $1, $self->line ); } else { push @tokens, ( "Invalid $token_name" => $$yaml, $self->line ); $self->_push_tokens(\@tokens); return; } } elsif ($first eq ' ' or $first eq "\t") { if ($$yaml =~ s/\A($RE_WS+)//) { my $ws = $1; if ($$yaml =~ s/\A((?:#.*)?\z)//) { push @tokens, ( EOL => $ws . $1 . $eol, $self->line ); $self->_push_tokens(\@tokens); return; } push @tokens, ( WS => $ws, $self->line ); } } elsif ($FLOW{ $first }) { push @tokens, ( $TOKEN_NAMES{ $first } => $first, $self->line ); substr($$yaml, 0, 1, ''); my $flowcontext = $self->flowcontext; if ($first eq '{' or $first eq '[') { $self->set_flowcontext(++$flowcontext); } elsif ($first eq '}' or $first eq ']') { $self->set_flowcontext(--$flowcontext); } } else { $plain = 1; } if ($plain) { push @tokens, ( CONTEXT => '', $self->line ); $self->_push_tokens(\@tokens); return 1; } } return; } sub fetch_plain { my ($self, $indent, $context) = @_; my $next_line = $self->next_line; my $yaml = \$next_line->[1]; my $eol = $next_line->[2]; my $REGEX = $RE_PLAIN_WORDS; if ($self->flowcontext) { $REGEX = $RE_PLAIN_WORDS_FLOW; } my @tokens; unless ($$yaml =~ s/\A($REGEX(?:[:]+(?=\:(\s|\z)))?)//) { $self->_push_tokens(\@tokens); $self->exception("Invalid plain scalar"); } my $plain = $1; push @tokens, ( PLAIN => $plain, $self->line ); if ($$yaml =~ s/\A(?:($RE_WS+#.*)|($RE_WS*))\z//) { if (defined $1) { push @tokens, ( EOL => $1 . $eol, $self->line ); $self->_push_tokens(\@tokens); $self->set_next_line(undef); return; } else { push @tokens, ( EOL => $2. $eol, $self->line ); $self->set_next_line(undef); } } else { $self->_push_tokens(\@tokens); my $partial = $self->_fetch_next_tokens($next_line); if (not $partial) { $self->set_next_line(undef); } return; } my $RE2 = $RE_PLAIN_WORDS2; if ($self->flowcontext) { $RE2 = $RE_PLAIN_WORDS_FLOW2; } my $fetch_next = 0; my @lines = ($plain); my @next; LOOP: while (1) { $next_line = $self->_fetch_next_line; if (not $next_line) { last LOOP; } my $spaces = $next_line->[0]; my $yaml = \$next_line->[1]; my $eol = $next_line->[2]; if (not length $$yaml) { push @tokens, ( EOL => $spaces . $eol, $self->line ); $self->set_next_line(undef); push @lines, ''; next LOOP; } if (not $spaces and $$yaml =~ s/\A(---|\.\.\.)(?=$RE_WS|\z)//) { push @next, $TOKEN_NAMES{ $1 } => $1, $self->line; $fetch_next = 1; last LOOP; } if ((length $spaces) < $indent) { last LOOP; } my $ws = ''; if ($$yaml =~ s/\A($RE_WS+)//) { $ws = $1; } if (not length $$yaml) { push @tokens, ( EOL => $spaces . $ws . $eol, $self->line ); $self->set_next_line(undef); push @lines, ''; next LOOP; } if ($$yaml =~ s/\A(#.*)\z//) { push @tokens, ( EOL => $spaces . $ws . $1 . $eol, $self->line ); $self->set_next_line(undef); last LOOP; } if ($$yaml =~ s/\A($RE2)//) { push @tokens, INDENT => $spaces, $self->line; push @tokens, WS => $ws, $self->line; push @tokens, PLAIN => $1, $self->line; push @lines, $1; my $ws = ''; if ($$yaml =~ s/\A($RE_WS+)//) { $ws = $1; } if (not length $$yaml) { push @tokens, EOL => $ws . $eol, $self->line; $self->set_next_line(undef); next LOOP; } if ($$yaml =~ s/\A(#.*)\z//) { push @tokens, EOL => $ws . $1 . $eol, $self->line; $self->set_next_line(undef); last LOOP; } else { push @tokens, WS => $ws, $self->line if $ws; $fetch_next = 1; } } else { push @tokens, SPACE => $spaces, $self->line; push @tokens, WS => $ws, $self->line; if ($self->flowcontext) { $fetch_next = 1; } else { push @tokens, ERROR => $$yaml, $self->line; } } last LOOP; } # remove empty lines at the end while (@lines > 1 and $lines[-1] eq '') { pop @lines; } if (@lines > 1) { my $value = YAML::PP::Render->render_multi_val(\@lines); my @eol; if ($tokens[-3] eq 'EOL') { @eol = splice @tokens, -3; } $self->push_subtokens( { name => 'PLAIN_MULTI', value => $value }, \@tokens); $self->_push_tokens([ @eol, @next ]); } else { $self->_push_tokens([ @tokens, @next ]); } @tokens = (); if ($fetch_next) { my $partial = $self->_fetch_next_tokens($next_line); if (not $partial) { $self->set_next_line(undef); } } return; } sub fetch_block { my ($self, $indent, $context) = @_; my $next_line = $self->next_line; my $yaml = \$next_line->[1]; my $eol = $next_line->[2]; my @tokens; my $token_name = $TOKEN_NAMES{ $context }; $$yaml =~ s/\A\Q$context\E// or die "Unexpected"; push @tokens, ( $token_name => $context, $self->line ); my $current_indent = $indent; my $started = 0; my $set_indent = 0; my $chomp = ''; if ($$yaml =~ s/\A([1-9])([+-]?)//) { push @tokens, ( BLOCK_SCALAR_INDENT => $1, $self->line ); $set_indent = $1; $chomp = $2 if $2; push @tokens, ( BLOCK_SCALAR_CHOMP => $2, $self->line ) if $2; } elsif ($$yaml =~ s/\A([+-])([1-9])?//) { push @tokens, ( BLOCK_SCALAR_CHOMP => $1, $self->line ); $chomp = $1; push @tokens, ( BLOCK_SCALAR_INDENT => $2, $self->line ) if $2; $set_indent = $2 if $2; } if ($set_indent) { $started = 1; $indent-- if $indent > 0; $current_indent = $indent + $set_indent; } if (not length $$yaml) { push @tokens, ( EOL => $eol, $self->line ); } elsif ($$yaml =~ s/\A($RE_WS*(?:$RE_WS#.*|))\z//) { push @tokens, ( EOL => $1 . $eol, $self->line ); } else { $self->_push_tokens(\@tokens); $self->exception("Invalid block scalar"); } my @lines; while (1) { $self->set_next_line(undef); $next_line = $self->_fetch_next_line; if (not $next_line) { last; } my $spaces = $next_line->[0]; my $content = $next_line->[1]; my $eol = $next_line->[2]; if (not $spaces and $content =~ m/\A(---|\.\.\.)(?=$RE_WS|\z)/) { last; } if ((length $spaces) < $current_indent) { if (length $content) { if ($content =~ m/\A\t/) { $self->_push_tokens(\@tokens); $self->exception("Invalid block scalar"); } last; } else { push @lines, ''; push @tokens, ( EOL => $spaces . $eol, $self->line ); next; } } if ((length $spaces) > $current_indent) { if ($started) { ($spaces, my $more_spaces) = unpack "a${current_indent}a*", $spaces; $content = $more_spaces . $content; } } unless (length $content) { push @lines, ''; push @tokens, ( INDENT => $spaces, $self->line, EOL => $eol, $self->line ); unless ($started) { $current_indent = length $spaces; } next; } unless ($started) { $started = 1; $current_indent = length $spaces; } push @lines, $content; push @tokens, ( INDENT => $spaces, $self->line, BLOCK_SCALAR_CONTENT => $content, $self->line, EOL => $eol, $self->line, ); } my $value = YAML::PP::Render->render_block_scalar($context, $chomp, \@lines); my @eol = splice @tokens, -3; $self->push_subtokens( { name => 'BLOCK_SCALAR', value => $value }, \@tokens ); $self->_push_tokens([ @eol ]); return 0; } sub fetch_quoted { my ($self, $indent, $context) = @_; my $next_line = $self->next_line; my $yaml = \$next_line->[1]; my $spaces = $next_line->[0]; my $token_name = $TOKEN_NAMES{ $context }; $$yaml =~ s/\A\Q$context// or die "Unexpected";; my @tokens = ( $token_name => $context, $self->line ); my $start = 1; my @values; while (1) { unless ($start) { $next_line = $self->_fetch_next_line or do { for (my $i = 0; $i < @tokens; $i+= 3) { my $token = $tokens[ $i + 1 ]; if (ref $token) { $tokens[ $i + 1 ] = $token->{orig}; } } $self->_push_tokens(\@tokens); $self->exception("Missing closing quote <$context> at EOF"); }; $start = 0; $spaces = $next_line->[0]; $yaml = \$next_line->[1]; if (not length $$yaml) { push @tokens, ( EOL => $spaces . $next_line->[2], $self->line ); $self->set_next_line(undef); push @values, { value => '', orig => '' }; next; } elsif (not $spaces and $$yaml =~ m/\A(---|\.\.\.)(?=$RE_WS|\z)/) { for (my $i = 0; $i < @tokens; $i+= 3) { my $token = $tokens[ $i + 1 ]; if (ref $token) { $tokens[ $i + 1 ] = $token->{orig}; } } $self->_push_tokens(\@tokens); $self->exception("Missing closing quote <$context> or invalid document marker"); } elsif ((length $spaces) < $indent) { for (my $i = 0; $i < @tokens; $i+= 3) { my $token = $tokens[ $i + 1 ]; if (ref $token) { $tokens[ $i + 1 ] = $token->{orig}; } } $self->_push_tokens(\@tokens); $self->exception("Wrong indendation or missing closing quote <$context>"); } if ($$yaml =~ s/\A($RE_WS+)//) { $spaces .= $1; } push @tokens, ( WS => $spaces, $self->line ); } my $v = $self->_read_quoted_tokens($start, $context, $yaml, \@tokens); push @values, $v; if ($tokens[-3] eq $token_name) { if ($start) { $self->push_subtokens( { name => 'QUOTED', value => $v->{value} }, \@tokens ); } else { my $value = YAML::PP::Render->render_quoted($context, \@values); $self->push_subtokens( { name => 'QUOTED_MULTILINE', value => $value }, \@tokens ); } $self->set_context(1) if $self->flowcontext; if (length $$yaml) { my $partial = $self->_fetch_next_tokens($next_line); if (not $partial) { $self->set_next_line(undef); } return 0; } else { @tokens = (); push @tokens, ( EOL => $next_line->[2], $self->line ); $self->_push_tokens(\@tokens); $self->set_next_line(undef); return; } } $tokens[-2] .= $next_line->[2]; $self->set_next_line(undef); $start = 0; } } sub _read_quoted_tokens { my ($self, $start, $first, $yaml, $tokens) = @_; my $quoted = ''; my $decoded = ''; my $token_name = $TOKEN_NAMES{ $first }; my $eol = ''; if ($first eq "'") { my $regex = $REGEXES{SINGLEQUOTED}; if ($$yaml =~ s/\A($regex)//) { $quoted .= $1; $decoded .= $1; $decoded =~ s/''/'/g; } unless (length $$yaml) { if ($quoted =~ s/($RE_WS+)\z//) { $eol = $1; $decoded =~ s/($eol)\z//; } } } else { ($quoted, $decoded, $eol) = $self->_read_doublequoted($yaml); } my $value = { value => $decoded, orig => $quoted }; if ($$yaml =~ s/\A$first//) { if ($start) { push @$tokens, ( $token_name . 'D' => $value, $self->line ); } else { push @$tokens, ( $token_name . 'D_LINE' => $value, $self->line ); } push @$tokens, ( $token_name => $first, $self->line ); return $value; } if (length $$yaml) { push @$tokens, ( $token_name . 'D' => $value->{orig}, $self->line ); $self->_push_tokens($tokens); $self->exception("Invalid quoted <$first> string"); } push @$tokens, ( $token_name . 'D_LINE' => $value, $self->line ); push @$tokens, ( EOL => $eol, $self->line ); return $value; } sub _read_doublequoted { my ($self, $yaml) = @_; my $quoted = ''; my $decoded = ''; my $eol = ''; while (1) { my $last = 1; if ($$yaml =~ s/\A([^"\\ \t]+)//) { $quoted .= $1; $decoded .= $1; $last = 0; } if ($$yaml =~ s/\A($RE_ESCAPES)//) { $quoted .= $1; my $dec = defined $2 ? $CONTROL{ $2 } : defined $3 ? chr hex $3 : defined $4 ? chr hex $4 : chr hex $5; $decoded .= $dec; $last = 0; } if ($$yaml =~ s/\A([ \t]+)//) { my $spaces = $1; if (length $$yaml) { $quoted .= $spaces; $decoded .= $spaces; $last = 0; } else { $eol = $spaces; last; } } if ($$yaml =~ s/\A(\\)\z//) { $quoted .= $1; $decoded .= $1; last; } last if $last; } return ($quoted, $decoded, $eol); } sub _fetch_next_tokens_directive { my ($self, $yaml, $eol) = @_; my @tokens; my $trailing_ws = ''; my $warn = $ENV{YAML_PP_RESERVED_DIRECTIVE} || 'warn'; if ($$yaml =~ s/\A(\s*%YAML[ \t]+([0-9]+\.[0-9]+))//) { my $dir = $1; my $version = $2; if ($$yaml =~ s/\A($RE_WS+)//) { $trailing_ws = $1; } elsif (length $$yaml) { push @tokens, ( 'Invalid directive' => $dir.$$yaml.$eol, $self->line ); $self->_push_tokens(\@tokens); return; } if ($version !~ m/^1\.[12]$/) { if ($warn eq 'warn') { warn "Unsupported YAML version '$dir'"; } elsif ($warn eq 'fatal') { push @tokens, ( 'Unsupported YAML version' => $dir, $self->line ); $self->_push_tokens(\@tokens); return; } } push @tokens, ( YAML_DIRECTIVE => $dir, $self->line ); } elsif ($$yaml =~ s/\A(\s*%TAG[ \t]+(!$RE_NS_WORD_CHAR*!|!)[ \t]+(tag:\S+|!$RE_URI_CHAR+))($RE_WS*)//) { push @tokens, ( TAG_DIRECTIVE => $1, $self->line ); # TODO my $tag_alias = $2; my $tag_url = $3; $trailing_ws = $4; } elsif ($$yaml =~ s/\A(\s*\A%(?:\w+).*)//) { push @tokens, ( RESERVED_DIRECTIVE => $1, $self->line ); if ($warn eq 'warn') { warn "Found reserved directive '$1'"; } elsif ($warn eq 'fatal') { die "Found reserved directive '$1'"; } } else { push @tokens, ( 'Invalid directive' => $$yaml, $self->line ); push @tokens, ( EOL => $eol, $self->line ); $self->_push_tokens(\@tokens); return; } if (not length $$yaml) { push @tokens, ( EOL => $eol, $self->line ); } elsif ($trailing_ws and $$yaml =~ s/\A(#.*)?\z//) { push @tokens, ( EOL => "$trailing_ws$1$eol", $self->line ); $self->_push_tokens(\@tokens); return; } elsif ($$yaml =~ s/\A([ \t]+#.*)?\z//) { push @tokens, ( EOL => "$1$eol", $self->line ); $self->_push_tokens(\@tokens); return; } else { push @tokens, ( 'Invalid directive' => $trailing_ws.$$yaml, $self->line ); push @tokens, ( EOL => $eol, $self->line ); } $self->_push_tokens(\@tokens); return; } sub _push_tokens { my ($self, $new_tokens) = @_; my $next = $self->next_tokens; my $line = $self->line; my $column = $self->offset; for (my $i = 0; $i < @$new_tokens; $i += 3) { my $value = $new_tokens->[ $i + 1 ]; my $name = $new_tokens->[ $i ]; my $line = $new_tokens->[ $i + 2 ]; my $push = { name => $name, line => $line, column => $column, value => $value, }; $column += length $value unless $name eq 'CONTEXT'; push @$next, $push; if ($name eq 'EOL') { $column = 0; } } $self->set_offset($column); return $next; } sub push_subtokens { my ($self, $token, $subtokens) = @_; my $next = $self->next_tokens; my $line = $self->line; my $column = $self->offset; $token->{column} = $column; $token->{subtokens} = \my @sub; for (my $i = 0; $i < @$subtokens; $i+=3) { my $name = $subtokens->[ $i ]; my $value = $subtokens->[ $i + 1 ]; my $line = $subtokens->[ $i + 2 ]; my $push = { name => $subtokens->[ $i ], line => $line, column => $column, }; if (ref $value eq 'HASH') { %$push = ( %$push, %$value ); $column += length $value->{orig}; } else { $push->{value} = $value; $column += length $value; } if ($push->{name} eq 'EOL') { $column = 0; } push @sub, $push; } $token->{line} = $sub[0]->{line}; push @$next, $token; $self->set_offset($column); return $next; } sub exception { my ($self, $msg) = @_; my $next = $self->next_tokens; $next = []; my $line = @$next ? $next->[0]->{line} : $self->line; my @caller = caller(0); my $yaml = ''; if (my $nl = $self->next_line) { $yaml = join '', @$nl; $yaml = $nl->[1]; } my $e = YAML::PP::Exception->new( line => $line, column => $self->offset + 1, msg => $msg, next => $next, where => $caller[1] . ' line ' . $caller[2], yaml => $yaml, ); croak $e; } 1; 07070100000037000081A40000000000000000000000016616D6BA000009BA000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Loader.pm# ABSTRACT: Load YAML into data with Parser and Constructor use strict; use warnings; package YAML::PP::Loader; our $VERSION = '0.000'; # VERSION use YAML::PP::Parser; use YAML::PP::Constructor; use YAML::PP::Reader; sub new { my ($class, %args) = @_; my $cyclic_refs = delete $args{cyclic_refs} || 'fatal'; my $default_yaml_version = delete $args{default_yaml_version} || '1.2'; my $preserve = delete $args{preserve}; my $duplicate_keys = delete $args{duplicate_keys}; my $schemas = delete $args{schemas}; $schemas ||= { '1.2' => YAML::PP->default_schema( boolean => 'perl', ) }; my $constructor = delete $args{constructor} || YAML::PP::Constructor->new( schemas => $schemas, cyclic_refs => $cyclic_refs, default_yaml_version => $default_yaml_version, preserve => $preserve, duplicate_keys => $duplicate_keys, ); my $parser = delete $args{parser}; unless ($parser) { $parser = YAML::PP::Parser->new( default_yaml_version => $default_yaml_version, ); } unless ($parser->receiver) { $parser->set_receiver($constructor); } if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } my $self = bless { parser => $parser, constructor => $constructor, }, $class; return $self; } sub clone { my ($self) = @_; my $clone = { parser => $self->parser->clone, constructor => $self->constructor->clone, }; bless $clone, ref $self; $clone->parser->set_receiver($clone->constructor); return $clone; } sub parser { return $_[0]->{parser} } sub constructor { return $_[0]->{constructor} } sub filename { my ($self) = @_; my $reader = $self->parser->reader; if ($reader->isa('YAML::PP::Reader::File')) { return $reader->input; } die "Reader is not a YAML::PP::Reader::File"; } sub load_string { my ($self, $yaml) = @_; $self->parser->set_reader(YAML::PP::Reader->new( input => $yaml )); $self->load(); } sub load_file { my ($self, $file) = @_; $self->parser->set_reader(YAML::PP::Reader::File->new( input => $file )); $self->load(); } sub load { my ($self) = @_; my $parser = $self->parser; my $constructor = $self->constructor; $constructor->init; $parser->parse(); my $docs = $constructor->docs; return wantarray ? @$docs : $docs->[0]; } 1; 07070100000038000081A40000000000000000000000016616D6BA0000A2B2000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Parser.pm# ABSTRACT: YAML Parser use strict; use warnings; package YAML::PP::Parser; our $VERSION = '0.000'; # VERSION use constant TRACE => $ENV{YAML_PP_TRACE} ? 1 : 0; use constant DEBUG => ($ENV{YAML_PP_DEBUG} || $ENV{YAML_PP_TRACE}) ? 1 : 0; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE /; use YAML::PP::Render; use YAML::PP::Lexer; use YAML::PP::Grammar qw/ $GRAMMAR /; use YAML::PP::Exception; use YAML::PP::Reader; use Carp qw/ croak /; sub new { my ($class, %args) = @_; my $reader = delete $args{reader} || YAML::PP::Reader->new; my $default_yaml_version = delete $args{default_yaml_version}; my $self = bless { default_yaml_version => $default_yaml_version || '1.2', lexer => YAML::PP::Lexer->new( reader => $reader, ), }, $class; my $receiver = delete $args{receiver}; if ($receiver) { $self->set_receiver($receiver); } return $self; } sub clone { my ($self) = @_; my $clone = { default_yaml_version => $self->default_yaml_version, lexer => YAML::PP::Lexer->new(), }; return bless $clone, ref $self; } sub receiver { return $_[0]->{receiver} } sub set_receiver { my ($self, $receiver) = @_; my $callback; if (ref $receiver eq 'CODE') { $callback = $receiver; } else { $callback = sub { my ($self, $event, $info) = @_; return $receiver->$event($info); }; } $self->{callback} = $callback; $self->{receiver} = $receiver; } sub reader { return $_[0]->lexer->{reader} } sub set_reader { my ($self, $reader) = @_; $self->lexer->set_reader($reader); } sub lexer { return $_[0]->{lexer} } sub callback { return $_[0]->{callback} } sub set_callback { $_[0]->{callback} = $_[1] } sub level { return $#{ $_[0]->{offset} } } sub offset { return $_[0]->{offset} } sub set_offset { $_[0]->{offset} = $_[1] } sub events { return $_[0]->{events} } sub set_events { $_[0]->{events} = $_[1] } sub new_node { return $_[0]->{new_node} } sub set_new_node { $_[0]->{new_node} = $_[1] } sub tagmap { return $_[0]->{tagmap} } sub set_tagmap { $_[0]->{tagmap} = $_[1] } sub tokens { return $_[0]->{tokens} } sub set_tokens { $_[0]->{tokens} = $_[1] } sub event_stack { return $_[0]->{event_stack} } sub set_event_stack { $_[0]->{event_stack} = $_[1] } sub default_yaml_version { return $_[0]->{default_yaml_version} } sub yaml_version { return $_[0]->{yaml_version} } sub set_yaml_version { $_[0]->{yaml_version} = $_[1] } sub yaml_version_directive { return $_[0]->{yaml_version_directive} } sub set_yaml_version_directive { $_[0]->{yaml_version_directive} = $_[1] } sub rule { return $_[0]->{rule} } sub set_rule { my ($self, $name) = @_; no warnings 'uninitialized'; DEBUG and $self->info("set_rule($name)"); $self->{rule} = $name; } sub init { my ($self) = @_; $self->set_offset([]); $self->set_events([]); $self->set_new_node(0); $self->set_tagmap({ '!!' => "tag:yaml.org,2002:", }); $self->set_tokens([]); $self->set_rule(undef); $self->set_event_stack([]); $self->set_yaml_version($self->default_yaml_version); $self->set_yaml_version_directive(undef); $self->lexer->init; } sub parse_string { my ($self, $yaml) = @_; $self->set_reader(YAML::PP::Reader->new( input => $yaml )); $self->parse(); } sub parse_file { my ($self, $file) = @_; $self->set_reader(YAML::PP::Reader::File->new( input => $file )); $self->parse(); } my %nodetypes = ( MAPVALUE => 'NODETYPE_COMPLEX', MAP => 'NODETYPE_MAP', # IMAP => 'NODETYPE_SEQ', SEQ => 'NODETYPE_SEQ', SEQ0 => 'NODETYPE_SEQ', FLOWMAP => 'NODETYPE_FLOWMAP', FLOWMAPVALUE => 'NODETYPE_FLOWMAPVALUE', FLOWSEQ => 'NODETYPE_FLOWSEQ', FLOWSEQ_NEXT => 'FLOWSEQ_NEXT', DOC => 'FULLNODE', DOC_END => 'DOCUMENT_END', STR => 'STREAM', END_FLOW => 'END_FLOW', ); sub parse { my ($self) = @_; TRACE and warn "=== parse()\n"; TRACE and $self->debug_yaml; $self->init; $self->lexer->init; eval { $self->start_stream; $self->set_rule( 'STREAM' ); $self->parse_tokens(); $self->end_stream; }; if (my $error = $@) { if (ref $error) { croak "$error\n "; } croak $error; } DEBUG and $self->highlight_yaml; TRACE and $self->debug_tokens; } sub lex_next_tokens { my ($self) = @_; DEBUG and $self->info("----------------> lex_next_tokens"); TRACE and $self->debug_events; my $indent = $self->offset->[-1]; my $event_types = $self->events; my $next_tokens = $self->lexer->fetch_next_tokens($indent); return unless @$next_tokens; my $next = $next_tokens->[0]; return 1 if ($next->{name} ne 'SPACE'); my $flow = $event_types->[-1] =~ m/^FLOW/; my $space = length $next->{value}; my $tokens = $self->tokens; if (not $space) { shift @$next_tokens; } else { push @$tokens, shift @$next_tokens; } if ($flow) { if ($space >= $indent) { return 1; } $self->exception("Bad indendation in " . $self->events->[-1]); } $next = $next_tokens->[0]; if ($space > $indent ) { return 1 if $indent < 0; unless ($self->new_node) { $self->exception("Bad indendation in " . $self->events->[-1]); } return 1; } if ($self->new_node) { if ($space < $indent) { $self->scalar_event({ style => YAML_PLAIN_SCALAR_STYLE, value => '' }); $self->remove_nodes($space); } else { # unindented sequence starts my $exp = $self->events->[-1]; my $seq_start = $next->{name} eq 'DASH'; if ( $seq_start and ($exp eq 'MAPVALUE' or $exp eq 'MAP')) { } else { $self->scalar_event({ style => YAML_PLAIN_SCALAR_STYLE, value => '' }); } } } else { if ($space < $indent) { $self->remove_nodes($space); } } my $exp = $self->events->[-1]; if ($exp eq 'SEQ0' and $next->{name} ne 'DASH') { TRACE and $self->info("In unindented sequence"); $self->end_sequence; $exp = $self->events->[-1]; } if ($self->offset->[-1] != $space) { $self->exception("Expected " . $self->events->[-1]); } return 1; } my %next_event = ( MAP => 'MAPVALUE', IMAP => 'IMAPVALUE', MAPVALUE => 'MAP', IMAPVALUE => 'IMAP', SEQ => 'SEQ', SEQ0 => 'SEQ0', DOC => 'DOC_END', STR => 'STR', FLOWSEQ => 'FLOWSEQ_NEXT', FLOWSEQ_NEXT => 'FLOWSEQ', FLOWMAP => 'FLOWMAPVALUE', FLOWMAPVALUE => 'FLOWMAP', ); my %event_to_method = ( MAP => 'mapping', IMAP => 'mapping', FLOWMAP => 'mapping', SEQ => 'sequence', SEQ0 => 'sequence', FLOWSEQ => 'sequence', DOC => 'document', STR => 'stream', VAL => 'scalar', ALI => 'alias', MAPVALUE => 'mapping', IMAPVALUE => 'mapping', ); #sub process_events { # my ($self, $res) = @_; # # my $event_stack = $self->event_stack; # return unless @$event_stack; # # if (@$event_stack == 1 and $event_stack->[0]->[0] eq 'properties') { # return; # } # # my $event_types = $self->events; # my $properties; # my @send_events; # for my $event (@$event_stack) { # TRACE and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$event], ['event']); # my ($type, $info) = @$event; # if ($type eq 'properties') { # $properties = $info; # } # elsif ($type eq 'scalar') { # $info->{name} = 'scalar_event'; # $event_types->[-1] = $next_event{ $event_types->[-1] }; # push @send_events, $info; # } # elsif ($type eq 'begin') { # my $name = $info->{name}; # $info->{name} = $event_to_method{ $name } . '_start_event'; # push @{ $event_types }, $name; # push @{ $self->offset }, $info->{offset}; # push @send_events, $info; # } # elsif ($type eq 'end') { # my $name = $info->{name}; # $info->{name} = $event_to_method{ $name } . '_end_event'; # $self->$type($name, $info); # push @send_events, $info; # if (@$event_types) { # $event_types->[-1] = $next_event{ $event_types->[-1] }; # } # } # elsif ($type eq 'alias') { # if ($properties) { # $self->exception("Parse error: Alias not allowed in this context"); # } # $info->{name} = 'alias_event'; # $event_types->[-1] = $next_event{ $event_types->[-1] }; # push @send_events, $info; # } # } # @$event_stack = (); # for my $info (@send_events) { # DEBUG and $self->debug_event( $info ); # $self->callback->($self, $info->{name}, $info); # } #} my %fetch_method = ( '"' => 'fetch_quoted', "'" => 'fetch_quoted', '|' => 'fetch_block', '>' => 'fetch_block', '' => 'fetch_plain', ); sub parse_tokens { my ($self) = @_; my $event_types = $self->events; my $offsets = $self->offset; my $tokens = $self->tokens; my $next_tokens = $self->lexer->next_tokens; unless ($self->lex_next_tokens) { $self->end_document(1); return 0; } unless ($self->new_node) { if ($self->level > 0) { my $new_rule = $nodetypes{ $event_types->[-1] } or die "Did not find '$event_types->[-1]'"; $self->set_rule( $new_rule ); } } my $rule_name = $self->rule; DEBUG and $self->info("----------------> parse_tokens($rule_name)"); my $rule = $GRAMMAR->{ $rule_name } or die "Could not find rule $rule_name"; TRACE and $self->debug_rules($rule); TRACE and $self->debug_yaml; DEBUG and $self->debug_next_line; RULE: while ($rule_name) { DEBUG and $self->info("RULE: $rule_name"); TRACE and $self->debug_tokens($next_tokens); unless (@$next_tokens) { $self->exception("No more tokens"); } TRACE and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$next_tokens->[0]], ['next_token']); my $got = $next_tokens->[0]->{name}; if ($got eq 'CONTEXT') { my $context = shift @$next_tokens; my $indent = $offsets->[-1]; $indent++ unless $self->lexer->flowcontext; my $method = $fetch_method{ $context->{value} }; my $partial = $self->lexer->$method($indent, $context->{value}); next RULE; } my $def = $rule->{ $got }; if ($def) { push @$tokens, shift @$next_tokens; } elsif ($def = $rule->{DEFAULT}) { $got = 'DEFAULT'; } else { $self->expected( expected => [keys %$rule], got => $next_tokens->[0], ); } DEBUG and $self->got("---got $got"); if (my $sub = $def->{match}) { DEBUG and $self->info("CALLBACK $sub"); $self->$sub(@$tokens ? $tokens->[-1] : ()); } my $eol = $got eq 'EOL'; my $new = $def->{new}; if ($new) { DEBUG and $self->got("NEW: $new"); $rule_name = $new; $self->set_rule($rule_name); } elsif ($eol) { } elsif ($def->{return}) { $rule_name = $nodetypes{ $event_types->[-1] } or die "Unexpected event type $event_types->[-1]"; $self->set_rule($rule_name); } else { $rule_name .= " - $got"; # for debugging $rule = $def; next RULE; } if ($eol) { unless ($self->lex_next_tokens) { if ($rule_name eq 'DIRECTIVE') { $self->exception("Directive needs document start"); } $self->end_document(1); return 0; } unless ($self->new_node) { if ($self->level > 0) { $rule_name = $nodetypes{ $event_types->[-1] } or die "Did not find '$event_types->[-1]'"; $self->set_rule( $rule_name ); } } $rule_name = $self->rule; } $rule = $GRAMMAR->{ $rule_name } or die "Unexpected rule $rule_name"; } die "Unexpected"; } sub end_sequence { my ($self) = @_; my $event_types = $self->events; pop @{ $event_types }; pop @{ $self->offset }; my $info = { name => 'sequence_end_event' }; $self->callback->($self, $info->{name} => $info ); $event_types->[-1] = $next_event{ $event_types->[-1] }; } sub remove_nodes { my ($self, $space) = @_; my $offset = $self->offset; my $event_types = $self->events; my $exp = $event_types->[-1]; while (@$offset) { if ($offset->[ -1 ] <= $space) { last; } if ($exp eq 'MAPVALUE') { $self->scalar_event({ style => YAML_PLAIN_SCALAR_STYLE, value => '' }); $exp = 'MAP'; } my $info = { name => $exp }; $info->{name} = $event_to_method{ $exp } . '_end_event'; pop @{ $event_types }; pop @{ $offset }; $self->callback->($self, $info->{name} => $info ); $event_types->[-1] = $next_event{ $event_types->[-1] }; $exp = $event_types->[-1]; } return $exp; } sub start_stream { my ($self) = @_; push @{ $self->events }, 'STR'; push @{ $self->offset }, -1; $self->callback->($self, 'stream_start_event', { name => 'stream_start_event', }); } sub start_document { my ($self, $implicit) = @_; push @{ $self->events }, 'DOC'; push @{ $self->offset }, -1; my $directive = $self->yaml_version_directive; my %directive; if ($directive) { my ($major, $minor) = split m/\./, $self->yaml_version; %directive = ( version_directive => { major => $major, minor => $minor } ); } $self->callback->($self, 'document_start_event', { name => 'document_start_event', implicit => $implicit, %directive, }); $self->set_yaml_version_directive(undef); $self->set_rule( 'FULLNODE' ); $self->set_new_node(1); } sub start_sequence { my ($self, $offset) = @_; my $offsets = $self->offset; if ($offsets->[-1] == $offset) { push @{ $self->events }, 'SEQ0'; } else { push @{ $self->events }, 'SEQ'; } push @{ $offsets }, $offset; my $event_stack = $self->event_stack; my $info = { name => 'sequence_start_event' }; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { my $properties = pop @$event_stack; $self->node_properties($properties->[1], $info); } $self->callback->($self, 'sequence_start_event', $info); } sub start_flow_sequence { my ($self, $offset) = @_; my $offsets = $self->offset; my $new_offset = $offsets->[-1]; my $event_types = $self->events; if ($new_offset < 0) { $new_offset = 0; } elsif ($self->new_node) { if ($event_types->[-1] !~ m/^FLOW/) { $new_offset++; } } push @{ $self->events }, 'FLOWSEQ'; push @{ $offsets }, $new_offset; my $event_stack = $self->event_stack; my $info = { style => YAML_FLOW_SEQUENCE_STYLE, name => 'sequence_start_event' }; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($event_stack, $info); } $self->callback->($self, 'sequence_start_event', $info); } sub start_flow_mapping { my ($self, $offset, $implicit_flowseq_map) = @_; my $offsets = $self->offset; my $new_offset = $offsets->[-1]; my $event_types = $self->events; if ($new_offset < 0) { $new_offset = 0; } elsif ($self->new_node) { if ($event_types->[-1] !~ m/^FLOW/) { $new_offset++; } } push @{ $self->events }, $implicit_flowseq_map ? 'IMAP' : 'FLOWMAP'; push @{ $offsets }, $new_offset; my $event_stack = $self->event_stack; my $info = { name => 'mapping_start_event', style => YAML_FLOW_MAPPING_STYLE }; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($event_stack, $info); } $self->callback->($self, 'mapping_start_event', $info); } sub end_flow_sequence { my ($self) = @_; my $event_types = $self->events; pop @{ $event_types }; pop @{ $self->offset }; my $info = { name => 'sequence_end_event' }; $self->callback->($self, $info->{name}, $info); if ($event_types->[-1] =~ m/^FLOW|^IMAP/) { $event_types->[-1] = $next_event{ $event_types->[-1] }; } else { push @$event_types, 'END_FLOW'; } } sub end_flow_mapping { my ($self) = @_; my $event_types = $self->events; pop @{ $event_types }; pop @{ $self->offset }; my $info = { name => 'mapping_end_event' }; $self->callback->($self, $info->{name}, $info); if ($event_types->[-1] =~ m/^FLOW|^IMAP/) { $event_types->[-1] = $next_event{ $event_types->[-1] }; } else { push @$event_types, 'END_FLOW'; } } sub cb_end_outer_flow { my ($self) = @_; my $event_types = $self->events; pop @$event_types; $event_types->[-1] = $next_event{ $event_types->[-1] }; } sub start_mapping { my ($self, $offset) = @_; my $offsets = $self->offset; push @{ $self->events }, 'MAP'; push @{ $offsets }, $offset; my $event_stack = $self->event_stack; my $info = { name => 'mapping_start_event' }; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { my $properties = pop @$event_stack; $self->node_properties($properties->[1], $info); } $self->callback->($self, 'mapping_start_event', $info); } sub end_document { my ($self, $implicit) = @_; my $event_types = $self->events; if ($event_types->[-1] =~ m/FLOW/) { die "Unexpected end of flow context"; } if ($self->new_node) { $self->scalar_event({ style => YAML_PLAIN_SCALAR_STYLE, value => '' }); } $self->remove_nodes(-1); if ($event_types->[-1] eq 'STR') { return; } my $last = pop @{ $event_types }; if ($last ne 'DOC' and $last ne 'DOC_END') { $self->exception("Unexpected event type $last"); } pop @{ $self->offset }; $self->callback->($self, 'document_end_event', { name => 'document_end_event', implicit => $implicit, }); if ($self->yaml_version eq '1.2') { # In YAML 1.2, directives are only for the following # document. In YAML 1.1, they are global $self->set_tagmap({ '!!' => "tag:yaml.org,2002:" }); } $event_types->[-1] = $next_event{ $event_types->[-1] }; $self->set_rule('STREAM'); } sub end_stream { my ($self) = @_; my $last = pop @{ $self->events }; $self->exception("Unexpected event type $last") unless $last eq 'STR'; pop @{ $self->offset }; $self->callback->($self, 'stream_end_event', { name => 'stream_end_event', }); } sub fetch_inline_properties { my ($self, $stack, $info) = @_; my $properties = $stack->[-1]; $properties = $properties->[1]; my $property_offset; if ($properties) { for my $p (@{ $properties->{inline} }) { my $type = $p->{type}; if (exists $info->{ $type }) { $self->exception("A node can only have one $type"); } $info->{ $type } = $p->{value}; unless (defined $property_offset) { $property_offset = $p->{offset}; $info->{offset} = $p->{offset}; } } delete $properties->{inline}; undef $properties unless $properties->{newline}; } unless ($properties) { pop @$stack; } } sub node_properties { my ($self, $properties, $info) = @_; if ($properties) { for my $p (@{ $properties->{newline} }) { my $type = $p->{type}; if (exists $info->{ $type }) { $self->exception("A node can only have one $type"); } $info->{ $type } = $p->{value}; } undef $properties; } } sub scalar_event { my ($self, $info) = @_; my $event_types = $self->events; my $event_stack = $self->event_stack; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { my $properties = pop @$event_stack; $properties = $self->node_properties($properties->[1], $info); } $info->{name} = 'scalar_event'; $self->callback->($self, 'scalar_event', $info); $self->set_new_node(0); $event_types->[-1] = $next_event{ $event_types->[-1] }; } sub alias_event { my ($self, $info) = @_; my $event_stack = $self->event_stack; if (@$event_stack and $event_stack->[-1]->[0] eq 'properties') { $self->exception("Parse error: Alias not allowed in this context"); } my $event_types = $self->events; $info->{name} = 'alias_event'; $self->callback->($self, 'alias_event', $info); $self->set_new_node(0); $event_types->[-1] = $next_event{ $event_types->[-1] }; } sub yaml_to_tokens { my ($class, $type, $input) = @_; my $yp = YAML::PP::Parser->new( receiver => sub {} ); my @docs = eval { $type eq 'string' ? $yp->parse_string($input) : $yp->parse_file($input); }; my $error = $@; my $tokens = $yp->tokens; if ($error) { my $remaining_tokens = $yp->_remaining_tokens; push @$tokens, map { +{ %$_, name => 'ERROR' } } @$remaining_tokens; } return $error, $tokens; } sub _remaining_tokens { my ($self) = @_; my @tokens; my $next = $self->lexer->next_tokens; push @tokens, @$next; my $next_line = $self->lexer->next_line; my $remaining = ''; if ($next_line) { if ($self->lexer->offset > 0) { $remaining = $next_line->[1] . $next_line->[2]; } else { $remaining = join '', @$next_line; } } $remaining .= $self->reader->read; $remaining = '' unless defined $remaining; push @tokens, { name => "ERROR", value => $remaining }; return \@tokens; } # deprecated sub event_to_test_suite { # uncoverable subroutine my ($self, $event) = @_; # uncoverable statement if (ref $event eq 'ARRAY') { # uncoverable statement return YAML::PP::Common::event_to_test_suite($event->[1]); # uncoverable statement } return YAML::PP::Common::event_to_test_suite($event); # uncoverable statement } sub debug_events { # uncoverable subroutine my ($self) = @_; # uncoverable statement $self->note("EVENTS: (" # uncoverable statement . join (' | ', @{ $_[0]->events }) . ')' # uncoverable statement ); $self->debug_offset; # uncoverable statement } sub debug_offset { # uncoverable subroutine my ($self) = @_; # uncoverable statement $self->note( qq{OFFSET: (} # uncoverable statement count:1 # uncoverable statement count:2 # uncoverable statement count:3 . join (' | ', map { defined $_ ? sprintf "%-3d", $_ : '?' } @{ $_[0]->offset }) # uncoverable statement . qq/) level=@{[ $_[0]->level ]}]}/ ); } sub debug_yaml { # uncoverable subroutine my ($self) = @_; # uncoverable statement my $line = $self->lexer->line; # uncoverable statement $self->note("LINE NUMBER: $line"); # uncoverable statement my $next_tokens = $self->lexer->next_tokens; # uncoverable statement if (@$next_tokens) { # uncoverable statement $self->debug_tokens($next_tokens); # uncoverable statement } } sub debug_next_line { my ($self) = @_; my $next_line = $self->lexer->next_line || []; my $line = $next_line->[0]; $line = '' unless defined $line; $line =~ s/( +)$/'·' x length $1/e; $line =~ s/\t/▸/g; $self->note("NEXT LINE: >>$line<<"); } sub note { my ($self, $msg) = @_; $self->_colorize_warn(["yellow"], "============ $msg"); } sub info { my ($self, $msg) = @_; $self->_colorize_warn(["cyan"], "============ $msg"); } sub got { my ($self, $msg) = @_; $self->_colorize_warn(["green"], "============ $msg"); } sub _colorize_warn { # uncoverable subroutine my ($self, $colors, $text) = @_; # uncoverable statement require Term::ANSIColor; # uncoverable statement warn Term::ANSIColor::colored($colors, $text), "\n"; # uncoverable statement } sub debug_event { # uncoverable subroutine my ($self, $event) = @_; # uncoverable statement my $str = YAML::PP::Common::event_to_test_suite($event); # uncoverable statement require Term::ANSIColor; # uncoverable statement warn Term::ANSIColor::colored(["magenta"], "============ $str"), "\n"; # uncoverable statement } sub debug_rules { # uncoverable subroutine my ($self, $rules) = @_; # uncoverable statement local $Data::Dumper::Maxdepth = 2; # uncoverable statement $self->note("RULES:"); # uncoverable statement for my $rule ($rules) { # uncoverable statement if (ref $rule eq 'ARRAY') { # uncoverable statement my $first = $rule->[0]; # uncoverable statement if (ref $first eq 'SCALAR') { # uncoverable statement $self->info("-> $$first"); # uncoverable statement } else { # uncoverable statement if (ref $first eq 'ARRAY') { # uncoverable statement $first = $first->[0]; # uncoverable statement } $self->info("TYPE $first"); # uncoverable statement } } else { # uncoverable statement eval { # uncoverable statement my @keys = sort keys %$rule; # uncoverable statement $self->info("@keys"); # uncoverable statement }; } } } sub debug_tokens { # uncoverable subroutine my ($self, $tokens) = @_; # uncoverable statement $tokens ||= $self->tokens; # uncoverable statement require Term::ANSIColor; # uncoverable statement for my $token (@$tokens) { # uncoverable statement my $type = Term::ANSIColor::colored(["green"], # uncoverable statement sprintf "%-22s L %2d C %2d ", # uncoverable statement $token->{name}, $token->{line}, $token->{column} + 1 # uncoverable statement ); local $Data::Dumper::Useqq = 1; # uncoverable statement local $Data::Dumper::Terse = 1; # uncoverable statement require Data::Dumper; # uncoverable statement my $str = Data::Dumper->Dump([$token->{value}], ['str']); # uncoverable statement chomp $str; # uncoverable statement $str =~ s/(^.|.$)/Term::ANSIColor::colored(['blue'], $1)/ge; # uncoverable statement warn "$type$str\n"; # uncoverable statement } } sub highlight_yaml { my ($self) = @_; require YAML::PP::Highlight; my $tokens = $self->tokens; my $highlighted = YAML::PP::Highlight->ansicolored($tokens); warn $highlighted; } sub exception { my ($self, $msg, %args) = @_; my $next = $self->lexer->next_tokens; my $line = @$next ? $next->[0]->{line} : $self->lexer->line; my $offset = @$next ? $next->[0]->{column} : $self->lexer->offset; $offset++; my $next_line = $self->lexer->next_line; my $remaining = ''; if ($next_line) { if ($self->lexer->offset > 0) { $remaining = $next_line->[1] . $next_line->[2]; } else { $remaining = join '', @$next_line; } } my $caller = $args{caller} || [ caller(0) ]; my $e = YAML::PP::Exception->new( got => $args{got}, expected => $args{expected}, line => $line, column => $offset, msg => $msg, next => $next, where => $caller->[1] . ' line ' . $caller->[2], yaml => $remaining, ); croak $e; } sub expected { my ($self, %args) = @_; my $expected = $args{expected}; @$expected = sort grep { m/^[A-Z_]+$/ } @$expected; my $got = $args{got}->{name}; my @caller = caller(0); $self->exception("Expected (@$expected), but got $got", caller => \@caller, expected => $expected, got => $args{got}, ); } sub cb_tag { my ($self, $token) = @_; my $stack = $self->event_stack; if (! @$stack or $stack->[-1]->[0] ne 'properties') { push @$stack, [ properties => {} ]; } my $last = $stack->[-1]->[1]; my $tag = $self->_read_tag($token->{value}, $self->tagmap); $last->{inline} ||= []; push @{ $last->{inline} }, { type => 'tag', value => $tag, offset => $token->{column}, }; } sub _read_tag { my ($self, $tag, $map) = @_; if ($tag eq '!') { return "!"; } elsif ($tag =~ m/^!<(.*)>/) { return $1; } elsif ($tag =~ m/^(![^!]*!|!)(.+)/) { my $alias = $1; my $name = $2; $name =~ s/%([0-9a-fA-F]{2})/chr hex $1/eg; if (exists $map->{ $alias }) { $tag = $map->{ $alias }. $name; } else { if ($alias ne '!' and $alias ne '!!') { die "Found undefined tag handle '$alias'"; } $tag = "!$name"; } } else { die "Invalid tag"; } return $tag; } sub cb_anchor { my ($self, $token) = @_; my $anchor = $token->{value}; $anchor = substr($anchor, 1); my $stack = $self->event_stack; if (! @$stack or $stack->[-1]->[0] ne 'properties') { push @$stack, [ properties => {} ]; } my $last = $stack->[-1]->[1]; $last->{inline} ||= []; push @{ $last->{inline} }, { type => 'anchor', value => $anchor, offset => $token->{column}, }; } sub cb_property_eol { my ($self, $res) = @_; my $stack = $self->event_stack; my $last = $stack->[-1]->[1]; my $inline = delete $last->{inline} or return; my $newline = $last->{newline} ||= []; push @$newline, @$inline; } sub cb_mapkey { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $stack }, [ scalar => $info ]; } sub cb_send_mapkey { my ($self, $res) = @_; my $last = pop @{ $self->event_stack }; $self->scalar_event($last->[1]); $self->set_new_node(1); } sub cb_send_scalar { my ($self, $res) = @_; my $last = pop @{ $self->event_stack }; return unless $last; $self->scalar_event($last->[1]); my $e = $self->events; if ($e->[-1] eq 'IMAP') { $self->end_flow_mapping; } } sub cb_empty_mapkey { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => '', offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->scalar_event($info); $self->set_new_node(1); } sub cb_send_flow_alias { my ($self, $token) = @_; my $alias = substr($token->{value}, 1); $self->alias_event({ value => $alias }); } sub cb_send_alias { my ($self, $token) = @_; my $alias = substr($token->{value}, 1); $self->alias_event({ value => $alias }); } sub cb_send_alias_key { my ($self, $token) = @_; my $alias = substr($token->{value}, 1); $self->alias_event({ value => $alias }); $self->set_new_node(1); } sub cb_send_alias_from_stack { my ($self, $token) = @_; my $last = pop @{ $self->event_stack }; $self->alias_event($last->[1]); } sub cb_alias { my ($self, $token) = @_; my $alias = substr($token->{value}, 1); push @{ $self->event_stack }, [ alias => { value => $alias, offset => $token->{column}, }]; } sub cb_question { my ($self, $res) = @_; $self->set_new_node(1); } sub cb_flow_question { my ($self, $res) = @_; $self->set_new_node(2); } sub cb_empty_complexvalue { my ($self, $res) = @_; $self->scalar_event({ style => YAML_PLAIN_SCALAR_STYLE, value => '' }); } sub cb_questionstart { my ($self, $token) = @_; $self->start_mapping($token->{column}); } sub cb_complexcolon { my ($self, $res) = @_; $self->set_new_node(1); } sub cb_seqstart { my ($self, $token) = @_; my $column = $token->{column}; $self->start_sequence($column); $self->set_new_node(1); } sub cb_seqitem { my ($self, $res) = @_; $self->set_new_node(1); } sub cb_take_quoted { my ($self, $token) = @_; my $subtokens = $token->{subtokens}; my $stack = $self->event_stack; my $info = { style => $subtokens->[0]->{value} eq '"' ? YAML_DOUBLE_QUOTED_SCALAR_STYLE : YAML_SINGLE_QUOTED_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $stack }, [ scalar => $info ]; } sub cb_quoted_multiline { my ($self, $token) = @_; my $subtokens = $token->{subtokens}; my $stack = $self->event_stack; my $info = { style => $subtokens->[0]->{value} eq '"' ? YAML_DOUBLE_QUOTED_SCALAR_STYLE : YAML_SINGLE_QUOTED_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $stack }, [ scalar => $info ]; $self->cb_send_scalar; } sub cb_take_quoted_key { my ($self, $token) = @_; $self->cb_take_quoted($token); $self->cb_send_mapkey; } sub cb_send_plain_multi { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $stack }, [ scalar => $info ]; $self->cb_send_scalar; } sub cb_start_plain { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $stack }, [ scalar => $info ]; } sub cb_start_flowseq { my ($self, $token) = @_; $self->start_flow_sequence($token->{column}); } sub cb_start_flowmap { my ($self, $token) = @_; $self->start_flow_mapping($token->{column}); } sub cb_end_flowseq { my ($self, $res) = @_; $self->cb_send_scalar; $self->end_flow_sequence; $self->set_new_node(0); } sub cb_flow_comma { my ($self) = @_; my $event_types = $self->events; $self->set_new_node(0); if ($event_types->[-1] =~ m/^FLOWSEQ/) { $self->cb_send_scalar; $event_types->[-1] = $next_event{ $event_types->[-1] }; } } sub cb_flow_colon { my ($self) = @_; $self->set_new_node(1); } sub cb_empty_flow_mapkey { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => '', offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->scalar_event($info); } sub cb_end_flowmap { my ($self, $res) = @_; $self->end_flow_mapping; $self->set_new_node(0); } sub cb_end_flowmap_empty { my ($self, $res) = @_; $self->cb_empty_flowmap_value; $self->end_flow_mapping; $self->set_new_node(0); } sub cb_flowkey_plain { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->scalar_event($info); } sub cb_flowkey_quoted { my ($self, $token) = @_; my $stack = $self->event_stack; my $subtokens = $token->{subtokens}; my $info = { style => $subtokens->[0]->{value} eq '"' ? YAML_DOUBLE_QUOTED_SCALAR_STYLE : YAML_SINGLE_QUOTED_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->scalar_event($info); } sub cb_empty_flowmap_key_value { my ($self, $token) = @_; $self->cb_empty_flow_mapkey($token); $self->cb_empty_flowmap_value; $self->cb_flow_comma; } sub cb_end_empty_flowmap_key_value { my ($self, $token) = @_; $self->cb_empty_flow_mapkey($token); $self->cb_empty_flowmap_value; $self->cb_flow_comma; $self->cb_end_flowmap; } sub cb_empty_flowmap_value { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => '', offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->scalar_event($info); } sub cb_empty_flowseq_comma { my ($self, $token) = @_; $self->cb_empty_flowmap_value($token); $self->cb_flow_comma; } sub cb_empty_flowseq_end { my ($self, $token) = @_; $self->cb_empty_flowmap_value($token); $self->cb_end_flowseq; } sub cb_insert_map_alias { my ($self, $res) = @_; my $stack = $self->event_stack; my $scalar = pop @$stack; my $info = $scalar->[1]; $self->start_mapping($info->{offset}); $self->alias_event($info); $self->set_new_node(1); } sub cb_insert_map { my ($self, $res) = @_; my $stack = $self->event_stack; my $scalar = pop @$stack; my $info = $scalar->[1]; $self->start_mapping($info->{offset}); $self->scalar_event($info); $self->set_new_node(1); } sub cb_insert_implicit_flowseq_map { my ($self, $res) = @_; my $stack = $self->event_stack; my $scalar = pop @$stack; my $info = $scalar->[1]; $self->start_flow_mapping($info->{offset}, 1); $self->scalar_event($info); $self->set_new_node(1); } sub cb_insert_empty_implicit_flowseq_map { my ($self, $res) = @_; my $stack = $self->event_stack; my $scalar = pop @$stack; my $info = $scalar->[1]; $self->start_flow_mapping($info->{offset}, 1); $self->cb_empty_flowmap_value; $self->set_new_node(2); } sub cb_insert_empty_map { my ($self, $token) = @_; my $stack = $self->event_stack; my $info = { style => YAML_PLAIN_SCALAR_STYLE, value => '', offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } $self->start_mapping($info->{offset}); $self->scalar_event($info); $self->set_new_node(1); } sub cb_send_block_scalar { my ($self, $token) = @_; my $type = $token->{subtokens}->[0]->{value}; my $stack = $self->event_stack; my $info = { style => $type eq '|' ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE, value => $token->{value}, offset => $token->{column}, }; if (@$stack and $stack->[-1]->[0] eq 'properties') { $self->fetch_inline_properties($stack, $info); } push @{ $self->event_stack }, [ scalar => $info ]; $self->cb_send_scalar; } sub cb_end_document { my ($self, $token) = @_; $self->end_document(0); } sub cb_end_document_empty { my ($self, $token) = @_; $self->end_document(0); } sub cb_doc_start_implicit { my ($self, $token) = @_; $self->start_document(1); } sub cb_doc_start_explicit { my ($self, $token) = @_; $self->start_document(0); } sub cb_end_doc_start_document { my ($self, $token) = @_; $self->end_document(1); $self->start_document(0); } sub cb_tag_directive { my ($self, $token) = @_; my ($name, $tag_alias, $tag_url) = split ' ', $token->{value}; $self->tagmap->{ $tag_alias } = $tag_url; } sub cb_reserved_directive { } sub cb_set_yaml_version_directive { my ($self, $token) = @_; if ($self->yaml_version_directive) { croak "Found duplicate YAML directive"; } my ($version) = $token->{value} =~ m/^%YAML[ \t]+(1\.[12])/; $self->set_yaml_version($version || '1.2'); $self->set_yaml_version_directive(1); } 1; 07070100000039000081A40000000000000000000000016616D6BA000005F5000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Perl.pmuse strict; use warnings; package YAML::PP::Perl; our $VERSION = '0.000'; # VERSION use base 'Exporter'; use base 'YAML::PP'; our @EXPORT_OK = qw/ Load Dump LoadFile DumpFile /; use YAML::PP; use YAML::PP::Schema::Perl; sub new { my ($class, %args) = @_; $args{schema} ||= [qw/ Core Perl /]; $class->SUPER::new(%args); } sub Load { my ($yaml) = @_; __PACKAGE__->new->load_string($yaml); } sub LoadFile { my ($file) = @_; __PACKAGE__->new->load_file($file); } sub Dump { my (@data) = @_; __PACKAGE__->new->dump_string(@data); } sub DumpFile { my ($file, @data) = @_; __PACKAGE__->new->dump_file($file, @data); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Perl - Convenience module for loading and dumping Perl objects =head1 SYNOPSIS use YAML::PP::Perl; my @docs = YAML::PP::Perl->new->load_string($yaml); my @docs = YAML::PP::Perl::Load($yaml); # same as use YAML::PP; my $yp = YAML::PP->new( schema => [qw/ Core Perl /] ); my @docs = $yp->load_string($yaml); =head1 DESCRIPTION This is just for convenience. It will create a YAML::PP object using the default schema (C<Core>) and the L<YAML::PP::Schema::Perl> schema. See L<YAML::PP::Schema::Perl> for documentation. =head1 METHODS =over =item Load, Dump, LoadFile, DumpFile These work like the functions in L<YAML::PP>, just adding the C<Perl> schema. =item new Constructor, works like in L<YAML::PP>, just adds the C<Perl> schema to the list of arguments. =back 0707010000003A000081A40000000000000000000000016616D6BA00000608000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Reader.pm# ABSTRACT: Reader class for YAML::PP representing input data use strict; use warnings; package YAML::PP::Reader; our $VERSION = '0.000'; # VERSION sub input { return $_[0]->{input} } sub set_input { $_[0]->{input} = $_[1] } sub new { my ($class, %args) = @_; my $input = delete $args{input}; return bless { input => $input, }, $class; } sub read { my ($self) = @_; my $pos = pos $self->{input} || 0; my $yaml = substr($self->{input}, $pos); $self->{input} = ''; return $yaml; } sub readline { my ($self) = @_; unless (length $self->{input}) { return; } if ( $self->{input} =~ m/\G([^\r\n]*(?:\n|\r\n|\r|\z))/g ) { my $line = $1; unless (length $line) { $self->{input} = ''; return; } return $line; } return; } package YAML::PP::Reader::File; use Scalar::Util qw/ openhandle /; our @ISA = qw/ YAML::PP::Reader /; use Carp qw/ croak /; sub open_handle { if (openhandle( $_[0]->{input} )) { return $_[0]->{input}; } open my $fh, '<:encoding(UTF-8)', $_[0]->{input} or croak "Could not open '$_[0]->{input}' for reading: $!"; return $fh; } sub read { my $fh = $_[0]->{filehandle} ||= $_[0]->open_handle; if (wantarray) { my @yaml = <$fh>; return @yaml; } else { local $/; my $yaml = <$fh>; return $yaml; } } sub readline { my $fh = $_[0]->{filehandle} ||= $_[0]->open_handle; return scalar <$fh>; } 1; 0707010000003B000081A40000000000000000000000016616D6BA00000E2F000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Render.pm# ABSTRACT: YAML::PP Rendering functions use strict; use warnings; package YAML::PP::Render; our $VERSION = '0.000'; # VERSION use constant TRACE => $ENV{YAML_PP_TRACE} ? 1 : 0; sub render_quoted { my ($self, $style, $lines) = @_; my $quoted = ''; my $addspace = 0; for my $i (0 .. $#$lines) { my $line = $lines->[ $i ]; my $value = $line->{value}; my $last = $i == $#$lines; my $first = $i == 0; if ($value eq '') { if ($first) { $addspace = 1; } elsif ($last) { $quoted .= ' ' if $addspace; } else { $addspace = 0; $quoted .= "\n"; } next; } $quoted .= ' ' if $addspace; $addspace = 1; if ($style eq '"') { if ($line->{orig} =~ m/\\$/) { $line->{value} =~ s/\\$//; $value =~ s/\\$//; $addspace = 0; } } $quoted .= $value; } return $quoted; } sub render_block_scalar { my ($self, $block_type, $chomp, $lines) = @_; my ($folded, $keep, $trim); if ($block_type eq '>') { $folded = 1; } if ($chomp eq '+') { $keep = 1; } elsif ($chomp eq '-') { $trim = 1; } my $string = ''; if (not $keep) { # remove trailing empty lines while (@$lines) { last if $lines->[-1] ne ''; pop @$lines; } } if ($folded) { my $prev = 'START'; my $trailing = ''; if ($keep) { while (@$lines and $lines->[-1] eq '') { pop @$lines; $trailing .= "\n"; } } for my $i (0 .. $#$lines) { my $line = $lines->[ $i ]; my $type = $line eq '' ? 'EMPTY' : $line =~ m/\A[ \t]/ ? 'MORE' : 'CONTENT'; if ($prev eq 'MORE' and $type eq 'EMPTY') { $type = 'MORE'; } elsif ($prev eq 'CONTENT') { if ($type ne 'CONTENT') { $string .= "\n"; } elsif ($type eq 'CONTENT') { $string .= ' '; } } elsif ($prev eq 'START' and $type eq 'EMPTY') { $string .= "\n"; $type = 'START'; } elsif ($prev eq 'EMPTY' and $type ne 'CONTENT') { $string .= "\n"; } $string .= $line; if ($type eq 'MORE' and $i < $#$lines) { $string .= "\n"; } $prev = $type; } if ($keep) { $string .= $trailing; } $string .= "\n" if @$lines and not $trim; } else { for my $i (0 .. $#$lines) { $string .= $lines->[ $i ]; $string .= "\n" if ($i != $#$lines or not $trim); } } TRACE and warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$string], ['string']); return $string; } sub render_multi_val { my ($self, $multi) = @_; my $string = ''; my $start = 1; for my $line (@$multi) { if (not $start) { if ($line eq '') { $string .= "\n"; $start = 1; } else { $string .= " $line"; } } else { $string .= $line; $start = 0; } } return $string; } 1; 0707010000003C000081A40000000000000000000000016616D6BA00001BDA000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Representer.pmuse strict; use warnings; package YAML::PP::Representer; our $VERSION = '0.000'; # VERSION use Scalar::Util qw/ reftype blessed refaddr /; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE YAML_DOUBLE_QUOTED_SCALAR_STYLE YAML_ANY_SCALAR_STYLE YAML_LITERAL_SCALAR_STYLE YAML_FOLDED_SCALAR_STYLE YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE YAML_BLOCK_MAPPING_STYLE YAML_BLOCK_SEQUENCE_STYLE PRESERVE_ORDER PRESERVE_SCALAR_STYLE PRESERVE_FLOW_STYLE PRESERVE_ALIAS /; use B; sub new { my ($class, %args) = @_; my $preserve = delete $args{preserve} || 0; if ($preserve == 1) { $preserve = PRESERVE_ORDER | PRESERVE_SCALAR_STYLE | PRESERVE_FLOW_STYLE | PRESERVE_ALIAS; } my $self = bless { schema => delete $args{schema}, preserve => $preserve, }, $class; if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } return $self; } sub clone { my ($self) = @_; my $clone = { schema => $self->schema, preserve => $self->{preserve}, }; return bless $clone, ref $self; } sub schema { return $_[0]->{schema} } sub preserve_order { return $_[0]->{preserve} & PRESERVE_ORDER } sub preserve_scalar_style { return $_[0]->{preserve} & PRESERVE_SCALAR_STYLE } sub preserve_flow_style { return $_[0]->{preserve} & PRESERVE_FLOW_STYLE } sub preserve_alias { return $_[0]->{preserve} & PRESERVE_ALIAS } sub represent_node { my ($self, $node) = @_; my $preserve_alias = $self->preserve_alias; my $preserve_style = $self->preserve_scalar_style; if ($preserve_style or $preserve_alias) { if (ref $node->{value} eq 'YAML::PP::Preserve::Scalar') { my $value = $node->{value}->value; if ($preserve_style) { $node->{style} = $node->{value}->style; } # $node->{tag} = $node->{value}->tag; $node->{value} = $value; } } $node->{reftype} = reftype($node->{value}); if (not $node->{reftype} and reftype(\$node->{value}) eq 'GLOB') { $node->{reftype} = 'GLOB'; } if ($node->{reftype}) { $self->_represent_noderef($node); } else { $self->_represent_node_nonref($node); } $node->{reftype} = (reftype $node->{data}) || ''; if ($node->{reftype} eq 'HASH' and my $tied = tied(%{ $node->{data} })) { my $representers = $self->schema->representers; $tied = ref $tied; if (my $def = $representers->{tied_equals}->{ $tied }) { my $code = $def->{code}; my $done = $code->($self, $node); } } if ($node->{reftype} eq 'HASH') { unless (defined $node->{items}) { # by default we sort hash keys my @keys; if ($self->preserve_order) { @keys = keys %{ $node->{data} }; } else { @keys = sort keys %{ $node->{data} }; } for my $key (@keys) { push @{ $node->{items} }, $key, $node->{data}->{ $key }; } } my %args; if ($self->preserve_flow_style and reftype $node->{value} eq 'HASH') { if (my $tied = tied %{ $node->{value} } ) { $args{style} = $tied->{style}; } } return [ mapping => $node, %args ]; } elsif ($node->{reftype} eq 'ARRAY') { unless (defined $node->{items}) { @{ $node->{items} } = @{ $node->{data} }; } my %args; if ($self->preserve_flow_style and reftype $node->{value} eq 'ARRAY') { if (my $tied = tied @{ $node->{value} } ) { $args{style} = $tied->{style}; } } return [ sequence => $node, %args ]; } elsif ($node->{reftype}) { die "Cannot handle reftype '$node->{reftype}' (you might want to enable YAML::PP::Schema::Perl)"; } else { unless (defined $node->{items}) { $node->{items} = [$node->{data}]; } return [ scalar => $node ]; } } my $bool_code = <<'EOM'; sub { my ($x) = @_; use experimental qw/ builtin /; builtin::is_bool($x); } EOM my $is_bool; sub _represent_node_nonref { my ($self, $node) = @_; my $representers = $self->schema->representers; if (not defined $node->{value}) { if (my $undef = $representers->{undef}) { return 1 if $undef->($self, $node); } else { $node->{style} = YAML_SINGLE_QUOTED_SCALAR_STYLE; $node->{data} = ''; return 1; } } if ($] >= 5.036000 and my $rep = $representers->{bool}) { $is_bool ||= eval $bool_code; if ($is_bool->($node->{value})) { return $rep->{code}->($self, $node); } } for my $rep (@{ $representers->{flags} }) { my $check_flags = $rep->{flags}; my $flags = B::svref_2object(\$node->{value})->FLAGS; if ($flags & $check_flags) { return 1 if $rep->{code}->($self, $node); } } if (my $rep = $representers->{equals}->{ $node->{value} }) { return 1 if $rep->{code}->($self, $node); } for my $rep (@{ $representers->{regex} }) { if ($node->{value} =~ $rep->{regex}) { return 1 if $rep->{code}->($self, $node); } } unless (defined $node->{data}) { $node->{data} = $node->{value}; } unless (defined $node->{style}) { $node->{style} = YAML_ANY_SCALAR_STYLE; $node->{style} = ""; } } sub _represent_noderef { my ($self, $node) = @_; my $representers = $self->schema->representers; if (my $classname = blessed($node->{value})) { if (my $def = $representers->{class_equals}->{ $classname }) { my $code = $def->{code}; return 1 if $code->($self, $node); } for my $matches (@{ $representers->{class_matches} }) { my ($re, $code) = @$matches; if (ref $re and $classname =~ $re or $re) { return 1 if $code->($self, $node); } } for my $isa (@{ $representers->{class_isa} }) { my ($class_name, $code) = @$isa; if ($node->{ value }->isa($class_name)) { return 1 if $code->($self, $node); } } } if ($node->{reftype} eq 'SCALAR' and my $scalarref = $representers->{scalarref}) { my $code = $scalarref->{code}; return 1 if $code->($self, $node); } if ($node->{reftype} eq 'REF' and my $refref = $representers->{refref}) { my $code = $refref->{code}; return 1 if $code->($self, $node); } if ($node->{reftype} eq 'CODE' and my $coderef = $representers->{coderef}) { my $code = $coderef->{code}; return 1 if $code->($self, $node); } if ($node->{reftype} eq 'GLOB' and my $glob = $representers->{glob}) { my $code = $glob->{code}; return 1 if $code->($self, $node); } $node->{data} = $node->{value}; } 1; 0707010000003D000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema0707010000003E000081A40000000000000000000000016616D6BA00002D61000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema.pmuse strict; use warnings; package YAML::PP::Schema; use B; use Module::Load qw//; our $VERSION = '0.000'; # VERSION use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE /; use Scalar::Util qw/ blessed /; sub new { my ($class, %args) = @_; my $yaml_version = delete $args{yaml_version}; my $bool = delete $args{boolean}; $bool = 'perl' unless defined $bool; if (keys %args) { die "Unexpected arguments: " . join ', ', sort keys %args; } my $true; my $false; my @bool_class; my @bools = split m/,/, $bool; for my $b (@bools) { if ($b eq '*') { push @bool_class, ('boolean', 'JSON::PP::Boolean'); last; } elsif ($b eq 'JSON::PP') { require JSON::PP; $true ||= \&_bool_jsonpp_true; $false ||= \&_bool_jsonpp_false; push @bool_class, 'JSON::PP::Boolean'; } elsif ($b eq 'boolean') { require boolean; $true ||= \&_bool_booleanpm_true; $false ||= \&_bool_booleanpm_false; push @bool_class, 'boolean'; } elsif ($b eq 'perl' or $b eq 'perl_experimental') { push @bool_class, 'perl'; } else { die "Invalid value for 'boolean': '$b'. Allowed: ('perl', 'boolean', 'JSON::PP')"; } } # Ensure booleans are resolved $true ||= \&_bool_perl_true; $false ||= \&_bool_perl_false; my %representers = ( 'undef' => undef, flags => [], equals => {}, regex => [], class_equals => {}, class_matches => [], class_isa => [], scalarref => undef, refref => undef, coderef => undef, glob => undef, tied_equals => {}, bool => undef, ); my $self = bless { yaml_version => $yaml_version, resolvers => {}, representers => \%representers, true => $true, false => $false, bool_class => \@bool_class, }, $class; return $self; } sub resolvers { return $_[0]->{resolvers} } sub representers { return $_[0]->{representers} } sub true { return $_[0]->{true} } sub false { return $_[0]->{false} } sub bool_class { return @{ $_[0]->{bool_class} } ? $_[0]->{bool_class} : undef } sub yaml_version { return $_[0]->{yaml_version} } my %LOADED_SCHEMA = ( JSON => 1, ); my %DEFAULT_SCHEMA = ( '1.2' => 'Core', '1.1' => 'YAML1_1', ); sub load_subschemas { my ($self, @schemas) = @_; my $yaml_version = $self->yaml_version; my $i = 0; while ($i < @schemas) { my $item = $schemas[ $i ]; if ($item eq '+') { $item = $DEFAULT_SCHEMA{ $yaml_version }; } $i++; if (blessed($item)) { $item->register( schema => $self, ); next; } my @options; while ($i < @schemas and ( $schemas[ $i ] =~ m/^[^A-Za-z]/ or $schemas[ $i ] =~ m/^[a-zA-Z0-9]+=/ ) ) { push @options, $schemas[ $i ]; $i++; } my $class; if ($item =~ m/^\:(.*)/) { $class = "$1"; unless ($class =~ m/\A[A-Za-z0-9_:]+\z/) { die "Module name '$class' is invalid"; } Module::Load::load $class; } else { $class = "YAML::PP::Schema::$item"; unless ($class =~ m/\A[A-Za-z0-9_:]+\z/) { die "Module name '$class' is invalid"; } $LOADED_SCHEMA{ $item } ||= Module::Load::load $class; } $class->register( schema => $self, options => \@options, ); } } sub add_resolver { my ($self, %args) = @_; my $tag = $args{tag}; my $rule = $args{match}; my $resolvers = $self->resolvers; my ($type, @rule) = @$rule; my $implicit = $args{implicit}; $implicit = 1 unless defined $implicit; my $resolver_list = []; if ($tag) { if (ref $tag eq 'Regexp') { my $res = $resolvers->{tags} ||= []; push @$res, [ $tag, {} ]; push @$resolver_list, $res->[-1]->[1]; } else { my $res = $resolvers->{tag}->{ $tag } ||= {}; push @$resolver_list, $res; } } if ($implicit) { push @$resolver_list, $resolvers->{value} ||= {}; } for my $res (@$resolver_list) { if ($type eq 'equals') { my ($match, $value) = @rule; unless (exists $res->{equals}->{ $match }) { $res->{equals}->{ $match } = $value; } next; } elsif ($type eq 'regex') { my ($match, $value) = @rule; push @{ $res->{regex} }, [ $match => $value ]; } elsif ($type eq 'all') { my ($value) = @rule; $res->{all} = $value; } } } sub add_sequence_resolver { my ($self, %args) = @_; return $self->add_collection_resolver(sequence => %args); } sub add_mapping_resolver { my ($self, %args) = @_; return $self->add_collection_resolver(mapping => %args); } sub add_collection_resolver { my ($self, $type, %args) = @_; my $tag = $args{tag}; my $implicit = $args{implicit}; my $resolvers = $self->resolvers; if ($tag and ref $tag eq 'Regexp') { my $res = $resolvers->{ $type }->{tags} ||= []; push @$res, [ $tag, { on_create => $args{on_create}, on_data => $args{on_data}, } ]; } elsif ($tag) { my $res = $resolvers->{ $type }->{tag}->{ $tag } ||= { on_create => $args{on_create}, on_data => $args{on_data}, }; } } sub add_representer { my ($self, %args) = @_; my $representers = $self->representers; if (my $flags = $args{flags}) { my $rep = $representers->{flags}; push @$rep, \%args; return; } if (my $regex = $args{regex}) { my $rep = $representers->{regex}; push @$rep, \%args; return; } if (my $regex = $args{class_matches}) { my $rep = $representers->{class_matches}; push @$rep, [ $args{class_matches}, $args{code} ]; return; } if (my $bool = $args{bool} and $] >= 5.036000) { $representers->{bool} = { code => $args{code}, }; return; } if (my $class_equals = $args{class_equals}) { my $rep = $representers->{class_equals}; $rep->{ $class_equals } = { code => $args{code}, }; return; } if (my $class_isa = $args{class_isa}) { my $rep = $representers->{class_isa}; push @$rep, [ $args{class_isa}, $args{code} ]; return; } if (my $tied_equals = $args{tied_equals}) { my $rep = $representers->{tied_equals}; $rep->{ $tied_equals } = { code => $args{code}, }; return; } if (defined(my $equals = $args{equals})) { my $rep = $representers->{equals}; $rep->{ $equals } = { code => $args{code}, }; return; } if (defined(my $scalarref = $args{scalarref})) { $representers->{scalarref} = { code => $args{code}, }; return; } if (defined(my $refref = $args{refref})) { $representers->{refref} = { code => $args{code}, }; return; } if (defined(my $coderef = $args{coderef})) { $representers->{coderef} = { code => $args{code}, }; return; } if (defined(my $glob = $args{glob})) { $representers->{glob} = { code => $args{code}, }; return; } if (my $undef = $args{undefined}) { $representers->{undef} = $undef; return; } } sub load_scalar { my ($self, $constructor, $event) = @_; my $tag = $event->{tag}; my $value = $event->{value}; my $resolvers = $self->resolvers; my $res; if ($tag) { $res = $resolvers->{tag}->{ $tag }; if (not $res and my $matches = $resolvers->{tags}) { for my $match (@$matches) { my ($re, $rule) = @$match; if ($tag =~ $re) { $res = $rule; last; } } } } else { $res = $resolvers->{value}; if ($event->{style} ne YAML_PLAIN_SCALAR_STYLE) { return $value; } } if (my $equals = $res->{equals}) { if (exists $equals->{ $value }) { my $res = $equals->{ $value }; if (ref $res eq 'CODE') { return $res->($constructor, $event); } return $res; } } if (my $regex = $res->{regex}) { for my $item (@$regex) { my ($re, $sub) = @$item; my @matches = $value =~ $re; if (@matches) { return $sub->($constructor, $event, \@matches); } } } if (my $catch_all = $res->{all}) { if (ref $catch_all eq 'CODE') { return $catch_all->($constructor, $event); } return $catch_all; } return $value; } sub create_sequence { my ($self, $constructor, $event) = @_; my $tag = $event->{tag}; my $data = []; my $on_data; my $resolvers = $self->resolvers->{sequence}; if ($tag) { if (my $equals = $resolvers->{tag}->{ $tag }) { my $on_create = $equals->{on_create}; $on_data = $equals->{on_data}; $on_create and $data = $on_create->($constructor, $event); return ($data, $on_data); } if (my $matches = $resolvers->{tags}) { for my $match (@$matches) { my ($re, $actions) = @$match; my $on_create = $actions->{on_create}; if ($tag =~ $re) { $on_data = $actions->{on_data}; $on_create and $data = $on_create->($constructor, $event); return ($data, $on_data); } } } } return ($data, $on_data); } sub create_mapping { my ($self, $constructor, $event) = @_; my $tag = $event->{tag}; my $data = {}; my $on_data; my $resolvers = $self->resolvers->{mapping}; if ($tag) { if (my $equals = $resolvers->{tag}->{ $tag }) { my $on_create = $equals->{on_create}; $on_data = $equals->{on_data}; $on_create and $data = $on_create->($constructor, $event); return ($data, $on_data); } if (my $matches = $resolvers->{tags}) { for my $match (@$matches) { my ($re, $actions) = @$match; my $on_create = $actions->{on_create}; if ($tag =~ $re) { $on_data = $actions->{on_data}; $on_create and $data = $on_create->($constructor, $event); return ($data, $on_data); } } } } return ($data, $on_data); } sub _bool_jsonpp_true { JSON::PP::true() } sub _bool_booleanpm_true { boolean::true() } sub _bool_perl_true { !!1 } sub _bool_jsonpp_false { JSON::PP::false() } sub _bool_booleanpm_false { boolean::false() } sub _bool_perl_false { !!0 } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema - Schema for YAML::PP 0707010000003F000081A40000000000000000000000016616D6BA00000A1C000000000000000000000000000000000000004200000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Binary.pmuse strict; use warnings; package YAML::PP::Schema::Binary; our $VERSION = '0.000'; # VERSION use MIME::Base64 qw/ decode_base64 encode_base64 /; use YAML::PP::Common qw/ YAML_ANY_SCALAR_STYLE /; sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_resolver( tag => 'tag:yaml.org,2002:binary', match => [ all => sub { my ($constructor, $event) = @_; my $base64 = $event->{value}; my $binary = decode_base64($base64); return $binary; }], implicit => 0, ); $schema->add_representer( regex => qr{.*}, code => sub { my ($rep, $node) = @_; my $binary = $node->{value}; unless ($binary =~ m/[\x{7F}-\x{10FFFF}]/) { # ASCII return; } if (utf8::is_utf8($binary)) { # utf8 return; } # everything else must be base64 encoded my $base64 = encode_base64($binary); $node->{style} = YAML_ANY_SCALAR_STYLE; $node->{data} = $base64; $node->{tag} = "tag:yaml.org,2002:binary"; return 1; }, ); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Binary - Schema for loading and binary data =head1 SYNOPSIS use YAML::PP; my $yp = YAML::PP->new( schema => [qw/ + Binary /] ); # or my ($binary, $same_binary) = $yp->load_string(<<'EOM'); --- !!binary "\ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" --- !!binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= # The binary value above is a tiny arrow encoded as a gif image. EOM =head1 DESCRIPTION See <https://yaml.org/type/binary.html> By prepending a base64 encoded binary string with the C<!!binary> tag, it can be automatically decoded when loading. Note that the logic for dumping is probably broken, see L<https://github.com/perlpunk/YAML-PP-p5/issues/28>. Suggestions welcome. =head1 METHODS =over =item register Called by L<YAML::PP::Schema> =back =cut 07070100000040000081A40000000000000000000000016616D6BA00001015000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Core.pmuse strict; use warnings; package YAML::PP::Schema::Core; our $VERSION = '0.000'; # VERSION use YAML::PP::Schema::JSON qw/ represent_int represent_float represent_literal represent_bool represent_undef /; use B; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE /; my $RE_INT_CORE = qr{^([+-]?(?:[0-9]+))$}; my $RE_FLOAT_CORE = qr{^([+-]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)(?:[eE][+-]?[0-9]+)?)$}; my $RE_INT_OCTAL = qr{^0o([0-7]+)$}; my $RE_INT_HEX = qr{^0x([0-9a-fA-F]+)$}; sub _from_oct { oct $_[2]->[0] } sub _from_hex { hex $_[2]->[0] } sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_resolver( tag => 'tag:yaml.org,2002:null', match => [ equals => $_ => undef ], ) for (qw/ null NULL Null ~ /, ''); $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => $_ => $schema->true ], ) for (qw/ true TRUE True /); $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => $_ => $schema->false ], ) for (qw/ false FALSE False /); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_CORE => \&YAML::PP::Schema::JSON::_to_int ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_OCTAL => \&_from_oct ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_HEX => \&_from_hex ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ regex => $RE_FLOAT_CORE => \&YAML::PP::Schema::JSON::_to_float ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 + "inf" ], ) for (qw/ .inf .Inf .INF +.inf +.Inf +.INF /); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 - "inf" ], ) for (qw/ -.inf -.Inf -.INF /); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 + "nan" ], ) for (qw/ .nan .NaN .NAN /); $schema->add_resolver( tag => 'tag:yaml.org,2002:str', match => [ all => sub { $_[1]->{value} } ], ); my $int_flags = B::SVp_IOK; my $float_flags = B::SVp_NOK; $schema->add_representer( flags => $int_flags, code => \&represent_int, ); $schema->add_representer( flags => $float_flags, code => \&represent_float, ); $schema->add_representer( undefined => \&represent_undef, ); $schema->add_representer( equals => $_, code => \&represent_literal, ) for ("", qw/ true TRUE True false FALSE False null NULL Null ~ .inf .Inf .INF +.inf +.Inf +.INF -.inf -.Inf -.INF .nan .NaN .NAN /); $schema->add_representer( regex => qr{$RE_INT_CORE|$RE_FLOAT_CORE|$RE_INT_OCTAL|$RE_INT_HEX}, code => \&represent_literal, ); if ($schema->bool_class) { for my $class (@{ $schema->bool_class }) { if ($class eq 'perl') { $schema->add_representer( bool => 1, code => \&represent_bool, ); next; } $schema->add_representer( class_equals => $class, code => \&represent_bool, ); } } return; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Core - YAML 1.2 Core Schema =head1 SYNOPSIS my $yp = YAML::PP->new( schema => ['Core'] ); =head1 DESCRIPTION This schema is the official recommended Core Schema for YAML 1.2. It loads additional values to the JSON schema as special types, for example C<TRUE> and C<True> additional to C<true>. Official Schema: L<https://yaml.org/spec/1.2/spec.html#id2804923> Here you can see all Schemas and examples implemented by YAML::PP: L<https://perlpunk.github.io/YAML-PP-p5/schemas.html> =head1 METHODS =over =item register Called by YAML::PP::Schema =back =cut 07070100000041000081A40000000000000000000000016616D6BA000002E5000000000000000000000000000000000000004400000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Failsafe.pmuse strict; use warnings; package YAML::PP::Schema::Failsafe; our $VERSION = '0.000'; # VERSION sub register { my ($self, %args) = @_; return; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Failsafe - YAML 1.2 Failsafe Schema =head1 SYNOPSIS my $yp = YAML::PP->new( schema => ['Failsafe'] ); =head1 DESCRIPTION With this schema, everything will be treated as a string. There are no booleans, integers, floats or undefined values. Here you can see all Schemas and examples implemented by YAML::PP: L<https://perlpunk.github.io/YAML-PP-p5/schemas.html> Official Schema: L<https://yaml.org/spec/1.2/spec.html#id2802346> =head1 METHODS =over =item register Called by YAML::PP::Schema =back =cut 07070100000042000081A40000000000000000000000016616D6BA0000195C000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Include.pmuse strict; use warnings; package YAML::PP::Schema::Include; our $VERSION = '0.000'; # VERSION use Carp qw/ croak /; use Scalar::Util qw/ weaken /; use File::Basename qw/ dirname /; sub new { my ($class, %args) = @_; my $paths = delete $args{paths}; if (defined $paths) { unless (ref $paths eq 'ARRAY') { $paths = [$paths]; } } else { $paths = []; } my $allow_absolute = $args{allow_absolute} || 0; my $loader = $args{loader} || \&default_loader; my $self = bless { paths => $paths, allow_absolute => $allow_absolute, last_includes => [], cached => {}, loader => $loader, }, $class; return $self; } sub init { my ($self) = @_; $self->{last_includes} = []; $self->{cached} = []; } sub paths { $_[0]->{paths} } sub allow_absolute { $_[0]->{allow_absolute} } sub yp { my ($self, $yp) = @_; if (@_ == 2) { $self->{yp} = $yp; weaken $self->{yp}; return $yp; } return $self->{yp}; } sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_resolver( tag => '!include', match => [ all => sub { $self->include(@_) } ], implicit => 0, ); } sub include { my ($self, $constructor, $event) = @_; my $yp = $self->yp; my $search_paths = $self->paths; my $allow_absolute = $self->allow_absolute; my $relative = not @$search_paths; if ($relative) { my $last_includes = $self->{last_includes}; if (@$last_includes) { $search_paths = [ $last_includes->[-1] ]; } else { # we are in the top-level file and need to look into # the original YAML::PP instance my $filename = $yp->loader->filename; $search_paths = [dirname $filename]; } } my $filename = $event->{value}; my $fullpath; if (File::Spec->file_name_is_absolute($filename)) { unless ($allow_absolute) { croak "Absolute filenames not allowed"; } $fullpath = $filename; } else { my @paths = File::Spec->splitdir($filename); unless ($allow_absolute) { # if absolute paths are not allowed, we also may not use upwards .. @paths = File::Spec->no_upwards(@paths); } for my $candidate (@$search_paths) { my $test = File::Spec->catfile( $candidate, @paths ); if (-e $test) { $fullpath = $test; last; } } croak "File '$filename' not found" unless defined $fullpath; } if ($self->{cached}->{ $fullpath }++) { croak "Circular include '$fullpath'"; } if ($relative) { push @{ $self->{last_includes} }, dirname $fullpath; } # We need a new object because we are still in the parsing and # constructing process my $clone = $yp->clone; my ($data) = $self->loader->($clone, $fullpath); if ($relative) { pop @{ $self->{last_includes} }; } unless (--$self->{cached}->{ $fullpath }) { delete $self->{cached}->{ $fullpath }; } return $data; } sub loader { my ($self, $code) = @_; if (@_ == 2) { $self->{loader} = $code; return $code; } return $self->{loader}; } sub default_loader { my ($yp, $filename) = @_; $yp->load_file($filename); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Include - Include YAML files =head1 SYNOPSIS # /path/to/file.yaml # --- # included: !include include/file2.yaml # /path/to/include/file2.yaml # --- # a: b my $include = YAML::PP::Schema::Include->new; my $yp = YAML::PP->new( schema => ['+', $include] ); # we need the original YAML::PP object for getting the current filename # and for loading another file $include->yp($yp); my ($data) = $yp->load_file("/path/to/file.yaml"); # The result will be: $data = { included => { a => 'b' } }; Allow absolute filenames and upwards C<'..'>: my $include = YAML::PP::Schema::Include->new( allow_absolute => 1, # default: 0 ); Specify paths to search for includes: my @include_paths = ("/path/to/include/yaml/1", "/path/to/include/yaml/2"); my $include = YAML::PP::Schema::Include->new( paths => \@include_paths, ); my $yp = YAML::PP->new( schema => ['+', $include] ); $include->yp($yp); # /path/to/include/yaml/1/file1.yaml # --- # a: b my $yaml = <<'EOM'; - included: !include file1.yaml EOM my ($data) = $yp->load_string($yaml); =head1 DESCRIPTION This plugin allows you to split a large YAML file into smaller ones. You can then include these files with the C<!include> tag. It will search for the specified filename relative to the currently processed filename. You can also specify the paths where to search for files to include. It iterates through the paths and returns the first filename that exists. By default, only relative paths are allowed. Any C<../> in the path will be removed. You can change that behaviour by setting the option C<allow_absolute> to true. If the included file contains more than one document, only the first one will be included. I will probably add a possibility to return all documents as an arrayref. The included YAML file will be loaded by creating a new L<YAML::PP> object with the schema from the existing object. This way you can recursively include files. You can even reuse the same include via an alias: --- invoice: shipping address: &address !include address.yaml billing address: *address Circular includes will be detected, and will be fatal. It's possible to specify what to do with the included file: my $include = YAML::PP::Schema::Include->new( loader => sub { my ($yp, $filename); if ($filename =~ m/\.txt$/) { # open file and just return text } else { # default behaviour return $yp->load_file($filename); } }, ); For example, RAML defines an C<!include> tag which depends on the file content. If it contains a special RAML directive, it will be loaded as YAML, otherwise the content of the file will be included as a string. So with this plugin you are able to read RAML specifications. =cut 07070100000043000081A40000000000000000000000016616D6BA00001896000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/JSON.pmuse strict; use warnings; package YAML::PP::Schema::JSON; our $VERSION = '0.000'; # VERSION use base 'Exporter'; our @EXPORT_OK = qw/ represent_int represent_float represent_literal represent_bool represent_undef /; use B; use Carp qw/ croak /; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE YAML_SINGLE_QUOTED_SCALAR_STYLE /; my $RE_INT = qr{^(-?(?:0|[1-9][0-9]*))$}; my $RE_FLOAT = qr{^(-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)$}; sub _to_int { 0 + $_[2]->[0] } # DaTa++ && shmem++ sub _to_float { unpack F => pack F => $_[2]->[0] } sub register { my ($self, %args) = @_; my $schema = $args{schema}; my $options = $args{options}; my $empty_null = 0; for my $opt (@$options) { if ($opt eq 'empty=str') { } elsif ($opt eq 'empty=null') { $empty_null = 1; } else { croak "Invalid option for JSON Schema: '$opt'"; } } $schema->add_resolver( tag => 'tag:yaml.org,2002:null', match => [ equals => null => undef ], ); if ($empty_null) { $schema->add_resolver( tag => 'tag:yaml.org,2002:null', match => [ equals => '' => undef ], implicit => 1, ); } else { $schema->add_resolver( tag => 'tag:yaml.org,2002:str', match => [ equals => '' => '' ], implicit => 1, ); } $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => true => $schema->true ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => false => $schema->false ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT => \&_to_int ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ regex => $RE_FLOAT => \&_to_float ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:str', match => [ all => sub { $_[1]->{value} } ], ); $schema->add_representer( undefined => \&represent_undef, ); my $int_flags = B::SVp_IOK; my $float_flags = B::SVp_NOK; $schema->add_representer( flags => $int_flags, code => \&represent_int, ); my %special = ( (0+'nan').'' => '.nan', (0+'inf').'' => '.inf', (0-'inf').'' => '-.inf' ); $schema->add_representer( flags => $float_flags, code => \&represent_float, ); $schema->add_representer( equals => $_, code => \&represent_literal, ) for ("", qw/ true false null /); $schema->add_representer( regex => qr{$RE_INT|$RE_FLOAT}, code => \&represent_literal, ); if ($schema->bool_class) { for my $class (@{ $schema->bool_class }) { if ($class eq 'perl') { $schema->add_representer( bool => 1, code => \&represent_bool, ); next; } $schema->add_representer( class_equals => $class, code => \&represent_bool, ); } } return; } sub represent_undef { my ($rep, $node) = @_; $node->{style} = YAML_PLAIN_SCALAR_STYLE; $node->{data} = 'null'; return 1; } sub represent_literal { my ($rep, $node) = @_; $node->{style} ||= YAML_SINGLE_QUOTED_SCALAR_STYLE; $node->{data} = "$node->{value}"; return 1; } sub represent_int { my ($rep, $node) = @_; if (int($node->{value}) ne $node->{value}) { return 0; } $node->{style} = YAML_PLAIN_SCALAR_STYLE; $node->{data} = "$node->{value}"; return 1; } my %special = ( (0+'nan').'' => '.nan', (0+'inf').'' => '.inf', (0-'inf').'' => '-.inf' ); sub represent_float { my ($rep, $node) = @_; if (exists $special{ $node->{value} }) { $node->{style} = YAML_PLAIN_SCALAR_STYLE; $node->{data} = $special{ $node->{value} }; return 1; } if (0.0 + $node->{value} ne $node->{value}) { return 0; } if (int($node->{value}) eq $node->{value} and not $node->{value} =~ m/\./) { $node->{value} .= '.0'; } $node->{style} = YAML_PLAIN_SCALAR_STYLE; $node->{data} = "$node->{value}"; return 1; } sub represent_bool { my ($rep, $node) = @_; my $string = $node->{value} ? 'true' : 'false'; $node->{style} = YAML_PLAIN_SCALAR_STYLE; @{ $node->{items} } = $string; $node->{data} = $string; return 1; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::JSON - YAML 1.2 JSON Schema =head1 SYNOPSIS my $yp = YAML::PP->new( schema => ['JSON'] ); my $yp = YAML::PP->new( schema => [qw/ JSON empty=str /] ); my $yp = YAML::PP->new( schema => [qw/ JSON empty=null /] ); =head1 DESCRIPTION With this schema, the resolution of plain values will work like in JSON. Everything that matches a special value will be loaded as such, other plain scalars will be loaded as strings. Note that this is different from the official YAML 1.2 JSON Schema, where all strings have to be quoted. Here you can see all Schemas and examples implemented by YAML::PP: L<https://perlpunk.github.io/YAML-PP-p5/schemas.html> Official Schema: L<https://yaml.org/spec/1.2/spec.html#id2803231> =head1 CONFIGURATION The official YAML 1.2 JSON Schema wants all strings to be quoted. YAML::PP currently does not require that (it might do this optionally in the future). That means, there are no empty nodes allowed in the official schema. Example: --- key: The default behaviour of YAML::PP::Schema::JSON is to return an empty string, so it would be equivalent to: --- key: '' You can configure it to resolve this as C<undef>: my $yp = YAML::PP->new( schema => [qw/ JSON empty=null /] ); This way it is equivalent to: --- key: null The default is: my $yp = YAML::PP->new( schema => [qw/ JSON empty=str /] ); =head1 METHODS =over =item register Called by YAML::PP::Schema =item represent_bool, represent_float, represent_int, represent_literal, represent_undef Functions to represent the several node types. represent_bool($representer, $node); =back =cut 07070100000044000081A40000000000000000000000016616D6BA000009BA000000000000000000000000000000000000004100000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Merge.pmuse strict; use warnings; package YAML::PP::Schema::Merge; our $VERSION = '0.000'; # VERSION use YAML::PP::Type::MergeKey; sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_resolver( tag => 'tag:yaml.org,2002:merge', match => [ equals => '<<' => YAML::PP::Type::MergeKey->new ], ); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Merge - Enabling YAML merge keys for mappings =head1 SYNOPSIS use YAML::PP; my $yp = YAML::PP->new( schema => [qw/ + Merge /] ); my $yaml = <<'EOM'; --- - &CENTER { x: 1, y: 2 } - &LEFT { x: 0, y: 2 } - &BIG { r: 10 } - &SMALL { r: 1 } # All the following maps are equal: - # Explicit keys x: 1 y: 2 r: 10 label: center/big - # Merge one map << : *CENTER r: 10 label: center/big - # Merge multiple maps << : [ *CENTER, *BIG ] label: center/big - # Override << : [ *BIG, *LEFT, *SMALL ] x: 1 label: center/big EOM my $data = $yp->load_string($yaml); # $data->[4] == $data->[5] == $data->[6] == $data->[7] =head1 DESCRIPTION See L<https://yaml.org/type/merge.html> for the specification. Quote: "Specify one or more mappings to be merged with the current one. The C<< << >> merge key is used to indicate that all the keys of one or more specified maps should be inserted into the current map. If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the current mapping, unless the key already exists in it. If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier in the sequence override keys specified in later mapping nodes." The implementation of this in a generic way is not trivial, because we also have to handle duplicate keys, and YAML::PP allows you to write your own handler for processing mappings. So the inner API of that is not stable at this point. Note that if you enable this schema, a plain scalar `<<` will be seen as special anywhere in your document, so if you want a literal `<<`, you have to put it in quotes. Note that the performed merge is not a "deep merge". Only top-level keys are merged. =head1 METHODS =over =item register Called by YAML::PP::Schema =back =cut 07070100000045000081A40000000000000000000000016616D6BA00005FC7000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Perl.pmuse strict; use warnings; package YAML::PP::Schema::Perl; our $VERSION = '0.000'; # VERSION use Scalar::Util qw/ blessed reftype /; my $qr_prefix; # workaround to avoid growing regexes when repeatedly loading and dumping # e.g. (?^:(?^:regex)) { $qr_prefix = qr{\(\?-xism\:}; if ($] >= 5.014) { $qr_prefix = qr{\(\?\^(?:[uadl])?\:}; } } sub new { my ($class, %args) = @_; my $tags = $args{tags} || []; my $loadcode = $args{loadcode} || 0; my $dumpcode = $args{dumpcode}; $dumpcode = 1 unless defined $dumpcode; my $classes = $args{classes}; my $self = bless { tags => $tags, loadcode => $loadcode, dumpcode => $dumpcode, classes => $classes, }, $class; } sub register { my ($self, %args) = @_; my $schema = $args{schema}; my $tags; my $loadcode = 0; my $dumpcode = 1; my $classes; if (blessed($self)) { $tags = $self->{tags}; @$tags = ('!perl') unless @$tags; $loadcode = $self->{loadcode}; $dumpcode = $self->{dumpcode}; $classes = $self->{classes}; } else { my $options = $args{options}; my $tagtype = '!perl'; for my $option (@$options) { if ($option =~ m/^tags?=(.+)$/) { $tagtype = $1; } elsif ($option eq '+loadcode') { $loadcode = 1; } elsif ($option eq '-dumpcode') { $dumpcode = 0; } } $tags = [split m/\+/, $tagtype]; } my $perl_tag; my %tagtypes; my @perl_tags; for my $type (@$tags) { if ($type eq '!perl') { $perl_tag ||= $type; push @perl_tags, '!perl'; } elsif ($type eq '!!perl') { $perl_tag ||= 'tag:yaml.org,2002:perl'; push @perl_tags, 'tag:yaml.org,2002:perl'; } else { die "Invalid tagtype '$type'"; } $tagtypes{ $type } = 1; } my $perl_regex = '!perl'; if ($tagtypes{'!perl'} and $tagtypes{'!!perl'}) { $perl_regex = '(?:tag:yaml\\.org,2002:|!)perl'; } elsif ($tagtypes{'!perl'}) { $perl_regex = '!perl'; } elsif ($tagtypes{'!!perl'}) { $perl_regex = 'tag:yaml\\.org,2002:perl'; } my $class_regex = qr{.+}; my $no_objects = 0; if ($classes) { if (@$classes) { $class_regex = '(' . join( '|', map "\Q$_\E", @$classes ) . ')'; } else { $no_objects = 1; $class_regex = ''; } } # Code if ($loadcode) { my $load_code = sub { my ($constructor, $event) = @_; return $self->evaluate_code($event->{value}); }; my $load_code_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/code:}{}; my $sub = $self->evaluate_code($event->{value}); return $self->object($sub, $class); }; $schema->add_resolver( tag => "$_/code", match => [ all => $load_code], implicit => 0, ) for @perl_tags; $schema->add_resolver( tag => qr{^$perl_regex/code:$class_regex$}, match => [ all => $load_code_blessed ], implicit => 0, ); $schema->add_resolver( tag => qr{^$perl_regex/code:.+}, match => [ all => $load_code ], implicit => 0, ) if $no_objects; } else { my $loadcode_dummy = sub { return sub {} }; my $loadcode_blessed_dummy = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/code:}{}; return $self->object(sub {}, $class); }; $schema->add_resolver( tag => "$_/code", match => [ all => $loadcode_dummy ], implicit => 0, ) for @perl_tags; $schema->add_resolver( tag => qr{^$perl_regex/code:$class_regex$}, match => [ all => $loadcode_blessed_dummy ], implicit => 0, ); $schema->add_resolver( tag => qr{^$perl_regex/code:.+}, match => [ all => $loadcode_dummy ], implicit => 0, ) if $no_objects; } # Glob my $load_glob = sub { my $value = undef; return \$value; }; my $load_glob_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/glob:}{}; my $value = undef; return $self->object(\$value, $class); }; $schema->add_mapping_resolver( tag => "$_/glob", on_create => $load_glob, on_data => sub { my ($constructor, $ref, $list) = @_; $$ref = $self->construct_glob($list); }, ) for @perl_tags; if ($no_objects) { $schema->add_mapping_resolver( tag => qr{^$perl_regex/glob:.+$}, on_create => $load_glob, on_data => sub { my ($constructor, $ref, $list) = @_; $$ref = $self->construct_glob($list); }, ); } else { $schema->add_mapping_resolver( tag => qr{^$perl_regex/glob:$class_regex$}, on_create => $load_glob_blessed, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_glob($list); }, ); } # Regex my $load_regex = sub { my ($constructor, $event) = @_; return $self->construct_regex($event->{value}); }; my $load_regex_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/regexp:}{}; my $qr = $self->construct_regex($event->{value}); return $self->object($qr, $class); }; $schema->add_resolver( tag => "$_/regexp", match => [ all => $load_regex ], implicit => 0, ) for @perl_tags; $schema->add_resolver( tag => qr{^$perl_regex/regexp:$class_regex$}, match => [ all => $load_regex_blessed ], implicit => 0, ); $schema->add_resolver( tag => qr{^$perl_regex/regexp:$class_regex$}, match => [ all => $load_regex ], implicit => 0, ) if $no_objects; my $load_sequence = sub { return [] }; my $load_sequence_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/array:}{}; return $self->object([], $class); }; $schema->add_sequence_resolver( tag => "$_/array", on_create => $load_sequence, ) for @perl_tags; $schema->add_sequence_resolver( tag => qr{^$perl_regex/array:$class_regex$}, on_create => $load_sequence_blessed, ); $schema->add_sequence_resolver( tag => qr{^$perl_regex/array:.+$}, on_create => $load_sequence, ) if $no_objects; my $load_mapping = sub { return {} }; my $load_mapping_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/hash:}{}; return $self->object({}, $class); }; $schema->add_mapping_resolver( tag => "$_/hash", on_create => $load_mapping, ) for @perl_tags; $schema->add_mapping_resolver( tag => qr{^$perl_regex/hash:$class_regex$}, on_create => $load_mapping_blessed, ); $schema->add_mapping_resolver( tag => qr{^$perl_regex/hash:.+$}, on_create => $load_mapping, ) if $no_objects; # Ref my $load_ref = sub { my $value = undef; return \$value; }; my $load_ref_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/ref:}{}; my $value = undef; return $self->object(\$value, $class); }; $schema->add_mapping_resolver( tag => "$_/ref", on_create => $load_ref, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_ref($list); }, ) for @perl_tags; $schema->add_mapping_resolver( tag => qr{^$perl_regex/ref:$class_regex$}, on_create => $load_ref_blessed, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_ref($list); }, ); $schema->add_mapping_resolver( tag => qr{^$perl_regex/ref:.+$}, on_create => $load_ref, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_ref($list); }, ) if $no_objects; # Scalar ref my $load_scalar_ref = sub { my $value = undef; return \$value; }; my $load_scalar_ref_blessed = sub { my ($constructor, $event) = @_; my $class = $event->{tag}; $class =~ s{^$perl_regex/scalar:}{}; my $value = undef; return $self->object(\$value, $class); }; $schema->add_mapping_resolver( tag => "$_/scalar", on_create => $load_scalar_ref, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_scalar($list); }, ) for @perl_tags; $schema->add_mapping_resolver( tag => qr{^$perl_regex/scalar:$class_regex$}, on_create => $load_scalar_ref_blessed, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_scalar($list); }, ); $schema->add_mapping_resolver( tag => qr{^$perl_regex/scalar:.+$}, on_create => $load_scalar_ref, on_data => sub { my ($constructor, $ref, $list) = @_; $$$ref = $self->construct_scalar($list); }, ) if $no_objects; $schema->add_representer( scalarref => 1, code => sub { my ($rep, $node) = @_; $node->{tag} = $perl_tag . "/scalar"; $node->{data} = $self->represent_scalar($node->{value}); }, ); $schema->add_representer( refref => 1, code => sub { my ($rep, $node) = @_; $node->{tag} = $perl_tag . "/ref"; $node->{data} = $self->represent_ref($node->{value}); }, ); $schema->add_representer( coderef => 1, code => sub { my ($rep, $node) = @_; $node->{tag} = $perl_tag . "/code"; $node->{data} = $dumpcode ? $self->represent_code($node->{value}) : '{ "DUMMY" }'; }, ); $schema->add_representer( glob => 1, code => sub { my ($rep, $node) = @_; $node->{tag} = $perl_tag . "/glob"; $node->{data} = $self->represent_glob($node->{value}); }, ); $schema->add_representer( class_matches => 1, code => sub { my ($rep, $node) = @_; my $blessed = blessed $node->{value}; my $tag_blessed = ":$blessed"; if ($blessed !~ m/^$class_regex$/) { $tag_blessed = ''; } $node->{tag} = sprintf "$perl_tag/%s%s", lc($node->{reftype}), $tag_blessed; if ($node->{reftype} eq 'HASH') { $node->{data} = $node->{value}; } elsif ($node->{reftype} eq 'ARRAY') { $node->{data} = $node->{value}; } # Fun with regexes in perl versions! elsif ($node->{reftype} eq 'REGEXP') { if ($blessed eq 'Regexp') { $node->{tag} = $perl_tag . "/regexp"; } $node->{data} = $self->represent_regex($node->{value}); } elsif ($node->{reftype} eq 'SCALAR') { # in perl <= 5.10 regex reftype(regex) was SCALAR if ($blessed eq 'Regexp') { $node->{tag} = $perl_tag . '/regexp'; $node->{data} = $self->represent_regex($node->{value}); } # In perl <= 5.10 there seemed to be no better pure perl # way to detect a blessed regex? elsif ( $] <= 5.010001 and not defined ${ $node->{value} } and $node->{value} =~ m/^\(\?/ ) { $node->{tag} = $perl_tag . '/regexp' . $tag_blessed; $node->{data} = $self->represent_regex($node->{value}); } else { # phew, just a simple scalarref $node->{data} = $self->represent_scalar($node->{value}); } } elsif ($node->{reftype} eq 'REF') { $node->{data} = $self->represent_ref($node->{value}); } elsif ($node->{reftype} eq 'CODE') { $node->{data} = $dumpcode ? $self->represent_code($node->{value}) : '{ "DUMMY" }'; } elsif ($node->{reftype} eq 'GLOB') { $node->{data} = $self->represent_glob($node->{value}); } else { die "Reftype '$node->{reftype}' not implemented"; } return 1; }, ); return; } sub evaluate_code { my ($self, $code) = @_; unless ($code =~ m/^ \s* \{ .* \} \s* \z/xs) { die "Malformed code"; } $code = "sub $code"; my $sub = eval $code; if ($@) { die "Couldn't eval code: $@>>$code<<"; } return $sub; } sub construct_regex { my ($self, $regex) = @_; if ($regex =~ m/^$qr_prefix(.*)\)\z/s) { $regex = $1; } my $qr = qr{$regex}; return $qr; } sub construct_glob { my ($self, $list) = @_; if (@$list % 2) { die "Unexpected data in perl/glob construction"; } my %globdata = @$list; my $name = delete $globdata{NAME} or die "Missing NAME in perl/glob"; my $pkg = delete $globdata{PACKAGE}; $pkg = 'main' unless defined $pkg; my @allowed = qw(SCALAR ARRAY HASH CODE IO); delete @globdata{ @allowed }; if (my @keys = keys %globdata) { die "Unexpected keys in perl/glob: @keys"; } no strict 'refs'; return *{"${pkg}::$name"}; } sub construct_scalar { my ($self, $list) = @_; if (@$list != 2) { die "Unexpected data in perl/scalar construction"; } my ($key, $value) = @$list; unless ($key eq '=') { die "Unexpected data in perl/scalar construction"; } return $value; } sub construct_ref { &construct_scalar; } sub represent_scalar { my ($self, $value) = @_; return { '=' => $$value }; } sub represent_ref { &represent_scalar; } sub represent_code { my ($self, $code) = @_; require B::Deparse; my $deparse = B::Deparse->new("-p", "-sC"); return $deparse->coderef2text($code); } my @stats = qw/ device inode mode links uid gid rdev size atime mtime ctime blksize blocks /; sub represent_glob { my ($self, $glob) = @_; my %glob; for my $type (qw/ PACKAGE NAME SCALAR ARRAY HASH CODE IO /) { my $value = *{ $glob }{ $type }; if ($type eq 'SCALAR') { $value = $$value; } elsif ($type eq 'IO') { if (defined $value) { undef $value; $value->{stat} = {}; if ($value->{fileno} = fileno(*{ $glob })) { @{ $value->{stat} }{ @stats } = stat(*{ $glob }); $value->{tell} = tell *{ $glob }; } } } $glob{ $type } = $value if defined $value; } return \%glob; } sub represent_regex { my ($self, $regex) = @_; $regex = "$regex"; if ($regex =~ m/^$qr_prefix(.*)\)\z/s) { $regex = $1; } return $regex; } sub object { my ($self, $data, $class) = @_; return bless $data, $class; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Perl - Schema for serializing perl objects and special types =head1 SYNOPSIS use YAML::PP; # This can be dangerous when loading untrusted YAML! my $yp = YAML::PP->new( schema => [qw/ + Perl /] ); # or my $yp = YAML::PP->new( schema => [qw/ Core Perl /] ); my $yaml = $yp->dump_string(sub { return 23 }); # loading code references # This is very dangerous when loading untrusted YAML!! my $yp = YAML::PP->new( schema => [qw/ + Perl +loadcode /] ); my $code = $yp->load_string(<<'EOM'); --- !perl/code | { use 5.010; my ($name) = @_; say "Hello $name!"; } EOM $code->("Ingy"); =head1 DESCRIPTION This schema allows you to load and dump perl objects and special types. Please note that loading objects of arbitrary classes can be dangerous in Perl. You have to load the modules yourself, but if an exploitable module is loaded and an object is created, its C<DESTROY> method will be called when the object falls out of scope. L<File::Temp> is an example that can be exploitable and might remove arbitrary files. Dumping code references is on by default, but not loading (because that is easily exploitable since it's using string C<eval>). =head2 Tag Styles You can define the style of tags you want to support: my $yp_perl_two_one = YAML::PP->new( schema => [qw/ + Perl tags=!!perl+!perl /], ); =over =item C<!perl> (default) Only C<!perl/type> tags are supported. =item C<!!perl> Only C<!!perl/type> tags are supported. =item C<!perl+!!perl> Both C<!perl/type> and C<!!perl/tag> are supported when loading. When dumping, C<!perl/type> is used. =item C<!!perl+!perl> Both C<!perl/type> and C<!!perl/tag> are supported when loading. When dumping, C<!!perl/type> is used. =back L<YAML>.pm, L<YAML::Syck> and L<YAML::XS> are using C<!!perl/type> when dumping. L<YAML>.pm and L<YAML::Syck> are supporting both C<!perl/type> and C<!!perl/type> when loading. L<YAML::XS> currently only supports the latter. =head2 Allow only certain classes Since v0.017 Blessing arbitrary objects can be dangerous. Maybe you want to allow blessing only specific classes and ignore others. For this you have to instantiate a Perl Schema object first and use the C<classes> option. Currently it only allows a list of strings: my $perl = YAML::PP::Schema::Perl->new( classes => ['Foo', 'Bar'], ); my $yp = YAML::PP::Perl->new( schema => [qw/ + /, $perl], ); Allowed classes will be loaded and dumped as usual. The others will be ignored. If you want to allow no objects at all, pass an empty array ref. =cut =head2 EXAMPLES This is a list of the currently supported types and how they are dumped into YAML: =cut ### BEGIN EXAMPLE =pod =over 4 =item array # Code [ qw/ one two three four / ] # YAML --- - one - two - three - four =item array_blessed # Code bless [ qw/ one two three four / ], "Just::An::Arrayref" # YAML --- !perl/array:Just::An::Arrayref - one - two - three - four =item circular # Code my $circle = bless [ 1, 2 ], 'Circle'; push @$circle, $circle; $circle; # YAML --- &1 !perl/array:Circle - 1 - 2 - *1 =item coderef # Code sub { my (%args) = @_; return $args{x} + $args{y}; } # YAML --- !perl/code |- { use warnings; use strict; (my(%args) = @_); (return ($args{'x'} + $args{'y'})); } =item coderef_blessed # Code bless sub { my (%args) = @_; return $args{x} - $args{y}; }, "I::Am::Code" # YAML --- !perl/code:I::Am::Code |- { use warnings; use strict; (my(%args) = @_); (return ($args{'x'} - $args{'y'})); } =item hash # Code { U => 2, B => 52, } # YAML --- B: 52 U: 2 =item hash_blessed # Code bless { U => 2, B => 52, }, 'A::Very::Exclusive::Class' # YAML --- !perl/hash:A::Very::Exclusive::Class B: 52 U: 2 =item refref # Code my $ref = { a => 'hash' }; my $refref = \$ref; $refref; # YAML --- !perl/ref =: a: hash =item refref_blessed # Code my $ref = { a => 'hash' }; my $refref = bless \$ref, 'Foo'; $refref; # YAML --- !perl/ref:Foo =: a: hash =item regexp # Code my $string = 'unblessed'; qr{$string} # YAML --- !perl/regexp unblessed =item regexp_blessed # Code my $string = 'blessed'; bless qr{$string}, "Foo" # YAML --- !perl/regexp:Foo blessed =item scalarref # Code my $scalar = "some string"; my $scalarref = \$scalar; $scalarref; # YAML --- !perl/scalar =: some string =item scalarref_blessed # Code my $scalar = "some other string"; my $scalarref = bless \$scalar, 'Foo'; $scalarref; # YAML --- !perl/scalar:Foo =: some other string =back =cut ### END EXAMPLE =head2 METHODS =over =item new my $perl = YAML::PP::Schema::Perl->new( tags => "!perl", classes => ['MyClass'], loadcode => 1, dumpcode => 1, ); The constructor recognizes the following options: =over =item tags Default: 'C<!perl>' See L<"Tag Styles"> =item classes Default: C<undef> Since: v0.017 Accepts an array ref of class names =item loadcode Default: 0 =item dumpcode Default: 1 my $yp = YAML::PP->new( schema => [qw/ + Perl -dumpcode /] ); =back =item register A class method called by L<YAML::PP::Schema> =item construct_ref, represent_ref Perl variables of the type C<REF> are represented in yaml like this: --- !perl/ref =: a: 1 C<construct_ref> returns the perl data: my $data = YAML::PP::Schema::Perl->construct_ref([ '=', { some => 'data' } ); my $data = \{ a => 1 }; C<represent_ref> turns a C<REF> variable into a YAML mapping: my $data = YAML::PP::Schema::Perl->represent_ref(\{ a => 1 }); my $data = { '=' => { a => 1 } }; =item construct_scalar, represent_scalar Perl variables of the type C<SCALAR> are represented in yaml like this: --- !perl/scalar =: string C<construct_scalar> returns the perl data: my $data = YAML::PP::Schema::Perl->construct_ref([ '=', 'string' ); my $data = \'string'; C<represent_scalar> turns a C<SCALAR> variable into a YAML mapping: my $data = YAML::PP::Schema::Perl->represent_scalar(\'string'); my $data = { '=' => 'string' }; =item construct_regex, represent_regex C<construct_regex> returns a C<qr{}> object from the YAML string: my $qr = YAML::PP::Schema::Perl->construct_regex('foo.*'); C<represent_regex> returns a string representing the regex object: my $string = YAML::PP::Schema::Perl->represent_regex(qr{...}); =item evaluate_code, represent_code C<evaluate_code> returns a code reference from a string. The string must start with a C<{> and end with a C<}>. my $code = YAML::PP::Schema::Perl->evaluate_code('{ return 23 }'); C<represent_code> returns a string representation of the code reference with the help of B::Deparse: my $string = YAML::PP::Schema::Perl->represent_code(sub { return 23 }); =item construct_glob, represent_glob C<construct_glob> returns a glob from a hash. my $glob = YAML::PP::Schema::Perl->construct_glob($hash); C<represent_glob> returns a hash representation of the glob. my $hash = YAML::PP::Schema::Perl->represent_glob($glob); =item object Does the same as C<bless>: my $object = YAML::PP::Schema::Perl->object($data, $class); =back =cut 07070100000046000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Tie07070100000047000081A40000000000000000000000016616D6BA00000998000000000000000000000000000000000000004600000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/Tie/IxHash.pmuse strict; use warnings; package YAML::PP::Schema::Tie::IxHash; our $VERSION = '0.000'; # VERSION use base 'YAML::PP::Schema'; use Scalar::Util qw/ blessed reftype /; my $ixhash = eval { require Tie::IxHash }; sub register { my ($self, %args) = @_; my $schema = $args{schema}; unless ($ixhash) { die "You need to install Tie::IxHash in order to use this module"; } $schema->add_representer( tied_equals => 'Tie::IxHash', code => sub { my ($rep, $node) = @_; $node->{items} = [ %{ $node->{data} } ]; return 1; }, ); return; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::Tie::IxHash - (Deprecated) Schema for serializing ordered hashes =head1 SYNOPSIS use YAML::PP; use Tie::IxHash; my $yp = YAML::PP->new( schema => [qw/ + Tie::IxHash /] ); tie(my %ordered, 'Tie::IxHash'); %ordered = ( U => 2, B => 52, ); my $yaml = $yp->dump_string(\%ordered); # Output: --- U: 2 B: 52 =head1 DESCRIPTION This is deprecated. See the new option C<preserve> in L<YAML::PP>. This schema allows you to dump ordered hashes which are tied to L<Tie::IxHash>. This code is pretty new and experimental. It is not yet implemented for loading yet, so for now you have to tie the hashes yourself. Examples: =cut ### BEGIN EXAMPLE =pod =over 4 =item order # Code tie(my %order, 'Tie::IxHash'); %order = ( U => 2, B => 52, c => 64, 19 => 84, Disco => 2000, Year => 2525, days_on_earth => 20_000, ); \%order; # YAML --- U: 2 B: 52 c: 64 19: 84 Disco: 2000 Year: 2525 days_on_earth: 20000 =item order_blessed # Code tie(my %order, 'Tie::IxHash'); %order = ( U => 2, B => 52, c => 64, 19 => 84, Disco => 2000, Year => 2525, days_on_earth => 20_000, ); bless \%order, 'Order'; # YAML --- !perl/hash:Order U: 2 B: 52 c: 64 19: 84 Disco: 2000 Year: 2525 days_on_earth: 20000 =back =cut ### END EXAMPLE =head1 METHODS =over =item register Called by YAML::PP::Schema =back =cut 07070100000048000081A40000000000000000000000016616D6BA00001A93000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Schema/YAML1_1.pmuse strict; use warnings; package YAML::PP::Schema::YAML1_1; our $VERSION = '0.000'; # VERSION use YAML::PP::Schema::JSON qw/ represent_int represent_float represent_literal represent_bool represent_undef /; use YAML::PP::Common qw/ YAML_PLAIN_SCALAR_STYLE /; #https://yaml.org/type/bool.html # y|Y|yes|Yes|YES|n|N|no|No|NO # |true|True|TRUE|false|False|FALSE # |on|On|ON|off|Off|OFF # https://yaml.org/type/float.html # [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)? (base 10) # |[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]* (base 60) # |[-+]?\.(inf|Inf|INF) # (infinity) # |\.(nan|NaN|NAN) # (not a number) # https://yaml.org/type/int.html # [-+]?0b[0-1_]+ # (base 2) # |[-+]?0[0-7_]+ # (base 8) # |[-+]?(0|[1-9][0-9_]*) # (base 10) # |[-+]?0x[0-9a-fA-F_]+ # (base 16) # |[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+ # (base 60) # https://yaml.org/type/null.html # ~ # (canonical) # |null|Null|NULL # (English) # | # (Empty) my $RE_INT_1_1 = qr{^([+-]?(?:0|[1-9][0-9_]*))$}; #my $RE_FLOAT_1_1 = qr{^([+-]?([0-9][0-9_]*)?\.[0-9.]*([eE][+-][0-9]+)?)$}; # https://yaml.org/type/float.html has a bug. The regex says \.[0-9.], but # probably means \.[0-9_] my $RE_FLOAT_1_1 = qr{^([+-]?(?:[0-9][0-9_]*)?\.[0-9_]*(?:[eE][+-][0-9]+)?)$}; my $RE_SEXAGESIMAL = qr{^([+-]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*)$}; my $RE_SEXAGESIMAL_INT = qr{^([-+]?[1-9][0-9_]*(:[0-5]?[0-9])+)$}; my $RE_INT_OCTAL_1_1 = qr{^([+-]?)0([0-7_]+)$}; my $RE_INT_HEX_1_1 = qr{^([+-]?)(0x[0-9a-fA-F_]+)$}; my $RE_INT_BIN_1_1 = qr{^([-+]?)(0b[0-1_]+)$}; sub _from_oct { my ($constructor, $event, $matches) = @_; my ($sign, $oct) = @$matches; $oct =~ tr/_//d; my $result = oct $oct; $result = -$result if $sign eq '-'; return $result; } sub _from_hex { my ($constructor, $event, $matches) = @_; my ($sign, $hex) = @$matches; my $result = hex $hex; $result = -$result if $sign eq '-'; return $result; } sub _sexa_to_float { my ($constructor, $event, $matches) = @_; my ($float) = @$matches; my $result = 0; my $i = 0; my $sign = 1; $float =~ s/^-// and $sign = -1; for my $part (reverse split m/:/, $float) { $result += $part * ( 60 ** $i ); $i++; } $result = unpack F => pack F => $result; return $result * $sign; } sub _to_float { my ($constructor, $event, $matches) = @_; my ($float) = @$matches; $float =~ tr/_//d; $float = unpack F => pack F => $float; return $float; } sub _to_int { my ($constructor, $event, $matches) = @_; my ($int) = @$matches; $int =~ tr/_//d; 0 + $int; } sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_resolver( tag => 'tag:yaml.org,2002:null', match => [ equals => $_ => undef ], ) for (qw/ null NULL Null ~ /, ''); $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => $_ => $schema->true ], ) for (qw/ true TRUE True y Y yes Yes YES on On ON /); $schema->add_resolver( tag => 'tag:yaml.org,2002:bool', match => [ equals => $_ => $schema->false ], ) for (qw/ false FALSE False n N no No NO off Off OFF /); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_OCTAL_1_1 => \&_from_oct ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_1_1 => \&_to_int ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_HEX_1_1 => \&_from_hex ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ regex => $RE_FLOAT_1_1 => \&_to_float ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_INT_BIN_1_1 => \&_from_oct ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:int', match => [ regex => $RE_SEXAGESIMAL_INT => \&_sexa_to_float ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ regex => $RE_SEXAGESIMAL => \&_sexa_to_float ], ); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 + "inf" ], ) for (qw/ .inf .Inf .INF +.inf +.Inf +.INF /); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 - "inf" ], ) for (qw/ -.inf -.Inf -.INF /); $schema->add_resolver( tag => 'tag:yaml.org,2002:float', match => [ equals => $_ => 0 + "nan" ], ) for (qw/ .nan .NaN .NAN /); $schema->add_resolver( tag => 'tag:yaml.org,2002:str', match => [ all => sub { $_[1]->{value} } ], implicit => 0, ); my $int_flags = B::SVp_IOK; my $float_flags = B::SVp_NOK; $schema->add_representer( flags => $int_flags, code => \&represent_int, ); $schema->add_representer( flags => $float_flags, code => \&represent_float, ); $schema->add_representer( undefined => \&represent_undef, ); $schema->add_representer( equals => $_, code => \&represent_literal, ) for ("", qw/ true TRUE True y Y yes Yes YES on On ON false FALSE False n N n no No NO off Off OFF null NULL Null ~ .inf .Inf .INF -.inf -.Inf -.INF +.inf +.Inf +.INF .nan .NaN .NAN /); $schema->add_representer( regex => qr{$RE_INT_1_1|$RE_FLOAT_1_1|$RE_INT_OCTAL_1_1|$RE_INT_HEX_1_1|$RE_INT_BIN_1_1|$RE_SEXAGESIMAL_INT|$RE_SEXAGESIMAL}, code => \&represent_literal, ); if ($schema->bool_class) { for my $class (@{ $schema->bool_class }) { if ($class eq 'perl') { $schema->add_representer( bool => 1, code => \&represent_bool, ); next; } $schema->add_representer( class_equals => $class, code => \&represent_bool, ); } } return; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Schema::YAML1_1 - YAML 1.1 Schema for YAML::PP =head1 SYNOPSIS use YAML::PP; my $yp = YAML::PP->new( schema => ['YAML1_1'] ); my $yaml = <<'EOM'; --- booltrue: [ true, True, TRUE, y, Y, yes, Yes, YES, on, On, ON ] EOM my $data = $yp->load_string($yaml); =head1 DESCRIPTION This schema allows you to load the common YAML Types from YAML 1.1. =head1 METHODS =over =item register Called by YAML::PP::Schema =back =head1 SEE ALSO =over =item L<https://yaml.org/type/null.html> =item L<https://yaml.org/type/float.html> =item L<https://yaml.org/type/int.html> =item L<https://yaml.org/type/bool.html> =back 07070100000049000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Type0707010000004A000081A40000000000000000000000016616D6BA00000181000000000000000000000000000000000000004200000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Type/MergeKey.pmuse strict; use warnings; package YAML::PP::Type::MergeKey; our $VERSION = '0.000'; # VERSION sub new { my ($class) = @_; return bless {}, $class; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Type::MergeKey - A special node type for merge keys =head1 DESCRIPTION See L<YAML::PP::Schema::Merge> =head1 METHODS =over =item new Constructor =back =cut 0707010000004B000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Writer0707010000004C000081A40000000000000000000000016616D6BA000004E8000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Writer.pm# ABSTRACT: Writer class for YAML::PP representing output data use strict; use warnings; package YAML::PP::Writer; our $VERSION = '0.000'; # VERSION sub output { return $_[0]->{output} } sub set_output { $_[0]->{output} = $_[1] } sub new { my ($class, %args) = @_; my $output = delete $args{output}; $output = '' unless defined $output; return bless { output => $output, }, $class; } sub write { my ($self, $line) = @_; $self->{output} .= $line; } sub init { $_[0]->set_output(''); } sub finish { my ($self) = @_; $_[0]->set_output(undef); } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Writer - Write YAML output =head1 SYNOPSIS my $writer = YAML::PP::Writer->new; =head1 DESCRIPTION The L<YAML::PP::Emitter> sends its output to the writer. You can use your own writer. if you want to send the YAML output to somewhere else. See t/44.writer.t for an example. =head1 METHODS =over =item new my $writer = YAML::PP::Writer->new; Constructor. =item write $writer->write('- '); =item init $writer->init; Initialize =item finish $writer->finish; Gets called when the output ends. =item output, set_output Getter/setter for the YAML output =back =cut 0707010000004D000081A40000000000000000000000016616D6BA0000072F000000000000000000000000000000000000004000000000perl-YAML-PP-3.14.1712772794.39ac610/lib/YAML/PP/Writer/File.pmuse strict; use warnings; package YAML::PP::Writer::File; our $VERSION = '0.000'; # VERSION use Scalar::Util qw/ openhandle /; use base qw/ YAML::PP::Writer /; use Carp qw/ croak /; sub _open_handle { my ($self) = @_; if (openhandle($self->{output})) { $self->{filehandle} = $self->{output}; return $self->{output}; } open my $fh, '>:encoding(UTF-8)', $self->{output} or croak "Could not open '$self->{output}' for writing: $!"; $self->{filehandle} = $fh; return $fh; } sub write { my ($self, $line) = @_; my $fh = $self->{filehandle}; print $fh $line; } sub init { my ($self) = @_; my $fh = $self->_open_handle; } sub finish { my ($self) = @_; if (openhandle($self->{output})) { # Original argument was a file handle, so the caller needs # to close it return; } close $self->{filehandle}; } 1; __END__ =pod =encoding utf-8 =head1 NAME YAML::PP::Writer::File - Write YAML output to file or file handle =head1 SYNOPSIS my $writer = YAML::PP::Writer::File->new(output => $file); =head1 DESCRIPTION The L<YAML::PP::Emitter> sends its output to the writer. You can use your own writer. if you want to send the YAML output to somewhere else. See t/44.writer.t for an example. =head1 METHODS =over =item new my $writer = YAML::PP::Writer::File->new(output => $file); my $writer = YAML::PP::Writer::File->new(output => $filehandle); Constructor. =item write $writer->write('- '); =item init $writer->init; Initialize =item finish $writer->finish; Gets called when the output ends. If The argument was a filename, the filehandle will be closed. If the argument was a filehandle, the caller needs to close it. =item output, set_output Getter/setter for the YAML output =back =cut 0707010000004E000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000002F00000000perl-YAML-PP-3.14.1712772794.39ac610/new_tests0707010000004F000081A40000000000000000000000016616D6BA0000000C000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/new_tests/unknown1.yaml[ foo:bar ] 07070100000050000081A40000000000000000000000016616D6BA00000009000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/new_tests/unknown2.yaml[ :bar ] 07070100000051000081A40000000000000000000000016616D6BA00000056000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/new_tests/valid10.yaml--- &a &b "a": 1 "b": 2 --- &a &b 'a': 1 'b': 2 --- &a &b a: 1 b: 2 --- *a : 1 *b : 2 07070100000052000081A40000000000000000000000016616D6BA00000027000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/new_tests/valid11.yaml- ::x - :# - ::# - ?:? - -:# - ?# - -# 07070100000053000041ED0000000000000000000000066616D6BA00000000000000000000000000000000000000000000002700000000perl-YAML-PP-3.14.1712772794.39ac610/t07070100000054000081A40000000000000000000000016616D6BA00000E30000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/00.compile.tuse 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.058 use Test::More; plan tests => 33 + ($ENV{AUTHOR_TESTING} ? 1 : 0); my @module_files = ( 'YAML/PP.pm', 'YAML/PP/Common.pm', 'YAML/PP/Constructor.pm', 'YAML/PP/Dumper.pm', 'YAML/PP/Emitter.pm', 'YAML/PP/Exception.pm', 'YAML/PP/Grammar.pm', 'YAML/PP/Highlight.pm', 'YAML/PP/Lexer.pm', 'YAML/PP/Loader.pm', 'YAML/PP/Parser.pm', 'YAML/PP/Perl.pm', 'YAML/PP/Reader.pm', 'YAML/PP/Render.pm', 'YAML/PP/Representer.pm', 'YAML/PP/Schema.pm', 'YAML/PP/Schema/Binary.pm', 'YAML/PP/Schema/Core.pm', 'YAML/PP/Schema/Failsafe.pm', 'YAML/PP/Schema/Include.pm', 'YAML/PP/Schema/JSON.pm', 'YAML/PP/Schema/Merge.pm', 'YAML/PP/Schema/Perl.pm', 'YAML/PP/Schema/Tie/IxHash.pm', 'YAML/PP/Schema/YAML1_1.pm', 'YAML/PP/Type/MergeKey.pm', 'YAML/PP/Writer.pm', 'YAML/PP/Writer/File.pm' ); my @scripts = ( 'bin/yamlpp-events', 'bin/yamlpp-highlight', 'bin/yamlpp-load', 'bin/yamlpp-load-dump', 'bin/yamlpp-parse-emit' ); # no fake home requested my @switches = ( -d 'blib' ? '-Mblib' : '-Ilib', ); use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L<perlfaq8/How can I capture STDERR from an external command?> my $stderr = IO::Handle->new; diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} } $^X, @switches, '-e', "require q[$lib]")) if $ENV{PERL_COMPILE_TEST_DEBUG}; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { +require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } foreach my $file (@scripts) { SKIP: { open my $fh, '<', $file or warn("Unable to open $file: $!"), next; my $line = <$fh>; close $fh and skip("$file isn't perl", 1) unless $line =~ /^#!\s*(?:\S*perl\S*)((?:\s+-\w*)*)(?:\s*#.*)?$/; @switches = (@switches, split(' ', $1)) if $1; close $fh and skip("$file uses -T; not testable with PERL5LIB", 1) if grep { $_ eq '-T' } @switches and $ENV{PERL5LIB}; my $stderr = IO::Handle->new; diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} } $^X, @switches, '-c', $file)) if $ENV{PERL_COMPILE_TEST_DEBUG}; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-c', $file); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$file compiled ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { +require blib; blib->VERSION('1.01') }; # in older perls, -c output is simply the file portion of the path being tested if (@_warnings = grep { !/\bsyntax OK$/ } grep { chomp; $_ ne (File::Spec->splitpath($file))[2] } @_warnings) { warn @_warnings; push @warnings, @_warnings; } } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING}; 07070100000055000081A40000000000000000000000016616D6BA00000603000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/10.parse-valid.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP::Parser; use Encode; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; my @skip = qw/ 4FJ6 9MMW LX3P Q9WF 6BFJ CT4Q M2N8:01 UKK6:01 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, events => 1, in_yaml => 1, linecount => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); my %errors; $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ OK DIFF ERROR TODO SKIP /], ids => [qw/ DIFF ERROR /], ); for my $type (sort keys %errors) { diag "ERRORS($type): (@{ $errors{ $type } })"; } sub test { my ($testsuite, $testcase) = @_; my $id = $testcase->{id}; my $result = $testsuite->parse_events($testcase); my $err = $result->{err}; if ($err) { diag "ERROR($id): $err"; my $error_type = 'unknown'; if ($err =~ m/^(Expected) *:/m) { $error_type = "$1"; } elsif ($err =~ m/(Not Implemented: .*?) at/) { $error_type = "$1"; } elsif ($err =~ m/(Unexpected .*?) at/) { $error_type = "$1"; } push @{ $errors{ $error_type } }, $id; } $testsuite->compare_parse_events($testcase, $result); return $result; } done_testing; 07070100000056000081A40000000000000000000000016616D6BA000007F4000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/11.parse-invalid.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP::Parser; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; my @skip = qw/ CXX2 9KBC S98Z T833 5LLU /; # in case of error events might not be exactly matching my %skip_events = ( Q4CL => 1, JY7Z => 1, '3HFZ' => 1, X4QW => 1, SU5Z => 1, W9L4 => 1, ZL4Z => 1, '9KBC' => 1, SY6V => 1, C2SP => 1, 'NTY5' => 1, '4EJS' => 1, '2CMS' => 1, 'HU3P' => 1, 'EW3V' => 1, 'G9HC' => 1, '4H7K' => 1, BS4K => 1, EB22 => 1, i037 => 1, i038 => 1, 'MUS6:00' => 1, 'MUS6:01' => 1, 'Y79Y:004' => 1, 'Y79Y:005' => 1, 'Y79Y:006' => 1, 'Y79Y:007' => 1, 'Y79Y:008' => 1, 'Y79Y:009' => 1, ); my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/invalid", valid => 0, events => 1, in_yaml => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); my %errors; $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ OK DIFF ERROR TODO SKIP /], ids => [qw/ OK DIFF /], ); for my $type (sort keys %errors) { diag "ERRORS($type): (@{ $errors{ $type } })" if $ENV{TEST_VERBOSE}; } done_testing; exit; sub test { my ($testsuite, $testcase) = @_; my $id = $testcase->{id}; my $result = $testsuite->parse_events($testcase); my $err = $result->{err}; if ($err) { diag "ERROR: $err" if $ENV{YAML_PP_TRACE}; my $error_type = 'unknown'; if ($@ =~ m/( Expected .*?)/) { $error_type = "$1"; } elsif ($@ =~ m/( Not Implemented: .*?)/) { $error_type = "$1"; } push @{ $errors{ $error_type } }, $id; } if ($skip_events{ $id }) { delete $result->{events}; } $testsuite->compare_invalid_parse_events($testcase, $result); return $result; } 07070100000057000081A40000000000000000000000016616D6BA00000431000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/12.load-json.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use Data::Dumper; use YAML::PP::Test; use YAML::PP; use Encode; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; my $json_pp = eval "use JSON::PP; 1"; unless ($json_pp) { plan skip_all => "JSON::PP not installed"; exit; } my $yts = "$Bin/../test-suite/yaml-test-suite-data"; $|++; my @skip = qw/ 87E4 8UDB CN3R CT4Q L9U5 LQZ7 QF4Y UKK6:01 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_json => 1, in_yaml => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ OK DIFF ERROR TODO SKIP /], ids => [qw/ ERROR DIFF /], ); my $stats = $testsuite->{stats}; done_testing; exit; sub test { my ($testsuite, $testcase) = @_; my $result = $testsuite->load_json($testcase); $testsuite->compare_load_json($testcase, $result); } 07070100000058000081A40000000000000000000000016616D6BA000002E4000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/13.load-anchor.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my $yaml = <<'EOM'; foo: &sequence - a - b - c bar: *sequence copies: - &alias A - *alias EOM my $yp = YAML::PP->new; my $data = $yp->load_string($yaml); cmp_ok($data->{copies}->[0],'eq', 'A', "Scalar anchor"); cmp_ok($data->{copies}->[0],'eq', $data->{copies}->[1], "Scalar alias equals anchor"); $data->{foo}->[-1] = "changed"; cmp_ok($data->{bar}->[-1],'eq', 'changed', "Alias changes when anchor changes"); $yaml = <<'EOM'; this should: *be_fatal EOM $data = eval { $yp->load_string($yaml) }; my $err = $@; like $err, qr{No anchor defined for alias}, 'Error when loading undefined alias'; done_testing; 07070100000059000081A40000000000000000000000016616D6BA0000078D000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/14.load-bool.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my $boolean = eval "use boolean; 1"; my $json_pp = eval "use JSON::PP; 1"; my $yaml = <<'EOM'; "TRUE": true "FALSE": false EOM my $ypp = YAML::PP->new(boolean => 'perl'); my $data_p = $ypp->load_string($yaml); cmp_ok(ref $data_p->{TRUE}, 'eq', '', "pure perl true"); cmp_ok($data_p->{TRUE}, '==', 1, "pure perl true"); cmp_ok($data_p->{FALSE}, '==', 0, "pure perl false"); SKIP: { skip "boolean not installed", 3 unless $boolean; my $ypp = YAML::PP->new(boolean => 'boolean'); my $data_b = $ypp->load_string($yaml); isa_ok($data_b->{TRUE}, 'boolean'); is($data_b->{TRUE}, 1, 'boolean.pm true'); is(! $data_b->{FALSE}, 1, 'boolean.pm false'); } SKIP: { skip "JSON::PP not installed", 3 unless $json_pp; my $ypp = YAML::PP->new(boolean => 'JSON::PP'); my $data_jp = $ypp->load_string($yaml); isa_ok($data_jp->{TRUE}, 'JSON::PP::Boolean'); is($data_jp->{TRUE}, 1, 'JSON::PP::Boolean true'); is(! $data_jp->{FALSE}, 1, 'JSON::PP::Boolean false'); } SKIP: { skip "JSON::PP and boolean not installed", 3 unless ($json_pp and $boolean); my $ypp = YAML::PP->new(boolean => 'JSON::PP,boolean'); my $data_jp = $ypp->load_string($yaml); isa_ok($data_jp->{TRUE}, 'JSON::PP::Boolean'); is($data_jp->{TRUE}, 1, 'JSON::PP::Boolean true'); is(! $data_jp->{FALSE}, 1, 'JSON::PP::Boolean false'); } SKIP: { skip "perl 5.36 required for this test", 3 unless $] >= 5.036000; my $is_bool = eval 'use experimental qw/ builtin /; sub { builtin::is_bool($_[0]) }'; my $ypp = YAML::PP->new(boolean => 'perl_experimental'); my $data_jp = $ypp->load_string($yaml); ok $is_bool->($data_jp->{TRUE}) && $data_jp->{TRUE}, 'builtin::is_bool truw'; ok $is_bool->($data_jp->{FALSE}) && ! $data_jp->{FALSE}, 'builtin::is_bool false'; } done_testing; 0707010000005A000081A40000000000000000000000016616D6BA00000370000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/15.parse-eol.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP::Parser; my @yaml = ( 'foo: bar', 'foo: bar #end', 'foo', '- a', '-', "|\nfoo", ">\nfoo", "|", '"foo"', '"foo" ', 'foo:', 'foo: ', '&foo', '&foo ', '!foo', "foo\n ", '---', '--- ', '...', '... ', ); my $ypp = YAML::PP::Parser->new( receiver => sub {} ); if (my $num = $ENV{TEST_NUM}) { @yaml = $yaml[$num-1]; } for my $yaml (@yaml) { my $display = $yaml; $display =~ s/\n/\\n/g; $display =~ s/\r/\\r/g; $display =~ s/\t/\\t/g; my $title = "Without final EOL: >>$display<<"; eval { $ypp->parse_string($yaml); }; if ($@) { diag "Error: $@"; ok(0, $title); } else { ok(1, $title); } } done_testing; 0707010000005B000081A40000000000000000000000016616D6BA00000124000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/16.loader.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP::Loader; eval { my $yppl = YAML::PP::Loader->new( boolean => 'bla' ); }; my $error = $@; cmp_ok($error, '=~', 'Unexpected arguments', "Unexpected arguments"); done_testing; 0707010000005C000081A40000000000000000000000016616D6BA00000588000000000000000000000000000000000000003E00000000perl-YAML-PP-3.14.1712772794.39ac610/t/17.load-complex-keys.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP::Loader; my $yppl = YAML::PP::Loader->new; my $yaml = <<'EOM'; complexmap: x: y ? a: b : c: d complexseq: X: Y ? - A - B : - C - D EOM my $nested_yaml = <<'EOM'; complex: ? ? a: b c: d : innervalue : outervalue EOM my $exp_complexmap = $yppl->constructor->stringify_complex({ a => 'b' }); my $exp_complexseq = $yppl->constructor->stringify_complex([qw/ A B /]); my $inner = $yppl->constructor->stringify_complex({ a => 'b', c => 'd' }); my $nested = $yppl->constructor->stringify_complex({ $inner => "innervalue" }); { my $data = $yppl->load_string($yaml); my $val1 = delete $data->{complexmap}->{x}; my $val2 = delete $data->{complexseq}->{X}; cmp_ok($val1, 'eq', 'y', "Normal key x"); cmp_ok($val2, 'eq', 'Y', "Normal key X"); my $complexmap = (keys %{ $data->{complexmap} })[0]; my $complexseq = (keys %{ $data->{complexseq} })[0]; cmp_ok($complexmap, 'eq', $exp_complexmap, "Complex map"); cmp_ok($complexseq, 'eq', $exp_complexseq, "Complex seq"); } { my $nested_data = $yppl->load_string($nested_yaml); my $data1 = $nested_data->{complex}; my $key = (keys %$data1)[0]; cmp_ok($key, 'eq', $nested, "Nested complex maps"); } done_testing; 0707010000005D000081A40000000000000000000000016616D6BA000005CD000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/18.control.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP::Parser; use YAML::PP; my %chars = ( "\x00" => '\0', "\x01" => '\x01', "\x02" => '\x02', "\x03" => '\x03', "\x04" => '\x04', "\x05" => '\x05', "\x06" => '\x06', "\x07" => '\a', "\x08" => '\b', "\x0b" => '\v', "\x0c" => '\f', "\x0e" => '\x0e', "\x0f" => '\x0f', "\x10" => '\x10', "\x11" => '\x11', "\x12" => '\x12', "\x13" => '\x13', "\x14" => '\x14', "\x15" => '\x15', "\x16" => '\x16', "\x17" => '\x17', "\x18" => '\x18', "\x19" => '\x19', "\x1a" => '\x1a', "\x1b" => '\e', "\x1c" => '\x1c', "\x1d" => '\x1d', "\x1e" => '\x1e', "\x1f" => '\x1f', ); my $ypp = YAML::PP::Parser->new( receiver => sub {} ); for my $char (sort keys %chars) { my $yaml = "control: $char"; local $Data::Dumper::Useqq = 1; my $display = Data::Dumper->Dump([\$yaml], ['yaml']); chomp $display; my $title = "Invalid literal control char: >>$display<<"; eval { $ypp->parse_string($yaml); }; if ($@) { #diag "Error: $@"; ok(1, "Parse: $title"); } else { ok(0, "Parse: $title"); } my $dump = YAML::PP->new->dump_string({ control => $char }); my $escaped = $chars{ $char }; my $expected = qq{---\ncontrol: "$escaped"\n}; cmp_ok($dump, 'eq', $expected, "Dump: $title"); } done_testing; 0707010000005E000081A40000000000000000000000016616D6BA0000066B000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/t/19.file.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my $file = "$Bin/data/simple.yaml"; my $file_out = "$Bin/data/simple-out.yaml"; my $invalid_file = "/non/existant/path/for/yaml/pp"; my $yaml = do { open my $fh, '<', $file or die $!; local $/; <$fh> }; my $data = { a => 1 }; my $all_data = [ { a => 1 }, { b => 2 } ]; my $data_from_string = YAML::PP->new->load_string($yaml); my $data_from_file = YAML::PP->new->load_file($file); open my $fh, '<', $file or die $!; my $data_from_filehandle = YAML::PP->new->load_file($fh); close $fh; is_deeply($data_from_string, $data, "load_string data ok"); is_deeply($data_from_file, $data, "load_file data ok"); is_deeply($data_from_filehandle, $data, "load_file(filehandle) data ok"); $data_from_file = YAML::PP::LoadFile($file); is_deeply($data_from_file, $data, "LoadFile data ok"); YAML::PP->new->dump_file($file_out, @$all_data); my $yaml2 = do { open my $fh, '<', $file_out or die $!; local $/; <$fh> }; cmp_ok($yaml2, 'eq', $yaml, "dump_file data correct"); YAML::PP::DumpFile($file_out, @$all_data); $yaml2 = do { open my $fh, '<', $file_out or die $!; local $/; <$fh> }; cmp_ok($yaml2, 'eq', $yaml, "DumpFile data correct"); open my $fh_out, '>', $file_out or die $!; YAML::PP::DumpFile($fh_out, @$all_data); close $fh_out; $yaml2 = do { open my $fh, '<', $file_out or die $!; local $/; <$fh> }; cmp_ok($yaml2, 'eq', $yaml, "DumpFile(filehandle) data correct"); eval { YAML::PP::DumpFile($invalid_file, $data); }; my $error = $@; cmp_ok($error, '=~', qr{Could not open}); done_testing; END { unlink $file_out; } 0707010000005F000081A40000000000000000000000016616D6BA0000048D000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/t/20.dump.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP; use Encode; use File::Basename qw/ dirname basename /; my $json_pp = eval "use JSON::PP; 1"; unless ($json_pp) { plan skip_all => "Need JSON::PP for testing booleans"; exit; } $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; # skip tests that parser can't parse my @skip = qw/ 4FJ6 87E4 8UDB 9MMW CN3R CT4Q L9U5 LQZ7 LX3P Q9WF QF4Y 6BFJ CFD4 M2N8:01 UKK6:01 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, out_yaml => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); sub test { my ($testsuite, $testcase) = @_; my $result = $testsuite->dump_yaml($testcase); $testsuite->compare_dump_yaml($testcase, $result); } done_testing; $testsuite->print_stats( count => [qw/ OK DIFF ERROR TODO SKIP /], ids => [qw/ ERROR DIFF /], ); 07070100000060000081A40000000000000000000000016616D6BA00000749000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/t/21.emit.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP::Parser; use YAML::PP::Emitter; use YAML::PP::Writer; use Encode; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; # skip tests that parser can't parse my @skip = qw/ 4FJ6 4ABK 87E4 8UDB 9MMW CN3R CT4Q FRK4 L9U5 LQZ7 LX3P Q9WF QF4Y 6BFJ F6MC NB6Z CFD4 M2N8:01 UKK6:01 /; # emitter push @skip, qw/ /; # quoting push @skip, qw/ 36F6 6CA3 9YRD HS5T EX5H NAT4 L24T:00 L24T:01 DK95:00 DK95:02 DK95:03 DK95:04 DK95:05 DK95:07 DK95:08 /; # tags push @skip, qw/ v014 /; # block scalar push @skip, qw/ 4QFQ R4YG v033 /; # test push @skip, qw/ XLQ9 K54U PUW8 MJS9 /; # TODO fix testsuite # 4QFQ # unicode push @skip, qw/ H3Z8 /; push @skip, qw/ /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, emit_yaml => 1, ); my %skip_yaml_equal = ( 'X38W' => 1, 'G4RS' => 1, '6CK3' => 1, '5TYM' => 1, '565N' => 1, # fix testsuite 'K858' => 1, '4MUZ' => 1, '8KB6' => 1, '9BXH' => 1, '6ZKB' => 1, '6SLA' => 1, '9DXL' => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ SAME_EVENTS SAME_YAML DIFF_EVENTS DIFF_YAML ERROR TODO SKIP /], ids => [qw/ DIFF_YAML DIFF_EVENTS /], ); sub test { my ($testsuite, $testcase) = @_; my $id = $testcase->{id}; my $result = $testsuite->emit_yaml($testcase); if ($skip_yaml_equal{ $id }) { delete $result->{emit_yaml}; } $testsuite->compare_emit_yaml($testcase, $result); } done_testing; exit; 07070100000061000081A40000000000000000000000016616D6BA000010B4000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/22.dump-bool.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use YAML::PP::Dumper; my $boolean = eval "use boolean; 1"; my $json_pp = eval "use JSON::PP; 1"; my $exp_yaml = <<"EOM"; --- false1: false false2: false true1: true true2: true EOM SKIP: { skip "boolean not installed", 1 unless $boolean; my $data = { "true1" => boolean::true(), "false1" => boolean::false(), "true2" => boolean::true(), "false2" => boolean::false(), }; my $yppd = YAML::PP->new(boolean => 'boolean'); my $yaml = $yppd->dump_string($data); cmp_ok($yaml, 'eq', $exp_yaml, "boolean.pm dump"); } SKIP: { skip "JSON::PP not installed", 1 unless $json_pp; my $data = { "true1" => JSON::PP::true(), "false1" => JSON::PP::false(), "true2" => JSON::PP::true(), "false2" => JSON::PP::false(), }; my $yppd = YAML::PP->new(boolean => 'JSON::PP'); my $yaml = $yppd->dump_string($data); cmp_ok($yaml, 'eq', $exp_yaml, "JSON::PP::Boolean dump"); } SKIP: { skip "JSON::PP and boolean not installed", 2 unless ($json_pp and $boolean); my $data = { "true1" => boolean::true(), "false1" => boolean::false(), "true2" => JSON::PP::true(), "false2" => JSON::PP::false(), }; my $yppd = YAML::PP->new(boolean => 'JSON::PP', schema => [qw/ + Perl /]); my $yaml = $yppd->dump_string($data); my $exp_json_pp = <<'EOM'; --- false1: !perl/scalar:boolean =: 0 false2: false true1: !perl/scalar:boolean =: 1 true2: true EOM cmp_ok($yaml, 'eq', $exp_json_pp, "JSON::PP::Boolean (no boolean) dump"); $yppd = YAML::PP->new(boolean => 'boolean', schema => [qw/ + Perl /]); $yaml = $yppd->dump_string($data); my $exp_boolean = <<'EOM'; --- false1: false false2: !perl/scalar:JSON::PP::Boolean =: 0 true1: true true2: !perl/scalar:JSON::PP::Boolean =: 1 EOM cmp_ok($yaml, 'eq', $exp_boolean, "boolean (no JSON::PP::Boolean) dump"); } SKIP: { skip "JSON::PP and boolean not installed", 6 unless ($json_pp and $boolean); my @tests = ( 'JSON::PP,boolean', 'boolean,JSON::PP', 'boolean,*', 'JSON::PP,*', '*', 'perl,*', ); my $data = { "true1" => boolean::true(), "false1" => boolean::false(), "true2" => JSON::PP::true(), "false2" => JSON::PP::false(), }; for my $test (@tests) { my $yppd = YAML::PP->new(boolean => $test); my $yaml = $yppd->dump_string($data); my $exp_json_pp = <<'EOM'; --- false1: false false2: false true1: true true2: true EOM cmp_ok($yaml, 'eq', $exp_json_pp, "$test dump"); } } SKIP: { skip "perl version < v5.36", 1 unless $] >= 5.036000; my $data = { "true1" => !!1, "false1" => !!0, }; my $yppd = YAML::PP->new(boolean => 'perl_experimental'); my $yaml = $yppd->dump_string($data); my $exp_json_pp = <<'EOM'; --- false1: false true1: true EOM cmp_ok($yaml, 'eq', $exp_json_pp, "perl_experimental dump"); } SKIP: { skip "perl version < v5.36", 1 unless $] >= 5.036000; my $data = { "true1" => !!1, "false1" => !!0, }; my $yppd = YAML::PP->new(boolean => ''); my $yaml = $yppd->dump_string($data); my $exp_json_pp = <<'EOM'; --- false1: '' true1: 1 EOM cmp_ok($yaml, 'eq', $exp_json_pp, "no booleans dump"); } SKIP: { skip "perl version < v5.36", 3 unless $] >= 5.036000; skip "JSON::PP and boolean not installed", 3 unless ($json_pp and $boolean); my @tests = ( 'perl_experimental,JSON::PP,boolean', 'perl_experimental,boolean,JSON::PP', 'perl_experimental,*', ); my $data = { "true1" => boolean::true(), "false1" => boolean::false(), "true2" => JSON::PP::true(), "false2" => JSON::PP::false(), "true3" => !!1, "false3" => !!0, }; for my $test (@tests) { my $yppd = YAML::PP->new(boolean => $test); my $yaml = $yppd->dump_string($data); my $exp_json_pp = <<'EOM'; --- false1: false false2: false false3: false true1: true true2: true true3: true EOM cmp_ok($yaml, 'eq', $exp_json_pp, "$test dump"); } } done_testing; 07070100000062000081A40000000000000000000000016616D6BA00000339000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/23-dump-anchor.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use YAML::PP::Dumper; my $hash = { a => "b" }; my $seq = [ "a", "b" ]; my $data1 = { hash => $hash, hashcopy => $hash, seq => $seq, seqcopy => $seq, }; my $exp_yaml1 = <<"EOM"; --- hash: &1 a: b hashcopy: *1 seq: &2 - a - b seqcopy: *2 EOM my $refa = { name => "a" }; my $refb = { name => "b", link => $refa }; $refa->{link} = $refb; my $data2 = { a => $refa, b => $refb, }; # cyclic my $exp_yaml2 = <<"EOM"; --- a: &1 link: &2 link: *1 name: b name: a b: *2 EOM my $yppd = YAML::PP::Dumper->new; my $yaml = $yppd->dump_string($data1); cmp_ok($yaml, 'eq', $exp_yaml1, "dump anchors"); $yaml = $yppd->dump_string($data2); cmp_ok($yaml, 'eq', $exp_yaml2, "dump cyclic data structure"); done_testing; 07070100000063000081A40000000000000000000000016616D6BA00000622000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/24.double-escapes.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my @yaml = ( [ q{\\\\}, q{\\}, q{\\} ], [ q{\"}, q{"}, q{'"'} ], [ q{\a}, qq{\a}, q{"\a"} ], [ q{\b}, qq{\b}, q{"\b"} ], [ q{\e}, qq{\e}, q{"\e"} ], [ q{\f}, qq{\f}, q{"\f"} ], [ q{\n}, qq{\n}, q{"\n"} ], [ q{\r}, qq{\r}, q{"\r"} ], [ q{\t}, qq{\t}, q{"\t"} ], [ q{\v}, qq{\x0b}, q{"\v"} ], [ q{\0}, qq{\0}, q{"\0"} ], [ q{\ }, q{ }, q{' '} ], [ q{\_}, qq{\xa0}, q{"\_"} ], [ q{\N}, qq{\x85}, q{"\N"} ], [ q{\L}, qq{\x{2028}}, q{"\L"}], [ q{\P}, qq{\x{2029}}, q{"\P"}], [ q{\x41}, q{A}, q{A} ], [ q{\u0041}, q{A}, q{A} ], [ q{\U00000041}, q{A}, q{A} ], ); for my $test (@yaml) { my ($yaml, $output, $dump) = @$test; unless (defined $dump) { $dump = $yaml; } $dump = "--- $dump\n"; $yaml = qq{"$yaml"}; my $got = eval { YAML::PP->new->load_string($yaml) }; if ($@) { diag "YAML:" . Data::Dumper->Dump([\$yaml], ['yaml']); diag "YAML: >>$yaml<< "; diag "Error: $@"; ok(0, "Escape: $yaml"); } else { local $Data::Dumper::Useqq = 1; my $ok = cmp_ok($got, 'eq', $output, "Escape: $yaml"); unless ($ok) { warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$got], ['got']); next; } } my $got_dump = YAML::PP->new->dump_string($got); my $ok = cmp_ok($got_dump, 'eq', $dump, "Dump: $yaml"); } done_testing; 07070100000064000081A40000000000000000000000016616D6BA00000788000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/30.legacy.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; use YAML::PP::Perl; my $file = "$Bin/data/simple.yaml"; my $copy = "$Bin/data/simple.yaml.copy"; my $yaml = do { open my $fh, '<', $file or die $!; local $/; <$fh> }; my $data = { a => 1 }; my $all_data = [ { a => 1 }, { b => 2 } ]; subtest default => sub { my $data_from_string = YAML::PP::Load($yaml); my $data_from_file = YAML::PP::LoadFile($file); is_deeply($data_from_string, $data, "scalar Load data ok"); is_deeply($data_from_file, $data, "scalar LoadFile data ok"); my @all_data_from_string = YAML::PP::Load($yaml); my @all_data_from_file = YAML::PP::LoadFile($file); is_deeply(\@all_data_from_string, $all_data, "Load data ok"); is_deeply(\@all_data_from_file, $all_data, "LoadFile data ok"); my $dump = YAML::PP::Dump(@$all_data); cmp_ok($dump, 'eq', $yaml, 'Dump() ok'); YAML::PP::DumpFile($copy, @$all_data); $yaml = do { open my $fh, '<', $copy or die $!; local $/; <$fh> }; cmp_ok($dump, 'eq', $yaml, 'DumpFile() ok'); }; subtest perl => sub { my $data_from_string = YAML::PP::Perl::Load($yaml); my $data_from_file = YAML::PP::Perl::LoadFile($file); is_deeply($data_from_string, $data, "Load data ok"); is_deeply($data_from_file, $data, "LoadFile data ok"); my @all_data_from_string = YAML::PP::Perl::Load($yaml); my @all_data_from_file = YAML::PP::Perl::LoadFile($file); is_deeply(\@all_data_from_string, $all_data, "Load data ok"); is_deeply(\@all_data_from_file, $all_data, "LoadFile data ok"); my $dump = YAML::PP::Perl::Dump(@$all_data); cmp_ok($dump, 'eq', $yaml, 'Dump() ok'); YAML::PP::Perl::DumpFile($copy, @$all_data); $yaml = do { open my $fh, '<', $copy or die $!; local $/; <$fh> }; cmp_ok($dump, 'eq', $yaml, 'DumpFile() ok'); }; done_testing; END { unlink $copy; } 07070100000065000081A40000000000000000000000016616D6BA000015F5000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/31.schema.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use B (); use Data::Dumper; use Scalar::Util qw/ blessed /; use YAML::PP; my $jsonpp = eval { require JSON::PP }; my $schema_file = "$Bin/../ext/yaml-test-schema/yaml-schema.yaml"; my $strings_file = "$Bin/../examples/strings.yaml"; my $schema_data = do { YAML::PP->new->load_file($schema_file) }; my $strings_data = do { YAML::PP->new->load_file($strings_file) }; $schema_data->{'#empty'}->{json_empty_null} = ['null', 'null()', "null"]; $schema_data->{'!!str #empty'}->{json_empty_null} = ['str', '', "''"]; %$schema_data = ( %$schema_data, %$strings_data, ); my $boolean = $jsonpp ? 'JSON::PP' : 'perl'; my %args = ( boolean => $boolean, header => 0, ); my $failsafe = YAML::PP->new( %args, schema => [qw/ Failsafe /] ); my $json = YAML::PP->new( %args, schema => [qw/ JSON /] ); my $json_empty_null = YAML::PP->new( %args, schema => [qw/ JSON empty=null /] ); my $core = YAML::PP->new( %args, schema => [qw/ Core /] ); my $yaml11 = YAML::PP->new( %args, schema => [qw/ YAML1_1 /] ); subtest 'invalid-option' => sub { eval { YAML::PP->new( boolean => $boolean, schema => [qw/ JSON empty=lala /] ); }; my $err = $@; like($err, qr{Invalid option}, 'Invalid option is fatal'); }; my %loaders = ( failsafe => $failsafe, json => $json, core => $core, yaml11 => $yaml11, json_empty_null => $json_empty_null, ); my $inf = 0 + 'inf'; my $inf_negative = 0 - 'inf'; my $nan = 0 + 'nan'; diag("inf: $inf -inf: $inf_negative nan: $nan"); my $inf_broken = $inf eq '0'; $inf_broken and diag("inf/nan seem broken, skipping those tests"); my %check = ( null => sub { not defined $_[0] }, inf => sub { my ($float) = @_; return $float eq $inf; }, 'inf-neg' => sub { my ($float) = @_; return $float eq $inf_negative; }, nan => sub { my ($float) = @_; return $float eq $nan; }, ); if ($jsonpp) { %check = ( %check, true => sub { blessed($_[0]) eq 'JSON::PP::Boolean' and $_[0] }, false => sub { blessed($_[0]) eq 'JSON::PP::Boolean' and not $_[0] }, ); } my $i = 0; for my $input (sort keys %$schema_data) { my $test_data = $schema_data->{ $input }; # note("Input: $input"); for my $schema_names (sort keys %$test_data) { note("[$input] Schemas: " . $schema_names); my @names = split m/ *, */, $schema_names; my $test = $test_data->{ $schema_names }; for my $name (@names) { my $yp = $loaders{ $name }; my %def; @def{ qw/ type data dump /} = @$test; next if ($def{type} eq 'bool' and not $jsonpp); my $func; my $data = $yp->load_string('--- ' . $input); my $data_orig = $data; # avoid stringifying original data my $flags = B::svref_2object(\$data)->FLAGS; my $is_str = $flags & B::SVp_POK; my $is_int = $flags & B::SVp_IOK; my $is_float = $flags & B::SVp_NOK; my $type = $def{type}; my $label = sprintf "(%s) type %s: load(%s)", $name, $def{type}, $input; if ($def{data} =~ m/^([\w-]+)\(\)$/) { my $func_name = $1; $func = $check{ $func_name }; my $ok = $func->($data); ok($ok, "$label - check $func_name() ok"); } if ($type eq 'str') { ok($is_str, "$label is str"); ok(! $is_int, "$label is not int"); ok(! $is_float, "$label is not float"); unless ($func) { cmp_ok($def{data}, 'eq', $data, "$label eq '$def{data}'"); } } elsif ($type eq 'int') { ok($is_int, "$label is int"); ok(!$is_str, "$label is not str"); unless ($func) { cmp_ok($data, '==', $def{data}, "$label == '$def{data}'"); } } elsif ($type eq 'float' or $type eq 'inf' or $type eq 'nan') { unless ($inf_broken) { ok($is_float, "$label is float"); ok(!$is_str, "$label is not str"); } unless ($func) { cmp_ok(sprintf("%.2f", $data), '==', $def{data}, "$label == '$def{data}'"); } } elsif ($type eq 'bool' or $type eq 'null') { } else { ok(0, "unknown type $type"); } unless ($inf_broken) { my $yaml_dump = $yp->dump_string($data_orig); $yaml_dump =~ s/\n\z//; cmp_ok($yaml_dump, 'eq', $def{dump}, "$label-dump as expected"); } } } # last if ++$i > 10; } subtest int_string => sub { my $x = "25.1"; my $y = $x + 0; for my $name (qw/ json core yaml11 /) { my $yp = $loaders{ $name }; my $yaml = $yp->dump_string($x); chomp $yaml; cmp_ok($yaml, 'eq', '25.1', "$name: IV and PV"); } }; subtest float_string => sub { my $x = 19; { no warnings 'numeric'; $x .= "x"; my $y = $x + 0; }; for my $name (qw/ json core yaml11 /) { my $yp = $loaders{ $name }; my $yaml = $yp->dump_string($x); chomp $yaml; cmp_ok($yaml, 'eq', '19x', "$name: NV and PV"); } }; done_testing; 07070100000066000081A40000000000000000000000016616D6BA00000637000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/32.cyclic-refs.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Warn; use Data::Dumper; use YAML::PP; my $yaml = <<'EOM'; - &NODEA name: A link: &NODEB name: B link: *NODEA EOM my $yaml2 = <<'EOM'; - &NODEA name: A foo: &NODEA # overwrite anchor bar: boo link: &NODEB name: B link: *NODEA EOM my $fatal = YAML::PP->new( cyclic_refs => 'fatal' ); my $warn = YAML::PP->new( cyclic_refs => 'warn' ); my $ignore = YAML::PP->new( cyclic_refs => 'ignore' ); my $allow = YAML::PP->new( cyclic_refs => 'allow' ); my $fatal2 = YAML::PP->new( ); my $data = eval { $fatal->load_string($yaml); }; my $error = $@; cmp_ok($error, '=~', qr{found cyclic ref}i, "cyclic_refs=fatal"); warning_like { $warn->load_string($yaml); } qr{found cyclic ref}i, "cyclic_refs=warn"; is($data->[0]->{link}->{link}, undef, "cyclic_refs=warn"); $data = $ignore->load_string($yaml); is($data->[0]->{link}->{link}, undef, "cyclic_refs=ignore"); $data = $allow->load_string($yaml); cmp_ok($data->[0]->{link}->{link}->{name}, 'eq', 'A', "cyclic_refs=allow"); $data = eval { $fatal2->load_string($yaml) }; $error = $@; cmp_ok($error, '=~', qr{found cyclic ref}i, "cyclic_refs=default (fatal)"); $data = eval { my $nonsense = YAML::PP->new( cyclic_refs => 'nonsense'); $nonsense->load_string($yaml); }; $error = $@; cmp_ok($error, '=~', qr{invalid}i, "cyclic_refs=nonsense (invalid parameter)"); $data = $fatal->load_string($yaml2); cmp_ok($data->[0]->{link}->{link}->{bar}, 'eq', 'boo', "cyclic_refs=fatal, no cyclic ref found"); done_testing; 07070100000067000081A40000000000000000000000016616D6BA00000769000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/34.emit-scalar-styles.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Data::Dumper; use YAML::PP::Parser; use YAML::PP::Emitter; use YAML::PP::Writer; use YAML::PP; use YAML::PP::Common qw/ :STYLES /; my @input = ( "", " ", "\n", "\na", "a", "a\n", " a", "a ", " a ", "\na\n", "\n a", "\n a\n", "\na \n", "a \n", "\n a \n", "\n\n a \n\n", "\n \n a \n\n", "\n \n a \n \n", " \n a \n ", " \n\n a \n\n ", ); my $emitter = YAML::PP::Emitter->new(); $emitter->set_writer(YAML::PP::Writer->new); my $yp = YAML::PP->new( schema => ['Failsafe'] ); #my @styles = qw/ : " ' | > /; my @styles = ( YAML_PLAIN_SCALAR_STYLE, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE ); for my $style (@styles) { subtest "style $style" => sub { for my $input (@input) { $emitter->init; local $Data::Dumper::Useqq = 1; my $label = Data::Dumper->Dump([$input], ['input']); chomp $label; $emitter->stream_start_event; $emitter->document_start_event({ implicit => 1 }); $emitter->sequence_start_event; $emitter->scalar_event({ value => $input, style => $style }); $emitter->sequence_end_event; $emitter->document_end_event({ implicit => 0 }); $emitter->stream_end_event; my $yaml = $emitter->writer->output; $emitter->finish; my $data = $yp->load_string($yaml); cmp_ok($data->[0], 'eq', $input, "style $style - $label") or do { diag ">>$yaml<<\n"; explain $data; diag(Data::Dumper->Dump([$data], ['data'])); diag(Data::Dumper->Dump([$yaml], ['yaml'])); }; } }; } done_testing; 07070100000068000081A40000000000000000000000016616D6BA00000956000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/35.highlight.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use YAML::PP::Highlight; my $yaml = "foo: bar\n"; my ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens(string => $yaml); delete @$_{qw/ line column /} for @$tokens; my @expected_tokens = ( { name => "PLAIN", value => "foo" }, { name => "COLON", value => ":" }, { name => "WS", value => " " }, { name => "PLAIN", value => "bar" }, { name => "EOL", value => "\n" }, ); is($error, '', "yaml_to_tokens suceeded"); is_deeply($tokens, \@expected_tokens, "yaml_to_tokens returned correct tokens"); $yaml = "foo: \@bar\n"; ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens(string => $yaml); cmp_ok($error, '=~', qr{Invalid}, "yaml_to_tokens returned an error"); delete @$_{qw/ line column /} for @$tokens; @expected_tokens = ( { name => "PLAIN", value => "foo" }, { name => "COLON", value => ":" }, { name => "WS", value => " " }, { name => "ERROR", value => "\@bar\n" }, ); is_deeply($tokens, \@expected_tokens, "yaml_to_tokens returned correct error tokens"); $yaml = <<'EOM'; foo: | bar quoted: "x" EOM ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens(string => $yaml); my @transformed = YAML::PP::Highlight->transform($tokens); cmp_ok($transformed[6]->{name}, 'eq', 'TRAILING_SPACE', "trailing spaces detected"); my $color = eval "use Term::ANSIColor 4.02; 1"; # older versions of Term::ANSIColor didn't have grey12 if ($color) { my $highlighted = YAML::PP::Highlight::Dump({ foo => 'bar' }); my $exp_highlighted = "\e[1m---\e[0m\n\e[94mfoo\e[0m\e[1;35m:\e[0m bar\n"; cmp_ok($highlighted, 'eq', $exp_highlighted, "YAML::PP::Highlight::Dump()"); } if ($color) { my $yaml = <<'EOM'; foo: bar EOM my ($error, $tokens) = YAML::PP::Parser->yaml_to_tokens(string => $yaml); my $ansitabs = YAML::PP::Highlight->ansicolored($tokens, expand_tabs => 0); my $ansi = YAML::PP::Highlight->ansicolored($tokens); local $Data::Dumper::Useqq = 1; my $exp1 = "\e[94mfoo\e[0m\e[1;35m:\e[0m bar\e[44m\t\e[0m\n"; my $exp2 = "\e[94mfoo\e[0m\e[1;35m:\e[0m bar\e[44m \e[0m\n"; is $ansitabs, $exp1, 'ansicolored, no expanded tabs' or do { diag(Data::Dumper->Dump([$ansitabs], ['ansitabs'])); }; is $ansi, $exp2, 'ansicolored, expanded tabs' or do { diag(Data::Dumper->Dump([$ansi], ['ansi'])); }; } done_testing; 07070100000069000081A40000000000000000000000016616D6BA00000214000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/36.debug.t#!/usr/bin/env perl use strict; use warnings; use Test::More; #$ENV{YAML_PP_TRACE} = 1; BEGIN { $ENV{YAML_PP_DEBUG} = 1; } use YAML::PP::Parser; my $yaml = "foo: bar"; my $parser = YAML::PP::Parser->new( receiver => sub {} ); no warnings 'redefine'; my $output = ''; *YAML::PP::Parser::_colorize_warn = sub { my ($self, $colors, $text) = @_; $output .= "$text\n"; }; *YAML::PP::Parser::highlight_yaml = sub { }; $parser->parse_string($yaml); cmp_ok($output, '=~', qr{lex_next_tokens}, "Debug output"); done_testing; 0707010000006A000081A40000000000000000000000016616D6BA00002778000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/37.schema-perl.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use Scalar::Util (); use YAML::PP; use YAML::PP::Perl; my $test_deep; BEGIN { eval "use Test::Deep qw/ cmp_deeply /"; unless ($@) { $test_deep = 1; } } unless ($test_deep) { plan skip_all => "No Test::Deep available"; exit; } my $tests = require "$Bin/../examples/schema-perl.pm"; my $perl_no_objects = YAML::PP::Schema::Perl->new( classes => [], cyclic_refs => 'allow', ); my $perl_no_objects_loadcode = YAML::PP::Schema::Perl->new( classes => [], loadcode => 1, cyclic_refs => 'allow', ); my $yp_perl = YAML::PP::Perl->new( schema => [qw/ JSON Perl tags=!perl /], cyclic_refs => 'allow', ); my $yp_perl_no_objects = YAML::PP::Perl->new( schema => [qw/ JSON /, $perl_no_objects], cyclic_refs => 'allow', ); my $yp_loadcode = YAML::PP->new( schema => [qw/ JSON Perl +loadcode /], cyclic_refs => 'allow', ); my $yp_loadcode_no_objects = YAML::PP->new( schema => [qw/ JSON /, $perl_no_objects_loadcode], cyclic_refs => 'allow', ); my $yp_perl_two = YAML::PP::Perl->new( schema => [qw/ JSON Perl tags=!!perl /], cyclic_refs => 'allow', ); my $yp_loadcode_two = YAML::PP->new( schema => [qw/ JSON Perl tags=!!perl +loadcode /], cyclic_refs => 'allow', ); my $yp_loadcode_one_two = YAML::PP->new( schema => [qw/ JSON Perl tags=!perl+!!perl +loadcode /], cyclic_refs => 'allow', ); my $yp_loadcode_two_one = YAML::PP->new( schema => [qw/ JSON Perl tags=!!perl+!perl +loadcode /], cyclic_refs => 'allow', ); my $yp_perl_one_two = YAML::PP::Perl->new( schema => [qw/ JSON Perl tags=!perl+!!perl /], cyclic_refs => 'allow', ); my $yp_perl_two_one = YAML::PP::Perl->new( schema => [qw/ JSON Perl tags=!!perl+!perl /], cyclic_refs => 'allow', ); my $yp_no_dumpcode = YAML::PP::Perl->new( schema => [qw/ + Perl -dumpcode /], ); my @tests = sort keys %$tests; @tests = qw/ array array_blessed hash hash_blessed scalarref scalarref_blessed refref refref_blessed coderef coderef_blessed regexp regexp_blessed circular /; { my $test_qr = qr{TEST_STRINGYFY_REGEX}; my $test_qr_string = "$test_qr"; diag("TEST QR: $test_qr_string"); my $qr_prefix = $test_qr_string; $qr_prefix =~ s/TEST_STRINGYFY_REGEX.*//; diag("QR PREFIX: $qr_prefix"); } my %loaders_perl = ( one => $yp_perl, one_no_objects => $yp_perl_no_objects, two => $yp_perl_two, onetwo => $yp_perl_one_two, twoone => $yp_perl_two_one, ); my %loaders_perl_code = ( one => $yp_loadcode, one_no_objects => $yp_loadcode_no_objects, two => $yp_loadcode_two, onetwo => $yp_loadcode_one_two, twoone => $yp_loadcode_two_one, ); my @tagtypes = qw/ one two onetwo twoone /; for my $type (@tagtypes) { for my $name (@tests) { test_perl($type, $name); } } sub test_perl { my ($type, $name) = @_; my $test = $tests->{ $name }; my $yp = $yp_perl; $yp = $loaders_perl{ $type }; my ($code, $yaml, $options) = @$test; if ($type eq 'two' or $type eq 'twoone') { unless (ref $yaml) { $yaml =~ s/\!perl/!!perl/g; } } my $data = eval $code; my $docs = [ $data, $data ]; my $out; if ($options->{load_code}) { $yp = $loaders_perl_code{ $type }; } if ($options->{load_only}) { $out = $yaml; } else { $out = $yp->dump_string($docs); if (ref $yaml) { cmp_ok($out, '=~', $yaml, "tagtype=$type $name: dump_string()"); } else { cmp_ok($out, 'eq', $yaml, "tagtype=$type $name: dump_string()"); } note($out); } my $reload_docs = $yp->load_string($out); if (Scalar::Util::reftype($data) eq 'CODE') { my $sub = $reload_docs->[0]; if (ref $sub and Scalar::Util::reftype($sub) eq 'CODE') { my %args = ( x => 23, y => 42 ); my $result1 = $data->(%args); my $result2 = $sub->(%args); cmp_ok($result2, 'eq', $result1, "tagtype=$type Coderef returns the same as original"); } else { ok(0, "tagtype=$type Did not reload as coderef"); } } else { cmp_deeply($reload_docs, $docs, "tagtype=$type $name: Reloaded data equals original"); } } subtest dummy_code => sub { my $yaml = <<'EOM'; --- - !perl/code | { die "oops"; } - !perl/code:Foo | { die "oops"; } EOM my $data = $yp_perl->load_string($yaml); my $code1 = $data->[0]; my $code2 = $data->[1]; isa_ok($code2, 'Foo', "Code is blessed 'Foo'"); is($code1->(), undef, "Dummy code 1 returns undef"); is($code2->(), undef, "Dummy code 2 returns undef"); }; subtest invalid_code => sub { my $yaml = <<'EOM'; --- - !perl/code | die "oops"; EOM my $data = eval { $yp_loadcode->load_string($yaml) }; my $error = $@; cmp_ok($error, '=~', qr{Malformed code}, "Loading invalid code dies"); $yaml = <<'EOM'; --- - !perl/code:Foo | die "oops"; EOM $data = eval { $yp_loadcode->load_string($yaml) }; $error = $@; cmp_ok($error, '=~', qr{Malformed code}, "Loading invalid code dies"); $yaml = <<'EOM'; --- - !perl/code | { =====> invalid <===== } EOM $data = eval { $yp_loadcode->load_string($yaml) }; $error = $@; cmp_ok($error, '=~', qr{eval code}, "Loading invalid code dies"); $yaml = <<'EOM'; --- - !perl/code:Foo | { =====> invalid <===== } EOM $data = eval { $yp_loadcode->load_string($yaml) }; $error = $@; cmp_ok($error, '=~', qr{eval code}, "Loading invalid code dies"); }; subtest regex => sub { my $re = qr{foo}; my $yaml = <<"EOM"; --- - !perl/regexp $re - !perl/regexp:Foo $re EOM my $data = $yp_perl->load_string($yaml); my ($regex1, $regex2) = @$data; isa_ok($regex2, 'Foo', "Regex is blessed 'Foo'"); cmp_ok('foo', '=~', $regex1, "Loaded regex 1 matches"); cmp_ok('foo', '=~', $regex2, "Loaded regex 2 matches"); }; subtest simple_array => sub { my $yaml = <<"EOM"; --- !perl/array [a, b] EOM my $data = $yp_perl->load_string($yaml); cmp_deeply($data, [qw/ a b /], "Loaded simple array"); }; subtest invalid_ref => sub { my @yaml = ( ['!perl/ref', q#--- !perl/ref {==: Invalid}#], ['!perl/ref:Foo', q#--- !perl/ref:Foo {==: Invalid}#], ['!perl/scalar', q#--- !perl/scalar {==: Invalid}#], ['!perl/scalar:Foo', q#--- !perl/scalar:Foo {==: Invalid}#], ['!perl/ref', q#--- !perl/ref {}#], ['!perl/ref:Foo', q#--- !perl/ref:Foo {}#], ['!perl/scalar', q#--- !perl/scalar {}#], ['!perl/scalar:Foo', q#--- !perl/scalar:Foo {}#], ); for my $test (@yaml) { my ($type, $yaml) = @$test; my $data = eval { $yp_perl->load_string($yaml) }; my $error = $@; cmp_ok($error, '=~', qr{Unexpected data}, "Invalid $type dies"); } }; subtest array => sub { my $object = bless [qw/ a b /], "Foo"; my $yaml_one_two = $yp_perl_one_two->dump_string($object); my $yaml_one_two_expected = <<'EOM'; --- !perl/array:Foo - a - b EOM my $yaml_two_one_expected = <<'EOM'; --- !!perl/array:Foo - a - b EOM my $yaml_two_one = $yp_perl_two_one->dump_string($object); cmp_ok($yaml_one_two, 'eq', $yaml_one_two_expected, "Perl =!+!! dump"); cmp_ok($yaml_two_one, 'eq', $yaml_two_one_expected, "Perl =!!+! dump"); my $reload1 = $yp_perl_two_one->load_string($yaml_one_two); my $reload2 = $yp_perl_two_one->load_string($yaml_two_one); my $reload3 = $yp_perl_one_two->load_string($yaml_one_two); my $reload4 = $yp_perl_one_two->load_string($yaml_two_one); cmp_deeply($reload1, $object, "Reload 1"); cmp_deeply($reload2, $object, "Reload 2"); cmp_deeply($reload3, $object, "Reload 3"); cmp_deeply($reload4, $object, "Reload 4"); }; subtest no_objects => sub { my $yaml = <<'EOM'; --- - !perl/array:Foo [a] - !perl/hash:Foo { a: 1 } - !perl/code:Foo "sub { return 23 }" - !perl/ref:Foo { = : { a: 1 } } - !perl/scalar:Foo { = : foo } - !perl/regexp:Foo foo EOM my $perl = YAML::PP::Schema::Perl->new( classes => [], ); my $yp = YAML::PP::Perl->new( schema => [qw/ JSON /, $perl], ); my $data = $yp->load_string($yaml); for my $i (0 .. $#$data) { my $item = $data->[ $i ]; my $blessed = Scalar::Util::blessed($item) || ''; if ($blessed eq 'Regexp') { ok(1, "Data $i not blessed"); } else { cmp_ok($blessed, 'eq', '', "Data $i not blessed"); } } }; subtest some_objects => sub { my $yaml = <<'EOM'; --- - !perl/array:Foo [a] - !perl/hash:Foo { a: 1 } - !perl/code:Foo "sub { return 23 }" - !perl/ref:Foo { = : { a: 1 } } - !perl/scalar:Foo { = : foo } - !perl/regexp:Foo foo - !perl/array:Bar [a] - !perl/hash:Bar { a: 1 } - !perl/code:Bar "sub { return 23 }" - !perl/ref:Bar { = : { a: 1 } } - !perl/scalar:Bar { = : foo } - !perl/regexp:Bar foo EOM my $perl = YAML::PP::Schema::Perl->new( classes => ['Bar'], ); my $yp = YAML::PP::Perl->new( schema => [qw/ JSON /, $perl], ); my $data = $yp->load_string($yaml); for my $i (0 .. $#$data) { my $item = $data->[ $i ]; my $blessed = Scalar::Util::blessed($item) || ''; if ($blessed eq 'Regexp') { ok(1, "Data $i not blessed"); } elsif ($i > 5) { cmp_ok($blessed, 'eq', 'Bar', "Data $i blessed"); } else { cmp_ok($blessed, 'eq', '', "Data $i not blessed"); } } }; subtest no_dumpcode => sub { my $code1 = sub { 23 }; my $code2 = sub { 23 }; my $data = { foo => bless ($code1, "Foo"), bar => $code2 }; my $yaml = $yp_no_dumpcode->dump_string($data); my $exp = <<'EOM'; --- bar: !perl/code '{ "DUMMY" }' foo: !perl/code:Foo '{ "DUMMY" }' EOM is $yaml, $exp, "Use -loadcode"; }; done_testing; 0707010000006B000081A40000000000000000000000016616D6BA000002E9000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/38.schema-ixhash.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my $ixhash = eval { require Tie::IxHash }; unless ($ixhash) { plan skip_all => "Tie::IxHash not installed"; exit; } my $tests = require "$Bin/../examples/schema-ixhash.pm"; my $yp = YAML::PP->new( schema => [qw/ JSON Perl Tie::IxHash /], ); my @tests = sort keys %$tests; for my $name (@tests) { my $test = $tests->{ $name }; my ($code, $yaml) = @$test; my $data = eval $code; my $out = $yp->dump_string([$data, $data]); if (ref $yaml) { cmp_ok($out, '=~', $yaml, "$name: dump_string()"); } else { cmp_ok($out, 'eq', $yaml, "$name: dump_string()"); } } done_testing; 0707010000006C000081A40000000000000000000000016616D6BA000004A2000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/39.emitter-alias.t#!/usr/bin/env perl use strict; use warnings; use Test::More tests => 1; use YAML::PP; use YAML::PP::Common; use YAML::PP::Emitter; use YAML::PP::Writer; my $writer = YAML::PP::Writer->new; my $emitter = YAML::PP::Emitter->new(); $emitter->set_writer($writer); my @events = ( '+STR', '+DOC ---', '+SEQ', '+MAP &map <tag:yaml.org,2002:map>', '=VAL <tag:yaml.org,2002:str> :foo', '=VAL :bar', '-MAP', '+SEQ', '=ALI *map', '=ALI *map', '-SEQ', '+MAP', '=ALI *map', '=VAL :foo', '=ALI *map', '=VAL :foo', '-MAP', '+MAP', '+SEQ <tag:yaml.org,2002:seq>', '-SEQ', '=ALI *map', '-MAP', '+MAP', '+MAP <tag:yaml.org,2002:map>', '-MAP', '=ALI *map', '-MAP', '-SEQ', '-DOC', '-STR', ); for my $str (@events) { my $event = YAML::PP::Common::test_suite_to_event($str); my $name = $event->{name}; $emitter->$name($event); } my $yaml = $emitter->writer->output; my $exp = <<'EOM'; --- - &map !!map !!str foo: bar - - *map - *map - *map : foo *map : foo - ? !!seq [] : *map - ? !!map {} : *map EOM cmp_ok($yaml, 'eq', $exp, "alias_event correct"); 0707010000006D000081A40000000000000000000000016616D6BA00000B3C000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/t/40.representers.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use YAML::PP; { my $parser = YAML::PP->new; $parser->schema->add_representer( class_equals => 'Class1', code => sub { my ($representer, $node) = @_; $node->{ tag } = '!Class1', $node->{ data } = \%{ $node->{ value } }; return 1; } ); my $data = { o1 => (bless {}, 'Class1'), o2 => (bless {}, 'Class2'), }; my $yaml = $parser->dump_string($data); like($yaml, qr/o1: !Class1/, 'o1s\' class has a representer that converts it to a tag'); like($yaml, qr/o2: \{\}/, 'o2s\' class doesn\'t have a representer. It gets converted to an empty hash'); } { my $parser = YAML::PP->new; $parser->schema->add_representer( class_matches => 1, code => sub { my ($representer, $node) = @_; if ($node->{ value }->isa('Class1')) { $node->{ tag } = '!Class1'; $node->{ data } = \%{ $node->{ value } }; return 1; } return 0; } ); $parser->schema->add_representer( class_matches => 1, code => sub { my ($representer, $node) = @_; $node->{ tag } = '!Class2'; $node->{ data } = \%{ $node->{ value } }; return 1; } ); my $data = { o1 => (bless {}, 'Class1'), o2 => (bless {}, 'Class2'), }; my $yaml = $parser->dump_string($data); # o1 serializes to Class1 because the first catchall says it's done like($yaml, qr/o1: !Class1/, 'o1s\' gets caught only by the first class_matches, since it sets work as done'); like($yaml, qr/o2: !Class2/, 'o2s\' gets caught by the second class_matches'); } # declare some packages inline for the next test package BaseClass; package Class4; our @ISA = ('BaseClass'); # return to the tests package package main; { my $parser = YAML::PP->new; $parser->schema->add_representer( class_isa => 'Class3', code => sub { my ($representer, $node) = @_; $node->{ tag } = '!Class3'; $node->{ data } = \%{ $node->{ value } }; return 1; } ); $parser->schema->add_representer( class_isa => 'BaseClass', code => sub { my ($representer, $node) = @_; $node->{ tag } = '!BaseClass'; $node->{ data } = \%{ $node->{ value } }; return 1; } ); my $data = { o3 => (bless {}, 'Class3'), o4 => (bless {}, 'Class4'), }; my $yaml = $parser->dump_string($data); like($yaml, qr/o3: !Class3/, 'Class3 gets caught by its class name'); like($yaml, qr/o4: !BaseClass/, 'Class4 gets caught because its inherited from BaseClass'); } done_testing; 0707010000006E000081A40000000000000000000000016616D6BA00000222000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/41.custom.schema.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use YAML::PP; use YAML::PP::Common qw/ :PRESERVE /; use FindBin '$Bin'; use lib "$Bin/lib"; my $yp = YAML::PP->new( schema => [qw/ :MySchema /], preserve => PRESERVE_ORDER, ); my $yaml = <<'EOM'; --- o1: !Class1 z: 1 a: 2 y: 3 b: 4 EOM my $data = $yp->load_string($yaml); $yaml = $yp->dump_string($data); cmp_ok($yaml, 'eq', <<EOY, '$data serializes with the schema in t/lib/MySchema.pm'); --- o1: !Class1 id: 23 z: 1 a: 2 y: 3 b: 4 EOY done_testing; 0707010000006F000081A40000000000000000000000016616D6BA0000035D000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/42.tokens.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use YAML::PP; use YAML::PP::Parser; use Data::Dumper; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; my @skip = qw/ 4FJ6 87E4 8UDB 9MMW CN3R CT4Q L9U5 LQZ7 LX3P Q9WF QF4Y 6BFJ CFD4 M2N8:01 UKK6:01 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); sub test { my ($testsuite, $testcase) = @_; my $result = $testsuite->parse_tokens($testcase); $testsuite->compare_tokens($testcase, $result); return $result; } done_testing; 07070100000070000081A40000000000000000000000016616D6BA00000CB5000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/43.indent.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use YAML::PP; use Data::Dumper; my $in = <<'EOM'; --- a: b: c: d list: - 1 - x: 2 y: 3 nested1: - - a - b nested2: - - a - b EOM my $out_expected1 = <<'EOM'; --- a: b: c: d list: - 1 - x: 2 y: 3 nested1: - - a - b nested2: - - a - b EOM my $out_expected4 = <<'EOM'; --- a: b: c: d list: - 1 - x: 2 y: 3 nested1: - - a - b nested2: - - a - b EOM my @events; my $parser = YAML::PP::Parser->new( receiver => sub { my ($parser, $name, $info) = @_; push @events, $info; }, ); $parser->parse_string( $in ); my $writer = YAML::PP::Writer->new; my $emitter = YAML::PP::Emitter->new( indent => 1); $emitter->set_writer($writer); $emitter->init; for my $event (@events) { my $type = $event->{name}; $emitter->$type($event); } my $out1 = $emitter->writer->output; cmp_ok($out1, 'eq', $out_expected1, "Emitting with indent 1"); $emitter->set_indent(4); $emitter->init; for my $event (@events) { my $type = $event->{name}; $emitter->$type($event); } my $out4 = $emitter->writer->output; cmp_ok($out4, 'eq', $out_expected4, "Emitting with indent 4"); $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; # skip tests that parser can't parse my @skip = qw/ 4FJ6 4ABK 87E4 8UDB 9MMW CN3R CT4Q FRK4 L9U5 LQZ7 LX3P Q9WF QF4Y 6BFJ F6MC NB6Z CFD4 M2N8:01 UKK6:01 /; # emitter push @skip, qw/ /; # quoting push @skip, qw/ 36F6 6CA3 9YRD HS5T EX5H NAT4 L24T:00 L24T:01 DK95:00 DK95:02 DK95:03 DK95:04 DK95:05 DK95:07 DK95:08 /; # tags push @skip, qw/ v014 /; # block scalar push @skip, qw/ 4QFQ 6VJK 7T8X R4YG v033 /; # test push @skip, qw/ XLQ9 K54U PUW8 3MYT MJS9 /; # TODO fix testsuite # 4QFQ # unicode push @skip, qw/ H3Z8 /; push @skip, qw/ X38W /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, emit_yaml => 1, ); my %skip_yaml_equal = ( 'X38W' => 1, 'G4RS' => 1, '6CK3' => 1, '5TYM' => 1, '565N' => 1, # fix testsuite 'K858' => 1, '4MUZ' => 1, '8KB6' => 1, '9BXH' => 1, '6ZKB' => 1, '6SLA' => 1, '9DXL' => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); my $indent = 1; subtest "indent-$indent" => sub { $testsuite->run_testcases( code => sub { test(@_, $indent) }, ); }; subtest "indent-$indent" => sub { $indent = 3; $testsuite->run_testcases( code => sub { test(@_, $indent) }, ); }; subtest "indent-$indent" => sub { $indent = 4; $testsuite->run_testcases( code => sub { test(@_, $indent) }, ); }; $testsuite->print_stats( count => [qw/ SAME_EVENTS SAME_YAML DIFF_EVENTS DIFF_YAML ERROR TODO SKIP /], ids => [qw/ DIFF_YAML DIFF_EVENTS /], ); sub test { my ($testsuite, $testcase, $indent) = @_; my $id = $testcase->{id}; my $result = $testsuite->emit_yaml($testcase, { indent => $indent }); delete $result->{emit_yaml}; $testsuite->compare_emit_yaml($testcase, $result); } done_testing; 07070100000071000081A40000000000000000000000016616D6BA00000369000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/44.writer.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use YAML::PP; use Data::Dumper; my $in = <<'EOM'; --- a: b: c: d list: - 1 - 2 EOM my $out_expected = <<'EOM'; --- a: b: c: d list: - 1 - 2 EOM my $writer = MyWriter->new(\my $output); my $yp = YAML::PP->new( writer => $writer, ); my $data = $yp->load_string($in); $yp->dump($data); cmp_ok($output, 'eq', $out_expected, "Dumping with indent"); done_testing; package MyWriter; sub new { my ($class, $ref) = @_; die "No scalar reference given" unless $ref; $$ref = '' unless defined $$ref; bless { output => $ref }, $class; } sub write { my ($self, $line) = @_; ${ $self->{output} } .= $line; } sub init { ${ $_[0]->{output} } = ''; } sub finish { my ($self) = @_; } sub output { my ($self) = @_; return "dummy"; return ${ $self->{output} }; } 07070100000072000081A40000000000000000000000016616D6BA00000FF4000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/45.binary.t#!/usr/bin/env perl use strict; use warnings; use Test::More tests => 3; use YAML::PP; use Encode; use Data::Dumper; my $yp_binary = YAML::PP->new( schema => [qw/ JSON Binary /] ); my $yp = YAML::PP->new( schema => [qw/ JSON /] ); my $gif = "GIF89a\f\0\f\0\204\0\0\377\377\367\365\365\356\351\351\345fff" . "\0\0\0\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237" . "\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377" . "\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371" . "\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376" . "\371\377\376\371\377\376\371!\376\16Made with GIMP\0,\0\0\0\0\f\0\f" . "\0\0\5, \216\2010\236\343\@\24\350i\20\304\321\212\b\34\317\200" . "M\$z\357\3770\205p\270\2601f\r\e\316\1\303\1\36\20' \202\n\1\0;"; subtest load_binary => sub { my $yaml = <<'EOM'; canonical: !!binary "\ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" EOM my $data = $yp_binary->load_string($yaml); cmp_ok($data->{canonical}, 'eq', $gif, "Loaded binary equals gif"); my $base64 = "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5" . "OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+" . "+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC" . "AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="; my $load = $yp->load_string($yaml); cmp_ok($load->{canonical}, 'eq', $base64, "Load back literally"); }; my $latin1_a_umlaut = encode(latin1 => (decode_utf8 "ä")); my @tests = ( [utf8 => "a"], [binary => $latin1_a_umlaut], [binary => "\304\244",], [utf8 => decode_utf8("\304\244"),], [binary => "a umlaut ä",], [utf8 => decode_utf8("a umlaut ä"),], [binary => "euro €",], [utf8 => decode_utf8("euro €"),], [binary => "\303\274 \374",], [binary => "\xC0\x80"], [binary => "\xC0\xAF"], [binary => "\xE0\x80\x80"], [binary => "\xF0\x80\x80\x80"], [binary => "\xE0\x83\xBF"], [binary => "\xF0\x80\x83\xBF"], [binary => "\xF0\x80\xA3\x80"], [binary => [$gif, decode_utf8("ä")],], [binary => [$gif, 'foo'],], ); subtest roundtrip => sub { for my $item (@tests) { select undef, undef, undef, 0.1; my ($type, $data) = @$item; local $Data::Dumper::Useqq = 1; my $label = Data::Dumper->Dump([$data], ['data']); chomp $label; note("\n\n\n=============== $type: $label"); my $dump = $yp->dump_string($data); #note("========= YAML:\n$dump"); my $reload = $yp->load_string($dump); if (ref $reload eq 'ARRAY') { cmp_ok($reload->[0], 'eq', $data->[0], "Reload binary->[0] ok ($label)"); cmp_ok($reload->[1], 'eq', $data->[1], "Reload binary->[1] ok ($label)"); } else { cmp_ok($reload, 'eq', $data, "Reload binary ok ($label)"); } } }; subtest roundtrip_binary => sub { for my $item (@tests) { my ($type, $data) = @$item; local $Data::Dumper::Useqq = 1; my $label = Data::Dumper->Dump([$data], ['data']); note("=============== $type: $label"); my $dump = $yp_binary->dump_string($data); if ($type eq 'binary') { like($dump, qr{!!binary}, "Output YAML contains !!binary"); } else { unlike($dump, qr{!!binary}, "Output YAML does not contain !!binary"); } my $reload = $yp_binary->load_string($dump); if (ref $reload eq 'ARRAY') { cmp_ok($reload->[0], 'eq', $data->[0], "Reload binary->[0] ok ($label)"); cmp_ok($reload->[1], 'eq', $data->[1], "Reload binary->[1] ok ($label)"); } else { cmp_ok($reload, 'eq', $data, "Reload binary ok ($label)"); } } }; done_testing; 07070100000073000081A40000000000000000000000016616D6BA00000266000000000000000000000000000000000000003900000000perl-YAML-PP-3.14.1712772794.39ac610/t/46.line-endings.t#!/usr/bin/env perl use strict; use warnings; use Test::More tests => 2; use YAML::PP; use Encode; use Data::Dumper; my $yp = YAML::PP->new; subtest mac => sub { my $yaml = qq{x: "a\r b"\ry: b\r}; my $data = $yp->load_string($yaml); my $expected = { x => 'a b', y => 'b', }; is_deeply($data, $expected, 'Mac \r line endings'); }; subtest win => sub { my $yaml = qq{x: "a\r\n b"\ry: b\r}; my $data = $yp->load_string($yaml); my $expected = { x => 'a b', y => 'b', }; is_deeply($data, $expected, 'Win \r\n line endings'); }; done_testing; 07070100000074000081A40000000000000000000000016616D6BA000005BC000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/47.header-footer.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use YAML::PP; use Data::Dumper; my $in = <<'EOM'; --- foo --- a: 1 --- - a - b ... EOM subtest header_no_footer => sub { my $out_expected = <<'EOM'; --- foo --- a: 1 --- - a - b EOM my $yp = YAML::PP->new( header => 1, footer => 0, ); my @docs = $yp->load_string($in); my $out = $yp->dump_string(@docs); cmp_ok($out, 'eq', $out_expected, "Dumping with indent"); }; subtest no_header_no_footer => sub { my $out_expected = <<'EOM'; foo --- a: 1 --- - a - b EOM my $yp = YAML::PP->new( header => 0, footer => 0, ); my @docs = $yp->load_string($in); my $out = $yp->dump_string(@docs); cmp_ok($out, 'eq', $out_expected, "Dumping with indent"); }; subtest header_footer => sub { my $out_expected = <<'EOM'; --- foo ... --- a: 1 ... --- - a - b ... EOM my $yp = YAML::PP->new( header => 1, footer => 1, ); my @docs = $yp->load_string($in); my $out = $yp->dump_string(@docs); cmp_ok($out, 'eq', $out_expected, "Dumping with indent"); }; subtest no_header_footer => sub { my $out_expected = <<'EOM'; foo ... --- a: 1 ... --- - a - b ... EOM my $yp = YAML::PP->new( header => 0, footer => 1, ); my @docs = $yp->load_string($in); my $out = $yp->dump_string(@docs); cmp_ok($out, 'eq', $out_expected, "Dumping with indent"); }; done_testing; 07070100000075000081A40000000000000000000000016616D6BA000006F9000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/48.merge.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; # https://yaml.org/type/merge.html my $yp = YAML::PP->new( schema => [qw/ JSON Merge /], ); subtest merge => sub { my $yaml = <<'EOM'; --- - &CENTER { x: 1, y: 2 } - &LEFT { x: 0, y: 2 } - &BIG { r: 10 } - &SMALL { r: 1 } # All the following maps are equal: - # Explicit keys x: 1 y: 2 r: 10 label: center/big - # Merge one map << : *CENTER r: 10 label: center/big - # Merge multiple maps << : [ *CENTER, *BIG ] label: center/big - # Override << : [ *BIG, *LEFT, *SMALL ] x: 1 label: center/big EOM my $data = $yp->load_string($yaml); my $expected = { label => 'center/big', x => 1, y => 2, r => 10, }; is_deeply($data->[4], $expected, "Merge: Explicit keys"); is_deeply($data->[5], $expected, "Merge: Merge one map"); is_deeply($data->[6], $expected, "Merge: Merge multiple maps"); is_deeply($data->[7], $expected, "Merge: Override"); }; subtest errors => sub { my $error1 = <<'EOM'; --- scalar: &scalar test merge: <<: *scalar EOM my $error2 = <<'EOM'; --- scalar: &scalar test merge: <<: [*scalar] EOM my $error3 = <<'EOM'; --- list: &list [23] merge: <<: [*list] EOM eval { my $data = $yp->load_string($error1); }; my $error = $@; cmp_ok($error, '=~', qr{Expected hash}, "Merge: invalid scalar"); eval { my $data = $yp->load_string($error2); }; $error = $@; cmp_ok($error, '=~', qr{Expected hash}, "Merge: invalid scalar"); eval { my $data = $yp->load_string($error3); }; $error = $@; cmp_ok($error, '=~', qr{Expected hash}, "Merge: invalid list"); }; done_testing; 07070100000076000081A40000000000000000000000016616D6BA000009E0000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/49.include.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; use YAML::PP::Schema::Include; use File::Spec; use Scalar::Util qw/ refaddr /; my $test_deep; BEGIN { eval "use Test::Deep qw/ cmp_deeply /"; unless ($@) { $test_deep = 1; } } unless ($test_deep) { plan skip_all => "No Test::Deep available"; exit; } my $include_path = "$Bin/data/include"; my $valid_yaml = <<'EOM'; --- - !include include1.yaml - !include include2.yaml - item3 EOM my $invalid_yaml = <<'EOM'; --- - !include ../../../../../../../../../../../etc/passwd EOM my $invalid_yaml2 = <<'EOM'; --- - !include /etc/passwd EOM my $expected = [ 'include1', [ 'include2', 'include3', ], 'item3', ]; my %objects; sub YAML::PP::DESTROY { my ($self) = @_; my $addr = refaddr($self); $objects{ $addr }--; } my $addr; subtest schema_include => sub { my $include = YAML::PP::Schema::Include->new( paths => $include_path ); my $yp = YAML::PP->new( schema => ['JSON', $include] ); $include->yp($yp); $addr = refaddr($yp); $objects{ $addr }++; my ($data) = $yp->load_string($valid_yaml); is_deeply($data, $expected, "!include"); }; cmp_ok($objects{ $addr }, 'eq', 0, "YAML::PP object was destroyed correctly"); subtest invalid_schema_include => sub { my $include = YAML::PP::Schema::Include->new( paths => $include_path, ); my $yp = YAML::PP->new( schema => ['JSON', $include] ); $include->yp($yp); my ($data) = eval { $yp->load_string($invalid_yaml) }; my $error = $@; cmp_ok($error, '=~', "not found", "Filter out .."); ($data) = eval { $yp->load_string($invalid_yaml2) }; $error = $@; cmp_ok($error, '=~', "Absolute filenames not allowed", "No absolute filenames"); }; subtest schema_include_filename => sub { my $include = YAML::PP::Schema::Include->new; my $yp = YAML::PP->new( schema => ['JSON', $include] ); $include->yp($yp); my ($data) = $yp->load_file("$include_path/include.yaml"); is_deeply($data, $expected, "!include"); }; subtest schema_include_circular => sub { my $include = YAML::PP::Schema::Include->new; my $yp = YAML::PP->new( schema => ['JSON', $include] ); $include->yp($yp); my ($data) = eval { $yp->load_file("$include_path/circular1.yaml"); }; my $error = $@; cmp_ok($@, '=~', "Circular include", "Circular include detected"); }; done_testing; 07070100000077000081A40000000000000000000000016616D6BA00000315000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/50.clone.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use YAML::PP; my $yp = YAML::PP->new( cyclic_refs => 'fatal', schema => ['Failsafe'], ); my $string = 'bar'; my $data = { foo => bless \$string, 'Foo' }; my $invalid = <<'EOM'; --- foo: @invalid EOM eval { $yp->load_string($invalid); }; ok($@, "load invalid YAML"); eval { $yp->dump_string($data); }; ok($@, "dump unsupported data"); my $clone = $yp->clone; my $valid = <<'EOM'; --- foo: bar EOM my $valid_data = { foo => 'bar' }; my $load = $clone->load_string($valid); is_deeply($load, $valid_data, "Second load ok"); my $dump = $clone->dump_string($load); my $exp_dump = <<'EOM'; --- foo: bar EOM cmp_ok($dump, 'eq', $exp_dump, "Second dump ok"); done_testing; 07070100000078000081A40000000000000000000000016616D6BA00001799000000000000000000000000000000000000003700000000perl-YAML-PP-3.14.1712772794.39ac610/t/51.directives.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use YAML::PP; subtest 'emit-yaml-directive' => sub { my $yp = YAML::PP->new( version_directive => 1, header => 0, # this should be overruled by version_directive ); my $yp_footer = YAML::PP->new( version_directive => 1, footer => 1, yaml_version => '1.1', ); my @docs = ( { a => 1 }, [ b => 2 ], 'c3', ); my $yaml = $yp->dump_string(@docs); my $yaml_footer = $yp_footer->dump_string(@docs); my $exp = <<'EOM'; %YAML 1.2 --- a: 1 ... %YAML 1.2 --- - b - 2 ... %YAML 1.2 --- c3 EOM my $exp_footer = <<'EOM'; %YAML 1.1 --- a: 1 ... %YAML 1.1 --- - b - 2 ... %YAML 1.1 --- c3 ... EOM is($yaml, $exp, 'Emit version directive'); is($yaml_footer, $exp_footer, 'Emit version directive (footer=1)'); }; subtest 'yaml-version' => sub { my $yaml = <<'EOM'; %YAML 1.2 --- a: 1 --- b: 2 ... %YAML 1.1 --- c: 3 --- b: 4 EOM my @events; my $receiver = sub { my ($p, $name, $event) = @_; if ($event->{name} eq 'document_start_event') { push @events, $event; } }; my $parser = YAML::PP::Parser->new( receiver => $receiver, ); my $parser_1_1 = YAML::PP::Parser->new( receiver => $receiver, default_yaml_version => '1.1', ); $parser->parse_string($yaml); is($events[0]->{version_directive}->{major}, '1', 'YAML 1.2 detected'); is($events[0]->{version_directive}->{minor}, '2', 'YAML 1.2 detected'); ok(! exists $events[1]->{version_directive}, 'No version directive'); is($events[2]->{version_directive}->{major}, '1', 'YAML 1.1 detected'); is($events[2]->{version_directive}->{minor}, '1', 'YAML 1.1 detected'); @events = (); $receiver = sub { my ($p, $name, $event) = @_; if ($event->{name} eq 'scalar_event') { push @events, $event; } }; my $parser_1_2 = YAML::PP::Parser->new( receiver => $receiver, ); $parser_1_1 = YAML::PP::Parser->new( receiver => $receiver, default_yaml_version => '1.1', ); $yaml = <<'EOM'; %TAG !a! !long- --- - !a!foo value --- - !a!bar value EOM eval { $parser_1_2->parse_string($yaml); }; my $err = $@; like($err, qr{undefined tag handle}, 'No global tags in YAML 1.2'); @events = (); $parser_1_1->parse_string($yaml); is($events[0]->{tag}, '!long-foo', 'First tag ok'); is($events[1]->{tag}, '!long-bar', 'Second tag ok'); }; subtest 'version-schema' => sub { my $yaml = <<'EOM'; what: [ yes, true ] ... %YAML 1.1 --- bool: yes ... %YAML 1.2 --- bool: true string: yes EOM my $out_12_11 = <<'EOM'; %YAML 1.2 --- what: - yes - 1 ... %YAML 1.2 --- bool: 1 ... %YAML 1.2 --- bool: 1 string: yes EOM my $out_11_12 = <<'EOM'; %YAML 1.1 --- what: - 1 - 1 ... %YAML 1.1 --- bool: 1 ... %YAML 1.1 --- bool: 1 string: 'yes' EOM my $out_12 = <<'EOM'; %YAML 1.2 --- what: - yes - 1 ... %YAML 1.2 --- bool: yes ... %YAML 1.2 --- bool: 1 string: yes EOM my $out_11 = <<'EOM'; %YAML 1.1 --- what: - 1 - 1 ... %YAML 1.1 --- bool: 1 ... %YAML 1.1 --- bool: 1 string: 1 EOM my %args= ( schema => [qw/ + /], boolean => '', version_directive => 1, ); my $yp = YAML::PP->new( %args, yaml_version => ['1.2', '1.1'], ); my @docs = $yp->load_string($yaml); is($docs[0]->{what}->[0], 'yes', '[1.2,1.1] Doc 1 default string'); is($docs[0]->{what}->[1], 1, '[1.2,1.1] Doc 1 YAML 1.2 bool'); is($docs[1]->{bool}, 1, '[1.2,1.1] Doc 2 YAML 1.1 bool'); is($docs[2]->{bool}, 1, '[1.2,1.1] Doc 2 YAML 1.2 bool'); is($docs[2]->{string}, 'yes', '[1.2,1.1] Doc 3 YAML 1.2 string'); my $out = $yp->dump_string(@docs); is($out, $out_12_11, '[1.2,1.1] Dump ok'); $yp = YAML::PP->new( %args, yaml_version => ['1.1', '1.2'], ); @docs = $yp->load_string($yaml); is($docs[0]->{what}->[0], 1, '[1.1,1.2] Doc 1 default bool'); is($docs[0]->{what}->[1], 1, '[1.1,1.2] Doc 1 YAML 1.1 bool'); is($docs[1]->{bool}, 1, '[1.1,1.2] Doc 2 YAML 1.1 bool'); is($docs[2]->{bool}, 1, '[1.1,1.2] Doc 2 YAML 1.2 bool'); is($docs[2]->{string}, 'yes', '[1.1,1.2] Doc 3 YAML 1.2 string'); $out = $yp->dump_string(@docs); is($out, $out_11_12, '[1.1,1.2] Dump ok'); $yp = YAML::PP->new( %args, yaml_version => ['1.2'], ); @docs = $yp->load_string($yaml); is($docs[0]->{what}->[0], 'yes', '[1.2] Doc 1 default string'); is($docs[0]->{what}->[1], 1, '[1.2] Doc 1 YAML 1.1 bool'); is($docs[1]->{bool}, 'yes', '[1.2] Doc 2 YAML 1.1 string'); is($docs[2]->{bool}, 1, '[1.2] Doc 2 YAML 1.2 bool'); is($docs[2]->{string}, 'yes', '[1.2] Doc 3 YAML 1.2 string'); $out = $yp->dump_string(@docs); is($out, $out_12, '[1.2] Dump ok'); $yp = YAML::PP->new( %args, yaml_version => ['1.1'], ); @docs = $yp->load_string($yaml); is($docs[0]->{what}->[0], 1, '[1.1] Doc 1 default bool'); is($docs[0]->{what}->[1], 1, '[1.1] Doc 1 YAML 1.1 bool'); is($docs[1]->{bool}, 1, '[1.1] Doc 2 YAML 1.1 bool'); is($docs[2]->{bool}, 1, '[1.1] Doc 2 YAML 1.2 bool'); is($docs[2]->{string}, 1, '[1.1] Doc 3 YAML 1.2 bool'); $out = $yp->dump_string(@docs); is($out, $out_11, '[1.1] Dump ok'); }; subtest 'yaml-and-tag' => sub { my $yaml = <<'EOM'; %YAML 1.2 %TAG !x! tag:foo- --- - !x!x EOM my @events; my $receiver = sub { my ($p, $name, $event) = @_; if ($event->{name} eq 'scalar_event') { push @events, $event; } }; my $parser = YAML::PP::Parser->new( receiver => $receiver, ); $parser->parse_string($yaml); is($events[0]->{tag}, 'tag:foo-x', '%YAML and %TAG directive'); }; done_testing; 07070100000079000081A40000000000000000000000016616D6BA00002576000000000000000000000000000000000000003500000000perl-YAML-PP-3.14.1712772794.39ac610/t/52.preserve.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use YAML::PP; use YAML::PP::Common qw/ PRESERVE_ORDER PRESERVE_SCALAR_STYLE PRESERVE_FLOW_STYLE PRESERVE_ALIAS YAML_LITERAL_SCALAR_STYLE YAML_FLOW_MAPPING_STYLE YAML_FLOW_SEQUENCE_STYLE /; subtest 'preserve-scalar-style' => sub { my $yp = YAML::PP->new( preserve => PRESERVE_ORDER | PRESERVE_SCALAR_STYLE ); my $yaml = <<'EOM'; --- p: plain 's': 'single' "d": "double" f: >- folded ? |- l : |- literal nl: |+ ... --- - 0 - null - 23 - "42" - !!int '99' EOM my $exp_styles = <<'EOM'; --- p: plain 's': 'single' "d": "double" f: >- folded ? |- l : |- literal nl: |+ ... EOM my $exp_data = <<'EOM'; --- - 0 - null - 23 - "42" - 99 EOM my @docs = $yp->load_string($yaml); my $styles = $docs[0]; my $data = $docs[1]; my $dump_styles = $yp->dump_string($styles); is($dump_styles, $exp_styles, 'preserve=1 dump styless ok'); my $newline = delete $styles->{nl}; my $string = join ' ', values %$styles; is($string, 'plain single double folded literal', 'Strings'); my $dump_data = $yp->dump_string($data); is($dump_data, $exp_data, 'preserve=1 dump data ok'); $styles->{s} .= ' APPEND'; is($styles->{s}, 'single APPEND', 'append works'); is($yp->dump_string($styles->{s}), "--- single APPEND\n", 'Style gets lost on append'); $newline->{value} = "\n\n"; is($yp->dump_string($newline),qq{--- |+\n\n\n...\n}, 'Style is preserved for direct assignment'); $newline->{value} = "\0"; is($yp->dump_string($newline),qq{--- "\\0"\n}, 'Style gets changed if necessary'); }; subtest 'preserve-order' => sub { my $yp = YAML::PP->new( preserve => PRESERVE_ORDER ); my $yaml = <<'EOM'; --- z: 1 a: 2 y: 3 b: 4 x: 5 c: 6 EOM my $data = $yp->load_string($yaml); my $dump = $yp->dump_string($data); is($dump, $yaml, 'preserve=1 Key order preserved'); my @keys = keys %$data; is("@keys", "z a y b x c", 'keys()'); is($data->{a}, 2, 'hash a'); my $first = each %$data; is($first, 'z', 'First key'); my $next = each %$data; is($next, 'a', 'Next key'); is(delete $data->{z}, 1, 'delete(z)'); @keys = keys %$data; is("@keys", "a y b x c", 'keys()'); $data->{z} = 99; @keys = keys %$data; is("@keys", "a y b x c z", 'keys()'); my $scalar = scalar %$data; if ($] >= 5.026) { is(scalar %$data, 6, 'scalar'); } my @values = values %$data; is("@values", "2 3 4 5 6 99", 'values()'); is(exists $data->{a}, 1, 'exists(a)'); is(exists $data->{A}, '', 'exists(A)'); %$data = (); is(scalar keys %$data, 0, 'clear'); is(scalar %$data, 0, 'clear'); }; subtest 'object-order' => sub { my $yp = YAML::PP->new( schema => [qw/ + Perl /], preserve => PRESERVE_ORDER, ); my $yaml = <<'EOM'; --- - !perl/hash:Foo z: 1 a: 2 y: 3 b: 4 x: 5 c: 6 EOM my $data = $yp->load_string($yaml); my $dump = $yp->dump_string($data); is($dump, $yaml, 'load-dump object with preserved hash key order'); }; subtest 'preserve-flow' => sub { my $yp = YAML::PP->new( preserve => PRESERVE_FLOW_STYLE, ); my $yaml = <<'EOM'; --- map: {z: 1, a: 2, y: 3, b: 4} seq: [c, b, {y: z}] EOM my $exp_sorted = <<'EOM'; --- map: {a: 2, b: 4, y: 3, z: 1} seq: [c, b, {y: z}] EOM my $data = $yp->load_string($yaml); my $dump = $yp->dump_string($data); is($dump, $exp_sorted, 'load-dump with preserve flow'); is(exists($data->{seq}->[0]), 1, 'load sequence'); is(exists($data->{seq}->[3]), !1, 'load sequence'); $yp = YAML::PP->new( preserve => PRESERVE_FLOW_STYLE | PRESERVE_ORDER ); $data = $yp->load_string($yaml); $dump = $yp->dump_string($data); is($dump, $yaml, 'load-dump with preserve flow && order'); $yp = YAML::PP->new( schema => [qw/ + Perl /], preserve => PRESERVE_FLOW_STYLE | PRESERVE_ORDER, ); $yaml = <<'EOM'; --- !perl/hash:Foo map: {z: 1, a: 2, y: 3, b: 4} seq: [c, b, {y: z}] EOM $data = $yp->load_string($yaml); $dump = $yp->dump_string($data); is($dump, $yaml, 'load-dump object with preserved flow && order'); }; subtest 'create-preserve' => sub { my $yp = YAML::PP->new( preserve => 1, ); my $scalar = $yp->preserved_scalar("\n", style => YAML_LITERAL_SCALAR_STYLE ); my $data = { literal => $scalar }; my $dump = $yp->dump_string($data); my $yaml = <<'EOM'; --- literal: |+ ... EOM is($dump, $yaml, 'dump with preserved scalar'); my $hash = $yp->preserved_mapping({}, style => YAML_FLOW_MAPPING_STYLE); %$hash = (z => 1, a => 2, y => 3, b => 4); my $array = $yp->preserved_sequence([23, 24], style => YAML_FLOW_SEQUENCE_STYLE); $data = $yp->preserved_mapping({}); %$data = ( map => $hash, seq => $array ); $dump = $yp->dump_string($data); $yaml = <<'EOM'; --- map: {z: 1, a: 2, y: 3, b: 4} seq: [23, 24] EOM is($dump, $yaml, 'dump with preserved flow && order'); my $alias1 = $yp->preserved_mapping({ a => 1 }, alias => 'MAP', style => YAML_FLOW_MAPPING_STYLE); my $alias2 = $yp->preserved_sequence([qw/ x y z /], alias => 'SEQ', style => YAML_FLOW_SEQUENCE_STYLE); my $alias3 = $yp->preserved_scalar('string', alias => 'SCALAR'); $data = $yp->preserved_sequence([$alias1, $alias2, $alias3, $alias3, $alias2, $alias1]); $dump = $yp->dump_string($data); my $expected = <<'EOM'; --- - &MAP {a: 1} - &SEQ [x, y, z] - &SCALAR string - *SCALAR - *SEQ - *MAP EOM is $dump, $expected, 'dump with preserved map/seq/scalar and aliases'; }; subtest 'tie-array' => sub { my $x = YAML::PP->preserved_sequence([23, 24], style => YAML_FLOW_SEQUENCE_STYLE); @$x = (25, 26); is("@$x", '25 26', 'STORE'); unshift @$x, 24; is("@$x", '24 25 26', 'UNSHIFT'); shift @$x; is("@$x", '25 26', 'SHIFT'); splice @$x, 1, 1, 99, 100; is("@$x", '25 99 100', 'SPLICE'); delete $x->[1]; { no warnings 'uninitialized'; is("@$x", '25 100', 'DELETE'); } $x->[1] = 99; $#$x = 1; is("@$x", '25 99', 'STORESIZE'); }; subtest 'tie-scalar' => sub { my $scalar = YAML::PP->preserved_scalar("abc", style => YAML_LITERAL_SCALAR_STYLE ); like $scalar, qr{abc}, 'Regex'; ok($scalar eq 'abc', 'eq'); ok('abc' eq $scalar, 'eq'); ok($scalar gt 'abb', 'gt'); $scalar = YAML::PP->preserved_scalar(23, style => YAML_LITERAL_SCALAR_STYLE ); ok($scalar > 22, '>'); ok($scalar <= 23, '<='); }; subtest 'aliases' => sub { my $yaml = <<'EOM'; --- mapping: &mapping a: 1 b: 2 alias: *mapping seq: &seq - a - b same: *seq str: &scalar xyz copy: *scalar EOM my $sorted = <<'EOM'; --- alias: &mapping a: 1 b: 2 copy: &scalar xyz mapping: *mapping same: &seq - a - b seq: *seq str: *scalar EOM my $yp = YAML::PP->new( preserve => PRESERVE_ALIAS ); my $data = $yp->load_string($yaml); my $dump = $yp->dump_string($data); is($dump, $sorted, "Preserving alias names, but not order"); $yp = YAML::PP->new( preserve => PRESERVE_ORDER | PRESERVE_ALIAS ); $data = $yp->load_string($yaml); $dump = $yp->dump_string($data); is($dump, $yaml, "Preserving alias names and order"); $yp = YAML::PP->new( preserve => PRESERVE_ALIAS | PRESERVE_FLOW_STYLE ); $yaml = <<'EOM'; --- a: &seq [a] b: *seq c: &seq [c] d: *seq e: &map {e: 1} f: *map g: &map {g: 1} h: *map i: &scalar X j: *scalar k: &scalar Y l: *scalar EOM $data = $yp->load_string($yaml); $dump = $yp->dump_string($data); my $swap = $data->{a}; $data->{a} = $data->{d}; $data->{d} = $swap; $swap = $data->{e}; $data->{e} = $data->{h}; $data->{h} = $swap; $swap = $data->{i}; $data->{i} = $data->{l}; $data->{l} = $swap; $dump = $yp->dump_string($data); my $expected = <<'EOM'; --- a: &1 [c] b: &seq [a] c: *1 d: *seq e: &2 {g: 1} f: &map {e: 1} g: *2 h: *map i: &3 Y j: &scalar X k: *3 l: *scalar EOM is $dump, $expected, 'dump - Repeated anchors are removed'; my $reload = $yp->load_string($dump); is_deeply($reload, $data, 'Reloading after shuffling wiht repeated anchors'); }; subtest 'create-tied-automatically' => sub { my $yp = YAML::PP->new( preserve => PRESERVE_ORDER ); my $outer = $yp->preserved_mapping({}); %$outer = (z => 1, a => 2, y => 3, b => 4); my $array = $outer->{new} = []; my $inner = $outer->{new}->[0] = {}; $inner->{Z} = 1; $inner->{A} = 2; $inner->{Y} = 3; $inner->{B} = 4; push @$array, {}; my $inner2 = $outer->{new}->[1]; $inner2->{Z} = 11; $inner2->{A} = 22; $inner2->{Y} = 33; $inner2->{B} = 44; splice @$array, 0, 0, {}; my $inner3 = $outer->{new}->[0]; $inner3->{Z} = 111; $inner3->{A} = 222; $inner3->{Y} = 333; $inner3->{B} = 444; unshift @$array, {}; my $inner4 = $outer->{new}->[0]; $inner4->{Z} = 1111; $inner4->{A} = 2222; $inner4->{Y} = 3333; $inner4->{B} = 4444; $outer->{new}->[4] = { key => 4 }; $outer->{new}->[5] = [55]; $outer->{newer} = { key => 6 }; $outer->{newest} = [66]; my $dump = $yp->dump_string($outer); my $expected = <<'EOM'; --- z: 1 a: 2 y: 3 b: 4 new: - Z: 1111 A: 2222 Y: 3333 B: 4444 - Z: 111 A: 222 Y: 333 B: 444 - Z: 1 A: 2 Y: 3 B: 4 - Z: 11 A: 22 Y: 33 B: 44 - key: 4 - - 55 newer: key: 6 newest: - 66 EOM is $dump, $expected, 'dump - Newly created hashes keep order automatically'; }; done_testing; 0707010000007A000081A40000000000000000000000016616D6BA000006A6000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/53.customtag-alias.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use YAML::PP; subtest 'join-tag' => sub { my $yp = YAML::PP->new; $yp->schema->add_sequence_resolver( tag => '!join', on_create => sub { return '' }, on_data => sub { my ($constructor, $data, $list) = @_; my $join = shift @$list; $$data .= join $join, @$list; }, ); my $yaml = <<'EOM'; --- name: &name YAML string: &what !join [ ' ', *name, Ain't, Markup, Language ] alias: *what EOM my $string = "YAML Ain't Markup Language"; my $expected = { name => 'YAML', string => $string, alias => $string, }; my ($data) = $yp->load_string($yaml); is_deeply($data, $expected, 'Loaded data as expected'); }; subtest 'inherit-tag' => sub { my $yp = YAML::PP->new; $yp->schema->add_mapping_resolver( tag => '!inherit', # on_create => sub { return '' }, on_data => sub { my ($constructor, $data, $list) = @_; for my $item (@$list) { %$$data = (%$$data, %$item); } }, ); my $yaml = <<'EOM'; --- parent: &parent a: A b: B child: &child !inherit *parent : a: new A c: C twin: *child EOM my $string = "YAML Ain't Markup Language"; my $child = { a => 'new A', b => 'B', c => 'C', }; my $expected = { parent => { a => 'A', b => 'B', }, child => $child, twin => $child, }; my ($data) = $yp->load_string($yaml); is_deeply($data, $expected, 'Loaded data as expected'); }; done_testing; 0707010000007B000081A40000000000000000000000016616D6BA000014AE000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/t/54.glob.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use Data::Dumper; use IO::File; use YAML::PP; use YAML::PP::Schema::Perl; use Scalar::Util qw/ blessed reftype /; my $test_deep; BEGIN { eval "use Test::Deep qw/ cmp_deeply /"; unless ($@) { $test_deep = 1; } } unless ($test_deep) { plan skip_all => "No Test::Deep available"; exit; } our $var = "Hola"; our @var = (3, 14, 15); our %var = (pi => '3.1415'); my $stdin = \*DATA, my $fileno = fileno DATA; my $perl_objects = YAML::PP::Schema::Perl->new( ); my $perl_no_objects = YAML::PP::Schema::Perl->new( classes => [], ); my $yp = YAML::PP->new( schema => ['+', $perl_objects], ); my $yp_no_objects = YAML::PP->new( schema => ['+', $perl_no_objects], ); my %tests = ( simple => { in => <<'EOM', --- !perl/glob ARRAY: - 3 - 14 - 15 HASH: pi: '3.1415' NAME: var PACKAGE: main SCALAR: Hola EOM name => '*main::var', value => 'Hola', types => { SCALAR => 'Hola', ARRAY => [ 3, 14, 15 ], HASH => { pi => '3.1415' }, }, }, blessed => { in => <<'EOM', --- !perl/glob:Foo ARRAY: - 3 - 14 - 15 HASH: pi: '3.1415' NAME: var PACKAGE: main SCALAR: Hola EOM name => '*main::var', class => 'Foo', value => 'Hola', types => { SCALAR => 'Hola', ARRAY => [ 3, 14, 15 ], HASH => { pi => '3.1415' }, }, }, io => { in => <<"EOM", --- !perl/glob IO: fileno: $fileno stat: {} NAME: DATA PACKAGE: main EOM name => '*main::DATA', types => { IO => $fileno, }, }, blessed_io => { in => <<"EOM", --- !perl/glob:Foo IO: fileno: $fileno stat: {} NAME: DATA PACKAGE: main EOM name => '*main::DATA', class => 'Foo', types => { IO => $fileno, }, }, ); subtest valid => sub { my @tests = ( [objects => $yp], [no_objects => $yp_no_objects], ); for my $type (@tests) { my ($test_type, $yp) = @$type; for my $key (sort keys %tests) { my $test = $tests{ $key }; my $name = $test->{name}; my $label = "$test_type - $key - $name"; my $class = $test->{class} || ''; note "============ $key $name"; my $input = $test->{in}; my $data = $yp->load_string($input); my $glob = *{$data}; if ($class) { my $ref = ref $data; if ($test_type eq 'no_objects') { my $reftype = reftype(\$data); is($reftype, 'GLOB', "$label - ($class) reftype is glob"); isnt(ref $data, $class, "$label - Class not equals '$class'"); } else { my $reftype = reftype($data); is($reftype, 'GLOB', "$label - ($class) reftype is glob"); is(ref $data, $class, "$label - Class equals '$class'"); } } else { my $reftype = reftype(\$data); is($reftype, 'GLOB', "$label - reftype is glob"); } is("$glob", $name, "$label - Glob name"); my $types = $test->{types}; for my $type (sort keys %$types) { my $exp = $types->{ $type }; my $value; my $glob = *{$data}{ $type }; if ($type eq 'SCALAR') { $value = $$glob; } elsif ($type eq 'ARRAY') { $value = [ @$glob ]; } elsif ($type eq 'HASH') { $value = { %$glob }; } elsif ($type eq 'IO') { $value = fileno $glob; } cmp_deeply($value, $exp, "$label - $type - Data equal"); } my $dump = $yp->dump_string($data); if ($key =~ m/io/) { $dump =~ s/^ [a-z]+: \S+\n//mg; $dump =~ s/^ tell: \S+\n//m; $dump =~ s/stat:$/stat: \{\}/m; } if ($class and $test_type eq 'no_objects') { isnt($dump, $input, "$label - Dump not equals input"); } else { is($dump, $input, "$label - Dump equals input"); } } } }; subtest ioscalar => sub { my $fh = IO::File->new("< $Bin/54.glob.t"); my $dump = $yp->dump_string($fh); my $fn = $fh->fileno; like $dump, qr{--- !perl/glob:IO::File}, "IO::Scalar correctly dumped as blessed per/glob"; like $dump, qr{fileno: $fn\n}, "IO::Scalar fileno correct"; }; my @error = ( [ <<'EOM', qr{Unexpected keys in perl/glob}], --- !perl/glob NAME: var this: should not be here EOM [ <<'EOM', qr{Missing NAME in perl/glob}], --- !perl/glob name: invalid EOM ); subtest error => sub { for my $item (@error) { my ($input, $qr) = @$item; my $data = eval { $yp->load_string($input); }; my $err = $@; like $err, $qr, "Invalid glob - error matches $qr"; } }; done_testing; __DATA__ dummy 0707010000007C000081A40000000000000000000000016616D6BA000004B9000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/t/55.flow.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP::Parser; use YAML::PP::Emitter; use YAML::PP::Writer; use Encode; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; # skip tests that parser can't parse my @skip = qw/ 4FJ6 4ABK 87E4 8UDB 9MMW CN3R CT4Q FRK4 L9U5 LQZ7 LX3P QF4Y 6BFJ CFD4 Q9WF v022 /; push @skip, qw/ v014 v033 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, emit_yaml => 1, tag => 'flow', ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ SAME_EVENTS SAME_YAML DIFF_EVENTS DIFF_YAML ERROR TODO SKIP /], ids => [qw/ DIFF_YAML DIFF_EVENTS /], ); sub test { my ($testsuite, $testcase) = @_; my $id = $testcase->{id}; my $result = $testsuite->emit_yaml($testcase, { flow => 'keep' }); $testsuite->compare_emit_yaml($testcase, $result); } done_testing; exit; 0707010000007D000081A40000000000000000000000016616D6BA000004DD000000000000000000000000000000000000003700000000perl-YAML-PP-3.14.1712772794.39ac610/t/56.force-flow.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use FindBin '$Bin'; use lib "$Bin/lib"; use YAML::PP::Test; use Data::Dumper; use YAML::PP::Parser; use YAML::PP::Emitter; use YAML::PP::Writer; use Encode; $ENV{YAML_PP_RESERVED_DIRECTIVE} = 'ignore'; $|++; my $yts = "$Bin/../test-suite/yaml-test-suite-data"; # skip tests that parser can't parse my @skip = qw/ 4FJ6 4ABK 87E4 8UDB 9MMW CN3R CT4Q FRK4 L9U5 LQZ7 LX3P QF4Y Q9WF 6BFJ CFD4 M2N8:01 UKK6:01 /; push @skip, qw/ 6VJK MJS9 7T8X JHB9 LE5A v014 v020 /; my $testsuite = YAML::PP::Test->new( test_suite_dir => "$yts", dir => "$Bin/valid", valid => 1, in_yaml => 1, emit_yaml => 1, ); my ($testcases) = $testsuite->read_tests( skip => \@skip, ); $testsuite->run_testcases( code => \&test, ); $testsuite->print_stats( count => [qw/ SAME_EVENTS SAME_YAML DIFF_EVENTS DIFF_YAML ERROR TODO SKIP /], ids => [qw/ DIFF_YAML DIFF_EVENTS /], ); sub test { my ($testsuite, $testcase) = @_; my $id = $testcase->{id}; my $result = $testsuite->emit_yaml($testcase, { flow => 'yes' }); $testsuite->compare_emit_yaml($testcase, $result); } done_testing; exit; 0707010000007E000081A40000000000000000000000016616D6BA000002AF000000000000000000000000000000000000003500000000perl-YAML-PP-3.14.1712772794.39ac610/t/57.dup-keys.t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Data::Dumper; use YAML::PP; my $allow = YAML::PP->new( duplicate_keys => 1, ); my $forbid = YAML::PP->new( duplicate_keys => 0, ); my $default = YAML::PP->new; my $yaml = <<'EOM'; a: 1 b: 2 a: 3 EOM my $data = $allow->load_string($yaml); my $expected = { a => 3, b => 2, }; is_deeply($data, $expected, "Allowed duplicate keys"); $data = eval { $forbid->load_string($yaml) }; my $err = $@; like $err, qr{Duplicate key 'a'}, "Forbidden duplicate keys"; $data = eval { $default->load_string($yaml) }; $err = $@; like $err, qr{Duplicate key 'a'}, "Forbidden duplicate keys by default"; done_testing; 0707010000007F000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/data07070100000080000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include07070100000081000081A40000000000000000000000016616D6BA00000026000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/circular1.yaml--- included: !include circular2.yaml 07070100000082000081A40000000000000000000000016616D6BA00000026000000000000000000000000000000000000004300000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/circular2.yaml--- included: !include circular1.yaml 07070100000083000081A40000000000000000000000016616D6BA0000003E000000000000000000000000000000000000004100000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/include.yaml--- - !include include1.yaml - !include include2.yaml - item3 07070100000084000081A40000000000000000000000016616D6BA0000000D000000000000000000000000000000000000004200000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/include1.yaml--- include1 07070100000085000081A40000000000000000000000016616D6BA00000028000000000000000000000000000000000000004200000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/include2.yaml--- - include2 - !include include3.yaml 07070100000086000081A40000000000000000000000016616D6BA0000000D000000000000000000000000000000000000004200000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/include/include3.yaml--- include3 07070100000087000081A40000000000000000000000016616D6BA00000012000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/data/simple.yaml--- a: 1 --- b: 2 07070100000088000041ED0000000000000000000000096616D6BA00000000000000000000000000000000000000000000002F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid07070100000089000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i0320707010000008A000081A40000000000000000000000016616D6BA00000023000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i032/===Invalid characters in Verbatim Tag 0707010000008B000081A40000000000000000000000016616D6BA00000022000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i032/in.yaml!<tag:yaml.org,2002:str> > scalar 0707010000008C000081A40000000000000000000000016616D6BA0000000A000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i032/test.event+STR +DOC 0707010000008D000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i0330707010000008E000081A40000000000000000000000016616D6BA0000002B000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i033/===Repeated question mark in flow mapping key 0707010000008F000081A40000000000000000000000016616D6BA0000001B000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i033/in.yaml--- { ? ? question: mark } 07070100000090000081A40000000000000000000000016616D6BA00000016000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i033/test.event+STR +DOC --- +MAP {} 07070100000091000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i03407070100000092000081A40000000000000000000000016616D6BA00000041000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i034/===Invalid block mapping key on same line as previous flow sequence 07070100000093000081A40000000000000000000000016616D6BA00000016000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i034/in.yaml--- x: [ y ]in: valid 07070100000094000081A40000000000000000000000016616D6BA00000030000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i034/test.event+STR +DOC --- +MAP =VAL :x +SEQ [] =VAL :y -SEQ 07070100000095000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i03507070100000096000081A40000000000000000000000016616D6BA00000020000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i035/===Literal modifers greater than 9 07070100000097000081A40000000000000000000000016616D6BA00000008000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i035/in.yaml--- |10 07070100000098000081A40000000000000000000000016616D6BA0000000E000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i035/test.event+STR +DOC --- 07070100000099000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i0360707010000009A000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i036/===Tabs in various contexts 0707010000009B000081A40000000000000000000000016616D6BA00000010000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i036/in.yamlfoo: | bar: 1 0707010000009C000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i036/test.event+STR +DOC +MAP =VAL :foo 0707010000009D000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i0370707010000009E000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i037/===Tabs in various contexts 0707010000009F000081A40000000000000000000000016616D6BA00000004000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i037/in.yaml- - 070701000000A0000081A40000000000000000000000016616D6BA0000000A000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i037/test.event+STR +DOC 070701000000A1000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003400000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i038070701000000A2000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003800000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i038/===Tabs in various contexts 070701000000A3000081A40000000000000000000000016616D6BA00000005000000000000000000000000000000000000003C00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i038/in.yaml- - 070701000000A4000081A40000000000000000000000016616D6BA0000000A000000000000000000000000000000000000003F00000000perl-YAML-PP-3.14.1712772794.39ac610/t/invalid/i038/test.event+STR +DOC 070701000000A5000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000002B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/lib070701000000A6000081A40000000000000000000000016616D6BA0000031F000000000000000000000000000000000000003700000000perl-YAML-PP-3.14.1712772794.39ac610/t/lib/MySchema.pmpackage MySchema; use base 'YAML::PP::Schema'; use strict; use warnings; sub new { my ($class, %args) = @_; my $self = bless {}, $class; return $self; } sub register { my ($self, %args) = @_; my $schema = $args{schema}; $schema->add_mapping_resolver( tag => '!Class1', on_create => sub { return bless { id => 23 }, 'Class1' }, on_data => sub { my ($constructor, $data, $list) = @_; %$$data = (%$$data, @$list); }, ); $schema->add_representer( class_equals => 'Class1', code => sub { my ($representer, $node) = @_; # $node->{value} contains the object $node->{tag} = '!Class1'; $node->{data} = $node->{value}; return 1; }, ); } 1; 070701000000A7000041ED0000000000000000000000036616D6BA00000000000000000000000000000000000000000000003000000000perl-YAML-PP-3.14.1712772794.39ac610/t/lib/YAML070701000000A8000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003300000000perl-YAML-PP-3.14.1712772794.39ac610/t/lib/YAML/PP070701000000A9000081A40000000000000000000000016616D6BA000059A1000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/lib/YAML/PP/Test.pmpackage YAML::PP::Test; use strict; use warnings; use File::Basename qw/ dirname basename /; use Encode; use Test::More; use YAML::PP::Common qw/ YAML_FLOW_SEQUENCE_STYLE YAML_FLOW_MAPPING_STYLE YAML_PLAIN_SCALAR_STYLE /; sub new { my ($class, %args) = @_; my $self = bless { stats => {}, %args, }, $class; my $id2tags = $self->get_tags; $self->{id2tags} = $id2tags; return $self; } sub get_tags { my ($self, %args) = @_; my %id_tags; my $dir = $self->{test_suite_dir} . "/tags"; return unless -d $dir; opendir my $dh, $dir or die $!; my @tags = grep { not m/^\./ } readdir $dh; for my $tag (sort @tags) { opendir my $dh, "$dir/$tag" or die $!; my @ids = grep { -l "$dir/$tag/$_" } readdir $dh; $id_tags{ $_ }->{ $tag } = 1 for @ids; closedir $dh; } closedir $dh; return \%id_tags; } sub get_tests { my ($self) = @_; my $test_suite_dir = $self->{test_suite_dir}; my $dir = $self->{dir}; my $tag = $self->{tag}; my $id2tags = $self->{id2tags}; my $valid = $self->{valid}; my $json = $self->{in_json}; my @dirs; if (-d $test_suite_dir) { opendir my $dh, $test_suite_dir or die $!; my @ids = grep { m/^[A-Z0-9]{4}\z/ } readdir $dh; closedir $dh; my @allids; for my $id (@ids) { if (-f "$test_suite_dir/$id/===") { push @allids, $id; next; } opendir my $dh, "$test_suite_dir/$id" or die $!; my @subids = map { "$id/$_" } grep { m/^[0-9]+\z/ } readdir $dh; closedir $dh; push @allids, @subids; } @allids = grep { $valid ? not -f "$test_suite_dir/$_/error" : -f "$test_suite_dir/$_/error" } @allids; if ($json) { @allids = grep { -f "$test_suite_dir/$_/in.json" } @allids; } if ($tag) { @allids = grep { $id2tags->{ $_ }->{ $tag }; } @allids; } push @dirs, map { "$test_suite_dir/$_" } @allids; } else { Test::More::diag("\n############################"); Test::More::diag("No yaml-test-suite directory"); Test::More::diag("Using only local tests"); Test::More::diag("Checkout with: git worktree add test-suite test-suite"); Test::More::diag("############################"); } @dirs = sort @dirs; opendir my $dh, $dir or die $!; push @dirs, map { "$dir/$_" } grep { m/^[iv][A-Z0-9]{3}\z/ and (not $json or -f "$dir/$_/in.json") } readdir $dh; closedir $dh; return @dirs; } sub read_tests { my ($self, %args) = @_; my $test_suite_dir = $self->{test_suite_dir}; my $dir = $self->{dir}; my $skip = $args{skip}; my @dirs; my @todo; if ($ENV{TEST_ALL}) { @todo = @$skip; @$skip = (); } if (my $dir = $ENV{YAML_TEST_DIR}) { @dirs = ($dir); @todo = (); @$skip = (); } else { @dirs = $self->get_tests(); } my $skipped; @$skipped{ @$skip } = (1) x @$skip; my %todo; @todo{ @todo } = (); my @testcases; for my $dir (sort @dirs) { my $id = basename $dir; if ($id =~ m/^\d+$/) { $id = (basename dirname $dir) . ':' . $id; } open my $fh, '<', "$dir/===" or die $!; chomp(my $title = <$fh>); close $fh; my @test_events; if ($self->{events}) { open my $fh, '<', "$dir/test.event" or die $!; chomp(@test_events = <$fh>); close $fh; } my $in_yaml; if ($self->{in_yaml}) { open my $fh, "<:encoding(UTF-8)", "$dir/in.yaml" or die $!; $in_yaml = do { local $/; <$fh> }; close $fh; } my $linecount = 0; if ($self->{linecount} and length $in_yaml) { $linecount = () = $in_yaml =~ m/^/mg; } my $out_yaml; if ($self->{out_yaml}) { if (-f "$dir/out.yaml") { open my $fh, "<:encoding(UTF-8)", "$dir/out.yaml" or die $!; $out_yaml = do { local $/; <$fh> }; close $fh; } else { open my $fh, "<:encoding(UTF-8)", "$dir/in.yaml" or die $!; $out_yaml = do { local $/; <$fh> }; close $fh; } } my $emit_yaml; if ($self->{emit_yaml}) { my $file = "$dir/emit.yaml"; unless (-f $file) { $file = "$dir/out.yaml"; } unless (-f $file) { $file = "$dir/in.yaml"; } open my $fh, "<:encoding(UTF-8)", $file or die $!; $emit_yaml = do { local $/; <$fh> }; close $fh; } my $in_json; if ($self->{in_json}) { open my $fh, "<:encoding(UTF-8)", "$dir/in.json" or die $!; $in_json = do { local $/; <$fh> }; close $fh; } my $todo = exists $todo{ $id }; my $skip = delete $skipped->{ $id }; my $test = { id => $id, dir => dirname($dir), title => $title, test_events => \@test_events, in_yaml => $in_yaml, out_yaml => $out_yaml, emit_yaml => $emit_yaml, in_json => $in_json, linecount => $linecount, todo => $todo, skip => $skip, }; push @testcases, $test; } if (keys %$skipped) { # are there any leftover skips? warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$skipped], ['skipped']); } $self->{testcases} = \@testcases; return (\@testcases); } sub run_testcases { my ($self, %args) = @_; my $testcases = $self->{testcases}; my $code = $args{code}; my $stats = $self->{stats}; unless (@$testcases) { ok(1); return; } for my $testcase (@$testcases) { my $id = $testcase->{id}; my $todo = $testcase->{todo}; # diag "------------------------------ $id"; my $result; if ($testcase->{skip}) { SKIP: { push @{ $stats->{SKIP} }, $id; skip "SKIP $id", 1; $result = $code->($self, $testcase); } } elsif ($todo) { TODO: { local $TODO = $todo; $result = $code->($self, $testcase); } } else { $result = $code->($self, $testcase); } } } sub print_stats { my ($self, %args) = @_; my $count_fields = $args{count}; my $list_fields = $args{ids}; my $stats = $self->{stats}; my $counts = ''; for my $field (@$count_fields) { my $count = scalar @{ $stats->{ $field } || [] }; $counts .= "$field: $count "; } $counts .= "\n"; diag $counts; for my $field (@$list_fields) { my $ids = $stats->{ $field } || []; diag "$field: (@$ids)" if @$ids; } } sub parse_events { my ($class, $testcase) = @_; my @events; my $parser = YAML::PP::Parser->new( receiver => sub { my ($self, $event, $info) = @_; push @events, YAML::PP::Common::event_to_test_suite($info, { flow => 1 }); }, ); eval { $parser->parse_string($testcase->{in_yaml}); }; my $err = $@; my $line = $parser->lexer->line; return { events => \@events, err => $err, parser => $parser, line => $line, }; } sub compare_parse_events { my ($self, $testcase, $result) = @_; my $stats = $self->{stats}; my $id = $testcase->{id}; my $title = $testcase->{title}; my $err = $result->{err}; my $yaml = $testcase->{in_yaml}; my $test_events = $testcase->{test_events}; my $exp_lines = $testcase->{linecount}; my @events = @{ $result->{events} }; $_ = encode_utf8 $_ for @events; my $ok = 0; if ($err) { push @{ $stats->{ERROR} }, $id; ok(0, "$id - $title (ERROR)"); } else { $ok = is_deeply(\@events, $test_events, "$id - $title"); } if ($ok) { push @{ $stats->{OK} }, $id; if (defined $exp_lines) { my $lines = $result->{line}; cmp_ok($lines, '==', $exp_lines, "$id - Line count $lines == $exp_lines"); } } else { push @{ $stats->{DIFF} }, $id unless $err; if ($testcase->{todo}) { push @{ $stats->{TODO} }, $id; } if (not $testcase->{todo} or $ENV{YAML_PP_TRACE}) { diag "YAML:\n$yaml" unless $testcase->{todo}; diag "EVENTS:\n" . join '', map { "$_\n" } @$test_events; diag "GOT EVENTS:\n" . join '', map { "$_\n" } @events; } } } sub parse_tokens { my ($class, $testcase) = @_; my $parser = YAML::PP::Parser->new( receiver => sub { my ($self, @args) = @_; }, ); eval { $parser->parse_string($testcase->{in_yaml}); }; my $err = $@; my $tokens = $parser->tokens; return { err => $err, tokens => $tokens, }; } sub compare_tokens { my ($self, $testcase, $result) = @_; my $id = $testcase->{id}; my $title = $testcase->{title}; my $yaml = $testcase->{in_yaml}; my $all_tokens = $result->{tokens}; my @yaml_lines = split /(?<=\n)/, $yaml; my $error; my $ok = 1; LINE: for my $i (0 .. $#yaml_lines) { my $line_number = $i + 1; # diag("============== Line $line_number"); my $line = $yaml_lines[ $i ]; my @tokens; TOKEN: while (@$all_tokens) { my $next = $all_tokens->[0]; if (my $sub = $next->{subtokens}) { shift @$all_tokens; unshift @$all_tokens, @$sub; next TOKEN; } if ($next->{line} < $line_number) { $error = { token => $next, msg => "Wrong line", }; $ok = 0; last LINE; } last if $next->{line} > $line_number; $next = shift @$all_tokens; push @tokens, $next; } my $column = 0; while (@tokens) { my $token = shift @tokens; my $token_column = $token->{column}; my $value = $token->{value}; if ($token->{orig}) { $value = $token->{orig}; } unless ($token->{column} == $column) { $ok = 0; $error = { token => $token, msg => "Wrong column", }; last LINE; } unless ($line =~ s/^\Q$value//) { $ok = 0; $error = { token => $token, msg => "Token does not match YAML", }; last LINE; } $column += length($value); } if (length $line) { $ok = 0; $error = { msg => "Line is longer than tokens", }; } } if (@$all_tokens) { $ok = 0; $error = { msg => "More tokens than YAML lines", }; } unless ($ok) { warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([$error], ['error']); diag($yaml); } ok($ok, "$id - Tokens match YAML"); } sub compare_invalid_parse_events { my ($self, $testcase, $result) = @_; my $stats = $self->{stats}; my $id = $testcase->{id}; my $title = $testcase->{title}; my $err = $result->{err}; my $yaml = $testcase->{in_yaml}; my $test_events = $testcase->{test_events}; my $ok = 0; if (not $err) { push @{ $stats->{OK} }, $id; ok(0, "$id - $title - should be invalid"); } else { push @{ $stats->{ERROR} }, $id; if (not $result->{events}) { $ok = ok(1, "$id - $title"); } else { $ok = is_deeply($result->{events}, $test_events, "$id - $title"); } } if ($ok) { } else { push @{ $stats->{DIFF} }, $id; if ($testcase->{todo}) { push @{ $stats->{TODO} }, $id; } if (not $testcase->{todo} or $ENV{YAML_PP_TRACE}) { diag "YAML:\n$yaml" unless $testcase->{todo}; diag "EVENTS:\n" . join '', map { "$_\n" } @$test_events; diag "GOT EVENTS:\n" . join '', map { "$_\n" } @{ $result->{events} }; } } } sub load_json { my ($self, $testcase) = @_; my $ypp = YAML::PP->new(boolean => 'JSON::PP', schema => [qw/ Core /]); my @docs = eval { $ypp->load_string($testcase->{in_yaml}) }; my $err = $@; return { data => \@docs, err => $err, }; } sub compare_load_json { my ($self, $testcase, $result) = @_; my $stats = $self->{stats}; my $id = $testcase->{id}; my $title = $testcase->{title}; my $err = $result->{err}; my $yaml = $testcase->{in_yaml}; my $exp_json = $testcase->{in_json}; my $docs = $result->{data}; # input can contain multiple JSON my @exp_json = split m/^(?=true|false|null|[0-9"\{\[])/m, $exp_json; $exp_json = ''; my $coder = JSON::PP->new->ascii->pretty->allow_nonref->canonical; for my $exp (@exp_json) { my $data = $coder->decode($exp); $exp = $coder->encode($data); $exp_json .= $exp; } my $json = ''; for my $doc (@$docs) { my $j = $coder->encode($doc); $json .= $j; } my $ok = 0; if ($err) { push @{ $stats->{ERROR} }, $id; ok(0, "$id - $title - ERROR"); } else { $ok = cmp_ok($json, 'eq', $exp_json, "$id - load -> JSON equals expected JSON"); if ($ok) { push @{ $stats->{OK} }, $id; } else { push @{ $stats->{DIFF} }, $id; } } unless ($ok) { if ($testcase->{todo}) { push @{ $stats->{TODO} }, $id; } if (not $testcase->{todo} or $ENV{YAML_PP_TRACE}) { diag "YAML:\n$yaml" unless $testcase->{todo}; diag "JSON:\n" . $exp_json; diag "GOT JSON:\n" . $json; } } } sub dump_yaml { my ($self, $testcase) = @_; my $id = $testcase->{id}; my $ypp = YAML::PP->new( boolean => 'JSON::PP', duplicate_keys => 1 ); my @docs = eval { $ypp->load_string($testcase->{in_yaml}) }; my $err = $@; my $result = {}; if ($err) { diag "ERROR loading $id"; $result->{err} = $err; return $result; } my $out_yaml; eval { $out_yaml = $ypp->dump_string(@docs); }; $err = $@; if ($err) { diag "ERROR dumping $id"; $result->{err} = $err; return $result; } $result->{dump_yaml} = $out_yaml; my @reload = eval { $ypp->load_string($out_yaml) }; $err = $@; if ($err) { diag "ERROR reloading $id"; $result->{err} = $err; return $result; } $result->{data} = \@docs; $result->{data_reload} = \@reload; my $exp_out_yaml = $testcase->{out_yaml}; my @events; my @reparse_events; my $parser = YAML::PP::Parser->new( receiver => sub { my ($self, $event, $info) = @_; push @events, YAML::PP::Common::event_to_test_suite($info, { flow => 0 }); }, ); eval { $parser->parse_string($out_yaml); }; $err = $@; if ($err) { diag "ERROR parsing $id\n$err"; $result->{err} = $err; return $result; } @reparse_events = @events; @events = (); my @exp_events; eval { $parser->parse_string($testcase->{out_yaml}); }; $err = $@; @exp_events = @events; $result->{dump_events} = \@reparse_events; $result->{expected_events} = \@exp_events; return $result; } sub compare_dump_yaml { my ($self, $testcase, $result) = @_; my $stats = $self->{stats}; my $id = $testcase->{id}; my $title = $testcase->{title}; my $err = $result->{err}; my $yaml = $testcase->{in_yaml}; my $out_yaml = $testcase->{out_yaml}; my $docs = $result->{data}; my $reload_docs = $result->{data_reload}; my $dump_yaml = $result->{dump_yaml}; my $dump_events = $result->{dump_events}; my $exp_events = $result->{expected_events}; my $ok = 0; if ($err) { push @{ $stats->{ERROR} }, $id; ok(0, "$id - $title - ERROR"); } else { $ok = is_deeply($reload_docs, $docs, "$id - $title - Reload data equals original"); push @{ $stats->{DIFF} }, $id unless $ok; } if ($ok) { push @{ $stats->{OK} }, $id; } else { if ($testcase->{todo}) { push @{ $stats->{TODO} }, $id; } warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$docs], ['docs']); if (not $testcase->{todo} or $ENV{YAML_PP_TRACE}) { diag "YAML:\n$out_yaml" unless $testcase->{todo}; diag "OUT YAML:\n$out_yaml" unless $testcase->{todo}; my $reload_dump = Data::Dumper->Dump([$reload_docs], ['reload_docs']); diag "RELOAD DATA:\n$reload_dump" unless $testcase->{todo}; } } # TODO # my $same_events = is_deeply($dump_events, $exp_events, "$id - $title - Events from re-parsing are the same"); } sub emit_yaml { my ($self, $testcase, $args) = @_; my $flow = $args->{flow} ||= 'no'; my $indent = $args->{indent} ||= 2; my $id = $testcase->{id}; my $exp_yaml = $testcase->{emit_yaml}; my @events; my $parser = YAML::PP::Parser->new( receiver => sub { my ($self, @args) = @_; push @events, [@args]; }, ); eval { $parser->parse_string($testcase->{in_yaml}); }; my $err = $@; my $result = {}; if ($err) { diag "ERROR parsing $id\n$err"; $result->{err} = $err; return $result; } my $emit_yaml = $self->_emit_events(\@events, $args); my @reparse_events; my @expected_reparse_events; my @ev; my @emit_events; $parser = YAML::PP::Parser->new( receiver => sub { my ($self, @args) = @_; my ($type, $info) = @args; push @emit_events, $info; push @ev, YAML::PP::Common::event_to_test_suite($info, { flow => $flow eq 'keep' }); }, ); eval { $parser->parse_string($emit_yaml); }; $err = $@; if ($err) { diag "ERROR parsing $id\n$err"; diag $emit_yaml; $result->{err} = $err; return $result; } @reparse_events = @ev; if ($flow eq 'keep') { @expected_reparse_events = map { YAML::PP::Common::event_to_test_suite($_->[1], { flow => 1 }) } @events; } elsif ($flow eq 'no') { @ev = (); eval { $parser->parse_string($exp_yaml); }; @expected_reparse_events = @ev; } else { @expected_reparse_events = map { if ($_->[1]->{name} eq 'sequence_start_event') { $_->[1]->{style} = YAML_FLOW_SEQUENCE_STYLE; } elsif ($_->[1]->{name} eq 'mapping_start_event') { $_->[1]->{style} = YAML_FLOW_MAPPING_STYLE; } elsif ($_->[1]->{name} eq 'scalar_event') { $_->[1]->{style} = YAML_PLAIN_SCALAR_STYLE; } YAML::PP::Common::event_to_test_suite($_->[1], { flow => 1 }); } @events; @reparse_events = map { if ($_->{name} eq 'scalar_event') { $_->{style} = YAML_PLAIN_SCALAR_STYLE; } YAML::PP::Common::event_to_test_suite($_, { flow => 1 }); } @emit_events; } $result = { expected_events => \@expected_reparse_events, reparse_events => \@reparse_events, }; # note "========= EMIT:\n$emit_yaml"; $result->{emit_yaml} = $emit_yaml if $flow eq 'no'; return $result; } sub _emit_events { my ($testsuite, $events, $args) = @_; my $indent = $args->{indent} ||= 2; my $writer = YAML::PP::Writer->new; my $emitter = YAML::PP::Emitter->new( indent => $indent ); $emitter->set_writer($writer); $emitter->init; for my $event (@$events) { my ($type, $info) = @$event; delete $info->{version_directive}; if ($type eq 'sequence_start_event' or $type eq 'mapping_start_event') { if ($args->{flow} eq 'no') { delete $info->{style}; } elsif ($args->{flow} eq 'keep') { delete $info->{style} if $args->{flow} eq 'no'; } elsif ($args->{flow} eq 'yes') { if ($type eq 'sequence_start_event') { $info->{style} = YAML_FLOW_SEQUENCE_STYLE; } else { $info->{style} = YAML_FLOW_MAPPING_STYLE; } } } $emitter->$type($info); } my $yaml = $emitter->writer->output; return $yaml; } sub compare_emit_yaml { my ($self, $testcase, $result) = @_; my $stats = $self->{stats}; my $id = $testcase->{id}; my $title = $testcase->{title}; my $err = $result->{err}; my $yaml = $testcase->{in_yaml}; my $exp_emit_yaml = $testcase->{emit_yaml}; my $emit_yaml = $result->{emit_yaml}; my $exp_events = $result->{expected_events}; my $reparse_events = $result->{reparse_events}; if ($err) { push @{ $stats->{ERROR} }, $id; ok(0, "$id - $title - ERROR"); return; } $_ = encode_utf8 $_ for (@$reparse_events, @$exp_events); my $same_events = is_deeply($reparse_events, $exp_events, "$id - $title - Events from re-parsing are the same"); if ($same_events) { push @{ $stats->{SAME_EVENTS} }, $id; if (defined $emit_yaml) { $_ = encode_utf8 $_ for ($emit_yaml, $exp_emit_yaml); my $same_yaml = cmp_ok($emit_yaml, 'eq', $exp_emit_yaml, "$id - $title - Emit events"); if ($same_yaml) { push @{ $stats->{SAME_YAML} }, $id; } else { local $Data::Dumper::Useqq = 1; diag(' ' . Data::Dumper->Dump([$emit_yaml], ['emit_yaml'])); diag(Data::Dumper->Dump([$exp_emit_yaml], ['exp_emit_yaml'])); push @{ $stats->{DIFF_YAML} }, $id; } } } else { push @{ $stats->{DIFF_EVENTS} }, $id; } } 1; 070701000000AA000041ED0000000000000000000000146616D6BA00000000000000000000000000000000000000000000002D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid070701000000AB000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v009070701000000AC000081A40000000000000000000000016616D6BA0000002A000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v009/===Empty value at end of unindented sequence 070701000000AD000081A40000000000000000000000016616D6BA0000001A000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v009/in.yamla: - 1 - 2 - # empty b: 3 070701000000AE000081A40000000000000000000000016616D6BA00000012000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v009/out.yamla: - 1 - 2 - b: 3 070701000000AF000081A40000000000000000000000016616D6BA00000057000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v009/test.event+STR +DOC +MAP =VAL :a +SEQ =VAL :1 =VAL :2 =VAL : -SEQ =VAL :b =VAL :3 -MAP -DOC -STR 070701000000B0000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v014070701000000B1000081A40000000000000000000000016616D6BA0000001B000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v014/===Allowed Characters in Tags 070701000000B2000081A40000000000000000000000016616D6BA00000091000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v014/in.yaml%TAG !123ab-! tag:example.com,2000:app/ --- !123ab-!foo scalar ... %TAG !pre! !prefix-%2F[]*@ --- !pre!name scalar --- !foo%2f()*@a=b&c=d scalar 070701000000B3000081A40000000000000000000000016616D6BA000000A7000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v014/test.event+STR +DOC --- =VAL <tag:example.com,2000:app/foo> :scalar -DOC ... +DOC --- =VAL <!prefix-%2F[]*@name> :scalar -DOC +DOC --- =VAL <!foo/()*@a=b&c=d> :scalar -DOC -STR 070701000000B4000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v019070701000000B5000081A40000000000000000000000016616D6BA00000029000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v019/===Implicit Key Block Sequence on same line 070701000000B6000081A40000000000000000000000016616D6BA00000039000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v019/in.yaml--- mapping: ? > key : : value ? - a - b 070701000000B7000081A40000000000000000000000016616D6BA0000003D000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v019/out.yaml--- mapping: ? > key : : value ? - a - b : 070701000000B8000081A40000000000000000000000016616D6BA00000081000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v019/test.event+STR +DOC --- +MAP =VAL :mapping +MAP =VAL >key\n =VAL : =VAL : =VAL :value +SEQ =VAL :a =VAL :b -SEQ =VAL : -MAP -MAP -DOC -STR 070701000000B9000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v020070701000000BA000081A40000000000000000000000016616D6BA00000014000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v020/===Complex mapping key 070701000000BB000081A40000000000000000000000016616D6BA0000004A000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v020/in.yaml--- ? x: y : z a: b --- top1: ? a: 1 : b: [c] ? x : y top2: value 070701000000BC000081A40000000000000000000000016616D6BA00000049000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v020/out.yaml--- ? x: y : z a: b --- top1: ? a: 1 : b: - c x: y top2: value 070701000000BD000081A40000000000000000000000016616D6BA000000E9000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v020/test.event+STR +DOC --- +MAP +MAP =VAL :x =VAL :y -MAP =VAL :z =VAL :a =VAL :b -MAP -DOC +DOC --- +MAP =VAL :top1 +MAP +MAP =VAL :a =VAL :1 -MAP +MAP =VAL :b +SEQ [] =VAL :c -SEQ -MAP =VAL :x =VAL :y -MAP =VAL :top2 =VAL :value -MAP -DOC -STR 070701000000BE000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v021070701000000BF000081A40000000000000000000000016616D6BA00000022000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v021/===Block indicators in deeper levels 070701000000C0000081A40000000000000000000000016616D6BA00000027000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v021/in.yaml- one: |2 two three: | four 070701000000C1000081A40000000000000000000000016616D6BA00000027000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v021/out.yaml- one: |2 two three: | four 070701000000C2000081A40000000000000000000000016616D6BA00000058000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v021/test.event+STR +DOC +SEQ +MAP =VAL :one =VAL | two\n =VAL :three =VAL |four\n -MAP -SEQ -DOC -STR 070701000000C3000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022070701000000C4000081A40000000000000000000000016616D6BA0000001B000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022/===Empty flow sequence values 070701000000C5000081A40000000000000000000000016616D6BA000001A1000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022/in.json[ [ "", "second value" ], [ "" ], [ "" ], [ "" ], [ "" ], [ null, "second value" ], [ null ], [ null ], [ null ], [ null ], [ "" ], [ "" ], [ "" ], [ "" ], [ "" ], [ "" ], [ "" ], [ "" ] ] 070701000000C6000081A40000000000000000000000016616D6BA00000139000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022/in.yaml- [!!str,second value] - [!!str,] - [!!str ,] - [!!str] - [!!str ] - [&anchor1,second value] - [&anchor2,] - [&anchor3 ,] - [&anchor4] - [&anchor5 ] - [!!str &anchor6,] - [!!str &anchor7 ,] - [!!str &anchor8] - [!!str &anchor9 ] - [&anchor10 !!str,] - [&anchor11 !!str ,] - [&anchor12 !!str] - [&anchor13 !!str ] 070701000000C7000081A40000000000000000000000016616D6BA00000131000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022/out.yaml- - !!str - second value - - !!str - - !!str - - !!str - - !!str - - &anchor1 - second value - - &anchor2 - - &anchor3 - - &anchor4 - - &anchor5 - - &anchor6 !!str - - &anchor7 !!str - - &anchor8 !!str - - &anchor9 !!str - - &anchor10 !!str - - &anchor11 !!str - - &anchor12 !!str - - &anchor13 !!str 070701000000C8000081A40000000000000000000000016616D6BA0000035D000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v022/test.event+STR +DOC +SEQ +SEQ [] =VAL <tag:yaml.org,2002:str> : =VAL :second value -SEQ +SEQ [] =VAL <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor1 : =VAL :second value -SEQ +SEQ [] =VAL &anchor2 : -SEQ +SEQ [] =VAL &anchor3 : -SEQ +SEQ [] =VAL &anchor4 : -SEQ +SEQ [] =VAL &anchor5 : -SEQ +SEQ [] =VAL &anchor6 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor7 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor8 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor9 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor10 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor11 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor12 <tag:yaml.org,2002:str> : -SEQ +SEQ [] =VAL &anchor13 <tag:yaml.org,2002:str> : -SEQ -SEQ -DOC -STR 070701000000C9000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023070701000000CA000081A40000000000000000000000016616D6BA00000018000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023/===Comment lines with tabs 070701000000CB000081A40000000000000000000000016616D6BA00000026000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023/in.json[ [], [], [], [], [] ] 070701000000CC000081A40000000000000000000000016616D6BA00000050000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023/in.yaml- [ ] - [ ] - [ # comment ] - [ # comment ] - [ # comment ] 070701000000CD000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023/out.yaml- [] - [] - [] - [] - [] 070701000000CE000081A40000000000000000000000016616D6BA0000005F000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v023/test.event+STR +DOC +SEQ +SEQ [] -SEQ +SEQ [] -SEQ +SEQ [] -SEQ +SEQ [] -SEQ +SEQ [] -SEQ -SEQ -DOC -STR 070701000000CF000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024070701000000D0000081A40000000000000000000000016616D6BA0000001F000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024/===Empty flow mapping keys values 070701000000D1000081A40000000000000000000000016616D6BA0000021F000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024/in.json[ { "" : null, "second key" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null, "second key" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null }, { "" : null } ] 070701000000D2000081A40000000000000000000000016616D6BA00000135000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024/in.yaml- {!!str,second key} - {!!str,} - {!!str ,} - {!!str} - {!!str } - {&anchor1,second key} - {&anchor2,} - {&anchor3 ,} - {&anchor4} - {&anchor5 } - {!!str &anchor6,} - {!!str &anchor7 ,} - {!!str &anchor8} - {!!str &anchor9 } - {&anchor10 !!str,} - {&anchor11 !!str ,} - {&anchor12 !!str} - {&anchor13 !!str } 070701000000D3000081A40000000000000000000000016616D6BA0000012B000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024/out.yaml- !!str : second key: - !!str : - !!str : - !!str : - !!str : - &anchor1 : second key: - &anchor2 : - &anchor3 : - &anchor4 : - &anchor5 : - &anchor6 !!str : - &anchor7 !!str : - &anchor8 !!str : - &anchor9 !!str : - &anchor10 !!str : - &anchor11 !!str : - &anchor12 !!str : - &anchor13 !!str : 070701000000D4000081A40000000000000000000000016616D6BA000003E5000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v024/test.event+STR +DOC +SEQ +MAP {} =VAL <tag:yaml.org,2002:str> : =VAL : =VAL :second key =VAL : -MAP +MAP {} =VAL <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor1 : =VAL : =VAL :second key =VAL : -MAP +MAP {} =VAL &anchor2 : =VAL : -MAP +MAP {} =VAL &anchor3 : =VAL : -MAP +MAP {} =VAL &anchor4 : =VAL : -MAP +MAP {} =VAL &anchor5 : =VAL : -MAP +MAP {} =VAL &anchor6 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor7 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor8 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor9 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor10 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor11 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor12 <tag:yaml.org,2002:str> : =VAL : -MAP +MAP {} =VAL &anchor13 <tag:yaml.org,2002:str> : =VAL : -MAP -SEQ -DOC -STR 070701000000D5000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v025070701000000D6000081A40000000000000000000000016616D6BA00000030000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v025/===Explicit empty key/value pairs in flow mappings 070701000000D7000081A40000000000000000000000016616D6BA0000005F000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v025/in.yaml- {? } - { ? } - { ? } - { ? } - { ? ,} - { ? , } - { ? ,key: value} - { ? , key: value} 070701000000D8000081A40000000000000000000000016616D6BA0000003A000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v025/out.yaml- : - : - : - : - : - : - : key: value - : key: value 070701000000D9000081A40000000000000000000000016616D6BA00000122000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v025/test.event+STR +DOC +SEQ +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : -MAP +MAP {} =VAL : =VAL : =VAL :key =VAL :value -MAP +MAP {} =VAL : =VAL : =VAL :key =VAL :value -MAP -SEQ -DOC -STR 070701000000DA000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v026070701000000DB000081A40000000000000000000000016616D6BA00000016000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v026/===Tabs in double quotes 070701000000DC000081A40000000000000000000000016616D6BA00000035000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v026/in.yaml- "1 inline\ttab" - "2 inline\ tab" - "3 inline tab" 070701000000DD000081A40000000000000000000000016616D6BA00000036000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v026/out.yaml- "1 inline\ttab" - "2 inline\ttab" - "3 inline\ttab" 070701000000DE000081A40000000000000000000000016616D6BA0000005A000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v026/test.event+STR +DOC +SEQ =VAL "1 inline\ttab =VAL "2 inline\ttab =VAL "3 inline\ttab -SEQ -DOC -STR 070701000000DF000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v027070701000000E0000081A40000000000000000000000016616D6BA0000001F000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v027/===Trailing tabs in double quotes 070701000000E1000081A40000000000000000000000016616D6BA0000009A000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v027/in.yaml- "1 trailing\t tab" - "2 trailing\t tab" - "3 trailing\ tab" - "4 trailing\ tab" - "5 trailing tab" - "6 trailing tab" 070701000000E2000081A40000000000000000000000016616D6BA0000007A000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v027/out.yaml- "1 trailing\t tab" - "2 trailing\t tab" - "3 trailing\t tab" - "4 trailing\t tab" - "5 trailing tab" - "6 trailing tab" 070701000000E3000081A40000000000000000000000016616D6BA000000A4000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v027/test.event+STR +DOC +SEQ =VAL "1 trailing\t tab =VAL "2 trailing\t tab =VAL "3 trailing\t tab =VAL "4 trailing\t tab =VAL "5 trailing tab =VAL "6 trailing tab -SEQ -DOC -STR 070701000000E4000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v028070701000000E5000081A40000000000000000000000016616D6BA0000001E000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v028/===Leading tabs in double quotes 070701000000E6000081A40000000000000000000000016616D6BA00000094000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v028/in.yaml- "1 leading \ttab" - "2 leading \ tab" - "3 leading tab" - "4 leading \t tab" - "5 leading \ tab" - "6 leading tab" 070701000000E7000081A40000000000000000000000016616D6BA00000078000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v028/out.yaml- "1 leading \ttab" - "2 leading \ttab" - "3 leading tab" - "4 leading \t tab" - "5 leading \t tab" - "6 leading tab" 070701000000E8000081A40000000000000000000000016616D6BA000000A2000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v028/test.event+STR +DOC +SEQ =VAL "1 leading \ttab =VAL "2 leading \ttab =VAL "3 leading tab =VAL "4 leading \t tab =VAL "5 leading \t tab =VAL "6 leading tab -SEQ -DOC -STR 070701000000E9000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v029070701000000EA000081A40000000000000000000000016616D6BA00000013000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v029/===Directive variants 070701000000EB000081A40000000000000000000000016616D6BA00000015000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v029/in.yaml%YAML 1.1 #... --- a 070701000000EC000081A40000000000000000000000016616D6BA00000006000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v029/out.yaml--- a 070701000000ED000081A40000000000000000000000016616D6BA00000020000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v029/test.event+STR +DOC --- =VAL :a -DOC -STR 070701000000EE000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v030070701000000EF000081A40000000000000000000000016616D6BA00000013000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v030/===Directive variants 070701000000F0000081A40000000000000000000000016616D6BA00000011000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v030/in.yaml%YAMLL 1.1 --- a 070701000000F1000081A40000000000000000000000016616D6BA00000006000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v030/out.yaml--- a 070701000000F2000081A40000000000000000000000016616D6BA00000020000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v030/test.event+STR +DOC --- =VAL :a -DOC -STR 070701000000F3000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v031070701000000F4000081A40000000000000000000000016616D6BA00000013000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v031/===Directive variants 070701000000F5000081A40000000000000000000000016616D6BA0000003A000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v031/in.yaml%YAML 1.1 --- a ... %YAML 1.1 --- b ... %YAML 1.1 --- c 070701000000F6000081A40000000000000000000000016616D6BA0000001A000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v031/out.yaml--- a ... --- b ... --- c 070701000000F7000081A40000000000000000000000016616D6BA00000054000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v031/test.event+STR +DOC --- =VAL :a -DOC ... +DOC --- =VAL :b -DOC ... +DOC --- =VAL :c -DOC -STR 070701000000F8000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v032070701000000F9000081A40000000000000000000000016616D6BA00000019000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v032/===Tabs in various contexts 070701000000FA000081A40000000000000000000000016616D6BA00000005000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v032/in.yaml- -1 070701000000FB000081A40000000000000000000000016616D6BA00000005000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v032/out.yaml- -1 070701000000FC000081A40000000000000000000000016616D6BA00000027000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v032/test.event+STR +DOC +SEQ =VAL :-1 -SEQ -DOC -STR 070701000000FD000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v033070701000000FE000081A40000000000000000000000016616D6BA00000030000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v033/===Folded scalars with keeping trailing linebreaks 070701000000FF000081A40000000000000000000000016616D6BA0000003C000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v033/in.json[ "", "\n", "\n\n", "a\n", "a\n\n", "a\n\n\n" ] 07070100000100000081A40000000000000000000000016616D6BA00000035000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v033/in.yaml--- - >+ - >+ - >+ - >+ a - >+ a - >+ a ... 07070100000101000081A40000000000000000000000016616D6BA00000065000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v033/test.event+STR +DOC --- +SEQ =VAL > =VAL >\n =VAL >\n\n =VAL >a\n =VAL >a\n\n =VAL >a\n\n\n -SEQ -DOC ... -STR 07070100000102000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000003200000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v03407070100000103000081A40000000000000000000000016616D6BA00000031000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v034/===Alias as mapping key and block sequence as value 07070100000104000081A40000000000000000000000016616D6BA00000062000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v034/in.json{ "key": "value", "value": [ "key" ] } { "key": "value", "value": [ "key" ] } 07070100000105000081A40000000000000000000000016616D6BA0000004C000000000000000000000000000000000000003A00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v034/in.yaml--- key: &alias value *alias : - key --- key: &alias value *alias : - key 07070100000106000081A40000000000000000000000016616D6BA0000004A000000000000000000000000000000000000003B00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v034/out.yaml--- key: &alias value *alias : - key --- key: &alias value *alias : - key 07070100000107000081A40000000000000000000000016616D6BA000000B4000000000000000000000000000000000000003D00000000perl-YAML-PP-3.14.1712772794.39ac610/t/valid/v034/test.event+STR +DOC --- +MAP =VAL :key =VAL &alias :value =ALI *alias +SEQ =VAL :key -SEQ -MAP -DOC +DOC --- +MAP =VAL :key =VAL &alias :value =ALI *alias +SEQ =VAL :key -SEQ -MAP -DOC -STR 07070100000108000041ED0000000000000000000000026616D6BA00000000000000000000000000000000000000000000002800000000perl-YAML-PP-3.14.1712772794.39ac610/xt07070100000109000081A40000000000000000000000016616D6BA0000017E000000000000000000000000000000000000003700000000perl-YAML-PP-3.14.1712772794.39ac610/xt/02.pod-cover.tuse Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; my $xsaccessor = eval "use Class::XSAccessor; 1"; unless ($xsaccessor) { diag "\n----------------"; diag "Class::XSAccessor is not installed. Class attributes might not be checked"; diag "----------------"; } all_pod_coverage_ok(); 0707010000010A000081A40000000000000000000000016616D6BA000001B0000000000000000000000000000000000000003600000000perl-YAML-PP-3.14.1712772794.39ac610/xt/03.spelling.t#!/usr/bin/perl use strict; use warnings; use Test::More; use Test::Spelling; use Pod::Wordlist; add_stopwords(<DATA>); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ ansi dumpcode DumpFile failsafe FUNCTIONS header loadcode libsyck libyaml linter LoadFile Nim PyYAML RAML refref Representer roundtrip scalarref schemas Schema Schemas superset tml TODO unicode USD vimscript yaml yamllint Ingy döt Net flyx Krause Müller 0707010000010B000081A40000000000000000000000016616D6BA000000AB000000000000000000000000000000000000003100000000perl-YAML-PP-3.14.1712772794.39ac610/xt/04.pod.t#!/usr/bin/perl use strict; use warnings; use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!1261 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor