home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / YAML.pm < prev    next >
Encoding:
Perl POD Document  |  2002-06-25  |  47.1 KB  |  1,580 lines

  1. package YAML; 
  2. $VERSION = '0.35';
  3.  
  4. # This module implements a Loader and Dumper for the YAML serialization
  5. # language, VERSION 1.0 TRIAL2. (http://www.yaml.org/spec/)
  6.  
  7. require Exporter;
  8. @ISA = qw(Exporter);
  9. # Basic interface is Load & Dump
  10. # Phasing out Store in favor of Dump XXX
  11. # Leave it in for now. XXX
  12. @EXPORT = qw(Load Dump Store);
  13. # Provide a bunch of aliases for TMTOWTDI's sake
  14. @EXPORT_OK = qw(LoadFile DumpFile
  15.                 Dumper Eval 
  16.                 freeze thaw
  17.                 VALUE COMMENT
  18.                 Bless Blessed
  19.                );
  20. # Export groups
  21. %EXPORT_TAGS = (all => [qw(Load Dump Store LoadFile DumpFile Bless Blessed)],
  22.                 constants => [qw(VALUE COMMENT)],
  23.                 Storable => [qw(freeze thaw)],
  24.                 POE => [qw(freeze thaw)],
  25.                );
  26.  
  27. use strict;
  28. use YAML::Node;
  29. use YAML::Transfer;
  30. use Carp;
  31.  
  32. sub PRINT { print STDERR @_, "\n" } # XXX
  33. sub DUMP { use Data::Dumper(); print STDERR Data::Dumper::Dumper(@_) } # XXX
  34.  
  35. # Context constants
  36. use constant LEAF => 1;
  37. use constant COLLECTION => 2;
  38. use constant KEY => 3;
  39. use constant BLESSED => 4;
  40. use constant FROMARRAY => 5;
  41. use constant VALUE => "\x07YAML\x07VALUE\x07";
  42. use constant COMMENT => "\x07YAML\x07COMMENT\x07";
  43.  
  44. # These are the user changable options
  45. {
  46.     no strict 'vars'; 
  47.     $Indent = 2 unless defined $Indent;
  48.     $UseHeader = 1 unless defined $UseHeader;
  49.     $UseVersion = 1 unless defined $UseVersion;
  50.     $SortKeys = 1 unless defined $SortKeys;
  51.     $AnchorPrefix = '' unless defined $AnchorPrefix;
  52.     $UseCode = 0 unless defined $UseCode;
  53.     $DumpCode = '' unless defined $DumpCode;
  54.     $LoadCode = '' unless defined $LoadCode;
  55.     $ForceBlock = 0 unless defined $ForceBlock;
  56.     $UseBlock = 0 unless defined $UseBlock;
  57.     $UseFold = 0 unless defined $UseFold;
  58.     $CompressSeries = 1 unless defined $CompressSeries;
  59.     $InlineSeries = 0 unless defined $InlineSeries;
  60.     $UseAliases = 1 unless defined $UseAliases;
  61.     $Purity = 0 unless defined $Purity;
  62.     $DateClass = '' unless defined $DateClass;
  63. }
  64.  
  65. # Common YAML character sets
  66. my $WORD_CHAR = '[A-Za-z-]';
  67. my $ESCAPE_CHAR = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f]';
  68. my $INDICATOR_CHAR = '[#-:?*&!|\\\\^@%]';
  69. my $FOLD_CHAR = '>';
  70. my $BLOCK_CHAR = '|';    
  71. my $BLOCK_CHAR_RX = "\\$BLOCK_CHAR";    
  72.  
  73. # $o is the YAML object. It contains the complete state of the YAML.pm
  74. # process. This is set at the file scope level so that I can avoid using
  75. # OO syntax or passing the object around in function calls.
  76. #
  77. # When callback are added to YAML.pm the calling code will have to save
  78. # the object so that it won't get clobbered. Also YAML.pm can't be subclassed.
  79. # The purpose of this is for efficiency and also for much simpler code.
  80. my $o;
  81.  
  82. # YAML OO constructor function
  83. sub new {
  84.     my $class = shift;
  85.     my $o = {
  86.              stream => '',
  87.              level => 0,
  88.              anchor => 1,
  89.              Indent => $YAML::Indent,
  90.              UseHeader => $YAML::UseHeader,
  91.              UseVersion => $YAML::UseVersion,
  92.              SortKeys => $YAML::SortKeys,
  93.              AnchorPrefix => $YAML::AnchorPrefix,
  94.              DumpCode => $YAML::DumpCode,
  95.              LoadCode => $YAML::LoadCode,
  96.              ForceBlock => $YAML::ForceBlock,
  97.              UseBlock => $YAML::UseBlock,
  98.              UseFold => $YAML::UseFold,
  99.              CompressSeries => $YAML::CompressSeries,
  100.              InlineSeries => $YAML::InlineSeries,
  101.              UseAliases => $YAML::UseAliases,
  102.              Purity => $YAML::Purity,
  103.              DateClass => $YAML::DateClass,
  104.             };
  105.     bless $o, $class;
  106.     set_default($o, 'DumpCode', $YAML::UseCode);
  107.     set_default($o, 'LoadCode', $YAML::UseCode);
  108.     return $o if is_valid($o);
  109. }
  110.  
  111. my $global = {}; # A global lookup
  112. sub Bless { YAML::bless($global, @_) }
  113. sub Blessed { YAML::blessed($global, @_) }
  114.  
  115. sub blessed {
  116.     my ($o, $ref) = @_;
  117.     $ref = \$_[0] unless ref $ref;
  118.     my (undef, undef, $node_id) = YAML::Node::info($ref);
  119.     $o->{blessed}{$node_id};
  120. }
  121.     
  122. sub bless {
  123.     my ($o, $ref, $blessing) = @_;
  124.     my $ynode;
  125.     $ref = \$_[0] unless ref $ref;
  126.     my (undef, undef, $node_id) = YAML::Node::info($ref);
  127.     if (not defined $blessing) {
  128.         $ynode = YAML::Node->new($ref);
  129.     }
  130.     elsif (ref $blessing) {
  131.         croak unless ynode($blessing);
  132.         $ynode = $blessing;
  133.     }
  134.     else {
  135.         no strict 'refs';
  136.         my $transfer = $blessing . "::yaml_dump";
  137.         croak unless defined &{$transfer};
  138.         $ynode = &{$transfer}($ref);
  139.         croak unless ynode($ynode);
  140.     }
  141.     $o->{blessed}{$node_id} = $ynode;
  142.     my $object = ynode($ynode) or croak;
  143.     return $object;
  144. }
  145.  
  146. sub stream {
  147.     my ($o, $stream) = @_;
  148.     if (not defined $stream) {
  149.         return $o->{$stream};
  150.     }
  151.     elsif (ref($stream) eq 'CODE') {
  152.         $o->{stream_fetch} = $stream;
  153.         $o->{stream_eos} = 0;
  154.     }
  155.     elsif ($stream eq '') {
  156.         $o->{stream} = '';
  157.     }
  158.     else {
  159.         $o->{stream} .= $stream;
  160.     }
  161. }
  162.  
  163. sub set_default {
  164.     my ($o, $option, $default) = (@_);
  165.     return if length $o->{$option};
  166.     if (length $default) {
  167.         $o->{$option} = $default;
  168.     }
  169.     else {
  170.         $o->{$option} = -1;
  171.     }
  172. }
  173.  
  174. sub is_valid { 
  175.     my ($o) = (@_);
  176.     croak YAML_DUMP_ERR_INVALID_INDENT($o->{Indent}) 
  177.       unless ($o->{Indent} =~ /^(\d+)$/) and $1 > 0;
  178.     # NOTE: Add more tests...
  179.     return 1;
  180. }
  181.  
  182. #==============================================================================
  183. # Save the contents of a Dump operation to a file. If the file exists
  184. # and has data, and a concatenation was requested, then verify the
  185. # existing header.
  186. sub DumpFile {
  187.     my $filename = shift;
  188.     local $/ = "\n"; # reset special to "sane"
  189.     my $mode = '>';
  190.     if ($filename =~ /^\s*(>{1,2})\s*(.*)$/) {
  191.         ($mode, $filename) = ($1, $2);
  192.     }
  193.     if ($mode eq '>>' && -f $filename && -s $filename) {
  194.         open MYYAML, "< $filename" 
  195.             or croak YAML_LOAD_ERR_FILE_INPUT($filename, $!);
  196.         my $line = <MYYAML>;
  197.         close MYYAML;
  198.         croak YAML_DUMP_ERR_FILE_CONCATENATE($filename)
  199.           unless $line =~ /^---(\s|$)/;
  200.     }
  201.     open MYYAML, "$mode $filename"
  202.       or croak YAML_DUMP_ERR_FILE_OUTPUT($filename, $!);
  203.     print MYYAML YAML::Dump(@_);
  204.     close MYYAML;
  205. }
  206.     
  207. # Serialize a list of elements
  208. sub Dump {
  209.     $o = YAML->new();
  210.     $o->dump(@_);
  211. }
  212.  
  213. sub Store {
  214.     warn YAML_DUMP_WARN_STORE() if $^W;
  215.     goto &Dump;
  216. }
  217.  
  218. # Aliases for Dump
  219. *freeze = *freeze = \&Dump;    # alias for Storable or POE users
  220.  
  221. # OO version of Dump. YAML->new->dump($foo); 
  222. sub dump {
  223.     $o = shift; 
  224.     # local $| = 1; # set buffering to "hot" (for testing) XXX
  225.     local $/ = "\n"; # reset special to "sane" XXX (danger) fix for callbacks
  226.     $o->{stream} = '';
  227.     $o->{document} = 0;
  228.     for my $document (@_) {
  229.         $o->{document}++;
  230.         $o->{transferred} = {};
  231.         $o->{id_refcnt} = {};
  232.         $o->{id_anchor} = {};
  233.         $o->{anchor} = 1;
  234.         $o->{level} = 0;
  235.         $o->{offset}[0] = 0 - $o->{Indent};
  236.         _prewalk($document);
  237.         _emit_header($document);
  238.         _emit_node($document);
  239.     }
  240.     return $o->{stream};
  241. }
  242.  
  243. # Every YAML document in the stream must begin with a YAML header, unless
  244. # there is only a single document and the user requests "no header".
  245. sub _emit_header {
  246.     my ($node) = @_;
  247.     if (not $o->{UseHeader} and 
  248.         $o->{document} == 1
  249.        ) {
  250.         croak YAML_DUMP_ERR_NO_HEADER() unless ref($node) =~ /^(HASH|ARRAY)$/;
  251.         croak YAML_DUMP_ERR_NO_HEADER() if ref($node) eq 'HASH' and 
  252.                                            keys(%$node) == 0;
  253.         croak YAML_DUMP_ERR_NO_HEADER() if ref($node) eq 'ARRAY' and 
  254.                                            @$node == 0;
  255.         # XXX Also croak if aliased, blessed, or ynode
  256.         $o->{headless} = 1;
  257.         return;
  258.     }
  259.     $o->{stream} .= '---';
  260.     if ($o->{UseVersion}) {
  261.         $o->{stream} .= " #YAML:1.0";
  262.     }
  263. }
  264.  
  265. # Walk the tree to be dumped and keep track of its reference counts.
  266. # This function is where the Dumper does all its work. All transfers
  267. # happen here.
  268. sub _prewalk {
  269.     my $value;
  270.     my ($class, $type, $node_id) = YAML::Node::info(\$_[0]);
  271.     # Handle typeglobs
  272.     if ($type eq 'GLOB') {
  273.         $value = $o->{transferred}{$node_id} = 
  274.           YAML::Transfer::glob::yaml_dump($_[0]);
  275.         return _prewalk($value);
  276.     }
  277.     # Handle regexps
  278.     if (ref($_[0]) eq 'Regexp') {  
  279.         $o->{transferred}{$node_id} = YAML::Transfer::regexp::yaml_dump($_[0]);
  280.         return;
  281.     }
  282.     # Handle Purity for scalars. XXX can't find a use case yet. Might be YAGNI.
  283.     if (not ref $_[0]) {
  284.         $o->{id_refcnt}{$node_id}++ if $o->{Purity};
  285.         return;
  286.     }
  287.     # Make a copy of original
  288.     $value = $_[0];
  289.     ($class, $type, $node_id) = YAML::Node::info($value);
  290.     # Look for things already transferred.
  291.     if ($o->{transferred}{$node_id}) {
  292.         (undef, undef, $node_id) = (ref $o->{transferred}{$node_id})
  293.           ? YAML::Node::info($o->{transferred}{$node_id})
  294.           : YAML::Node::info(\ $o->{transferred}{$node_id});
  295.         $o->{id_refcnt}{$node_id}++;
  296.         return;
  297.     }
  298.     # Handle code refs
  299.     if ($type eq 'CODE') {
  300.         $o->{transferred}{$node_id} = 'crufty tracking reference placeholder';
  301.         YAML::Transfer::code::yaml_dump($o->{DumpCode},
  302.                                         $_[0], 
  303.                                         $o->{transferred}{$node_id});
  304.         ($class, $type, $node_id) = 
  305.           YAML::Node::info(\ $o->{transferred}{$node_id});
  306.         $o->{id_refcnt}{$node_id}++;
  307.         return;
  308.     }
  309.     # Handle blessed things
  310.     elsif (defined $class) {
  311.         no strict 'refs';
  312.         if ($class eq $o->{DateClass}) {
  313.             $value = eval "&${class}::yaml_dump(\$value)";
  314.         }
  315.         elsif (defined &{$class . "::yaml_dump"}) {
  316.             $value = eval "&${class}::yaml_dump(\$value)";
  317.         }
  318.         elsif ($type eq 'SCALAR') {
  319.             $o->{transferred}{$node_id} = 'tracking reference placeholder';
  320.             YAML::Transfer::blessed::yaml_dump
  321.               ($_[0], $o->{transferred}{$node_id});
  322.             ($class, $type, $node_id) =
  323.               YAML::Node::info(\ $o->{transferred}{$node_id});
  324.             $o->{id_refcnt}{$node_id}++;
  325.             return;
  326.         }
  327.         else {
  328.             $value = YAML::Transfer::blessed::yaml_dump($value);
  329.         }
  330.         $o->{transferred}{$node_id} = $value;
  331.         (undef, $type, $node_id) = YAML::Node::info($value);
  332.     }
  333.     # Handle YAML Blessed things
  334.     if (defined $global->{blessed}{$node_id}) {
  335.         $value = $global->{blessed}{$node_id};
  336.         $o->{transferred}{$node_id} = $value;
  337.         ($class, $type, $node_id) = YAML::Node::info($value);
  338.         return _prewalk($value);
  339.     }
  340.     # Handle hard refs
  341.     if ($type eq 'REF' or $type eq 'SCALAR') {
  342.         $value = YAML::Transfer::ref::yaml_dump($value);
  343.         $o->{transferred}{$node_id} = $value;
  344.         (undef, $type, $node_id) = YAML::Node::info($value);
  345.     }
  346.     # Handle ref-to-glob's
  347.     elsif ($type eq 'GLOB') {
  348.         my $ref_ynode = $o->{transferred}{$node_id} =
  349.           YAML::Transfer::ref::yaml_dump($value);
  350.  
  351.         my $glob_ynode = $ref_ynode->{&VALUE} = 
  352.           YAML::Transfer::glob::yaml_dump($$value);
  353.  
  354.         (undef, undef, $node_id) = YAML::Node::info($glob_ynode);
  355.         $o->{transferred}{$node_id} = $glob_ynode;
  356.         return _prewalk($glob_ynode);
  357.     }
  358.       
  359.     # Increment ref count for node
  360.     return if ++($o->{id_refcnt}{$node_id}) > 1;
  361.  
  362.     # Continue walking
  363.     if ($type eq 'HASH') {
  364.         _prewalk($value->{$_}) for keys %{$value};
  365.     }
  366.     elsif ($type eq 'ARRAY') {
  367.         _prewalk($_) for @{$value};
  368.     }
  369. }
  370.  
  371. # Every data element and sub data element is a node. Everything emitted
  372. # goes through this function.
  373. sub _emit_node {
  374.     my ($type, $node_id);
  375.     my $ref = ref($_[0]);
  376.     if ($ref and $ref ne 'Regexp') {
  377.         (undef, $type, $node_id) = YAML::Node::info($_[0]);
  378.     }
  379.     else {
  380.         $type = $ref || 'SCALAR';
  381.         (undef, undef, $node_id) = YAML::Node::info(\$_[0]);
  382.     }
  383.  
  384.     my ($ynode, $family) = ('') x 2;
  385.     my ($value, $context) = (@_, 0); # XXX don't copy scalars
  386.     if (defined $o->{transferred}{$node_id}) {
  387.         $value = $o->{transferred}{$node_id};
  388.         $ynode = ynode($value);
  389.         if (ref $value) {
  390.             $family = defined $ynode ? $ynode->family->short : '';
  391.             (undef, $type, $node_id) = YAML::Node::info($value);
  392.         }
  393.         else {
  394.             $family = ynode($o->{transferred}{$node_id})->family->short;
  395.             $type = 'SCALAR';
  396.             (undef, undef, $node_id) = 
  397.               YAML::Node::info(\ $o->{transferred}{$node_id});
  398.         }
  399.     }
  400.     elsif ($ynode = ynode($value)) {
  401.         $family = $ynode->family->short;
  402.     }
  403.  
  404.     if ($o->{UseAliases}) {
  405.         $o->{id_refcnt}{$node_id} ||= 0;
  406.         if ($o->{id_refcnt}{$node_id} > 1) {
  407.             if (defined $o->{id_anchor}{$node_id}) {
  408.                 $o->{stream} .= ' *' . $o->{id_anchor}{$node_id} . "\n";
  409.                 return;
  410.             }
  411.             my $anchor = $o->{AnchorPrefix} . $o->{anchor}++;
  412.             $o->{stream} .= ' &' . $anchor;
  413.             $o->{id_anchor}{$node_id} = $anchor;
  414.         }
  415.     }
  416.  
  417.     return _emit_scalar($value, $family) if $type eq 'SCALAR' and $family;
  418.     return _emit_str($value) if $type eq 'SCALAR';
  419.     return _emit_mapping($value, $family, $node_id, $context) if $type eq 'HASH';
  420.     return _emit_sequence($value, $family) if $type eq 'ARRAY';
  421.     warn YAML_DUMP_WARN_BAD_NODE_TYPE($type) if $^W;
  422.     return _emit_str("$value");
  423. }
  424.  
  425. # A YAML mapping is akin to a Perl hash. 
  426. sub _emit_mapping {
  427.     my ($value, $family, $node_id, $context) = @_;
  428.     $o->{stream} .= " !$family" if $family;
  429.  
  430.     # Sometimes 'keys' fails. Like on a bad tie implementation.
  431.     my $empty_hash = not(eval {keys %$value});
  432.     warn YAML_EMIT_WARN_KEYS($@) if $^W and $@;
  433.     return ($o->{stream} .= " {}\n") if $empty_hash;
  434.         
  435.     # If CompressSeries is on (default) and legal is this context, then
  436.     # use it and make the indent level be 2 for this node.
  437.     if ($context == FROMARRAY and $o->{CompressSeries} and
  438.         not (defined $o->{id_anchor}{$node_id} or $family or $empty_hash)
  439.        ) {
  440.         $o->{stream} .= ' ';
  441.         $o->{offset}[$o->{level}+1] = $o->{offset}[$o->{level}] + 2;
  442.     }
  443.     else {
  444.         $context = 0;
  445.         $o->{stream} .= "\n" unless $o->{headless} && not($o->{headless} = 0);
  446.         $o->{offset}[$o->{level}+1] = $o->{offset}[$o->{level}] + $o->{Indent};
  447.     }
  448.  
  449.     $o->{level}++;
  450.     my @keys;
  451.     if ($o->{SortKeys} == 1) {
  452.         if (ynode($value)) {
  453.             @keys = keys %$value;
  454.         }
  455.         else {
  456.             @keys = sort keys %$value;
  457.         }
  458.     }
  459.     elsif ($o->{SortKeys} == 2) {
  460.         @keys = sort keys %$value;
  461.     }
  462.     # XXX This is hackish but sometimes handy. Not sure whether to leave it in.
  463.     elsif (ref($o->{SortKeys}) eq 'ARRAY') {
  464.         my $i = 1;
  465.         my %order = map { ($_, $i++) } @{$o->{SortKeys}};
  466.         @keys = sort {
  467.             (defined $order{$a} and defined $order{$b})
  468.               ? ($order{$a} <=> $order{$b})
  469.               : ($a cmp $b);
  470.         } keys %$value;
  471.     }
  472.     else {
  473.         @keys = keys %$value;
  474.     }
  475.     # Force the YAML::VALUE ('=') key to sort last.
  476.     if (exists $value->{&VALUE}) {
  477.         for (my $i = 0; $i < @keys; $i++) {
  478.             if ($keys[$i] eq &VALUE) {
  479.                 splice(@keys, $i, 1);
  480.                 push @keys, &VALUE;
  481.                 last;
  482.             }
  483.         }
  484.     }
  485.  
  486.     for my $key (@keys) {
  487.         _emit_key($key, $context);
  488.         $context = 0;
  489.         $o->{stream} .= ':';
  490.         _emit_node($value->{$key});
  491.     }
  492.     $o->{level}--;
  493. }
  494.  
  495. # A YAML series is akin to a Perl array.
  496. sub _emit_sequence {
  497.     my ($value, $family) = @_;
  498.     $o->{stream} .= " !$family" if $family;
  499.  
  500.     return ($o->{stream} .= " []\n") if @$value == 0;
  501.         
  502.     $o->{stream} .= "\n" unless $o->{headless} && not($o->{headless} = 0);
  503.  
  504.     # XXX Really crufty feature. Better implemented by ynodes.
  505.     if ($o->{InlineSeries} and
  506.         @$value <= $o->{InlineSeries} and
  507.         not (scalar grep {ref or /\n/} @$value)
  508.        ) {
  509.         $o->{stream} =~ s/\n\Z/ /;
  510.         $o->{stream} .= '[';
  511.         for (my $i = 0; $i < @$value; $i++) {
  512.             _emit_str($value->[$i], KEY);
  513.             last if $i == $#{$value};
  514.             $o->{stream} .= ', ';
  515.         }
  516.         $o->{stream} .= "]\n";
  517.         return;
  518.     }
  519.  
  520.     $o->{offset}[$o->{level} + 1] = $o->{offset}[$o->{level}] + $o->{Indent};
  521.     $o->{level}++;
  522.     for my $val (@$value) {
  523.         $o->{stream} .= ' ' x $o->{offset}[$o->{level}];
  524.         $o->{stream} .= '-';
  525.         _emit_node($val, FROMARRAY);
  526.     }
  527.     $o->{level}--;
  528. }
  529.  
  530. # Emit a mapping key
  531. sub _emit_key {
  532.     my ($value, $context) = @_;
  533.     $o->{stream} .= ' ' x $o->{offset}[$o->{level}]
  534.       unless $context == FROMARRAY;
  535.     _emit_str($value, KEY);
  536. }
  537.  
  538. # Emit a blessed SCALAR
  539. sub _emit_scalar {
  540.     my ($value, $family) = @_;
  541.     $o->{stream} .= " !$family";
  542.     _emit_str($value, BLESSED);
  543. }
  544.  
  545. # Emit a string value. YAML has many scalar styles. This routine attempts to
  546. # guess the best style for the text.
  547. sub _emit_str {
  548.     my $type = $_[1] || 0;
  549.  
  550.     # Use heuristics to find the best scalar emission style.
  551.     $o->{offset}[$o->{level} + 1] = $o->{offset}[$o->{level}] + $o->{Indent};
  552.     $o->{level}++;
  553.  
  554.     if (defined $_[0] and
  555.         $_[0] !~ /$ESCAPE_CHAR/ and
  556.         (length($_[0]) > 50 or $_[0] =~ /\n\s/ or
  557.          ($o->{ForceBlock} and $type != KEY)
  558.         ) 
  559.        ) {
  560.         $o->{stream} .= ($type == KEY) ? '? ' : ' ';
  561.         if (($o->{UseFold} and not $o->{ForceBlock}) or
  562.             ($_[0] =~ /^\S[^\n]{76}/m)
  563.            ) {  
  564.             if (is_valid_implicit($_[0]) && # XXX Check implicit check
  565.                 $type != BLESSED
  566.                ) {
  567.                 $o->{stream} .= '! ';
  568.             }
  569.             _emit_nested($FOLD_CHAR, $_[0]);
  570.         }
  571.         else {
  572.             _emit_nested($BLOCK_CHAR, $_[0]);
  573.         }
  574.         $o->{stream} .= "\n";
  575.     }
  576.     else {
  577.         $o->{stream} .= ' ' if $type != KEY;
  578.         if (defined $_[0] && $_[0] eq VALUE) {
  579.             $o->{stream} .= '=';
  580.         }
  581.         elsif (is_valid_implicit($_[0])) {
  582.             _emit_simple($_[0]);
  583.         }
  584.         elsif ($_[0] =~ /$ESCAPE_CHAR|\n|\'/) {
  585.             _emit_double($_[0]);
  586.         }
  587.         else {
  588.             _emit_single($_[0]);
  589.         }
  590.         $o->{stream} .= "\n" if $type != KEY;
  591.     }
  592.     
  593.     $o->{level}--;
  594.  
  595.     return;
  596. }
  597.  
  598. # Check whether or not a scalar should be emitted as an simple scalar.
  599. sub is_valid_implicit {
  600.     return 1 if not defined $_[0];
  601.     return 1 if $_[0] =~ /^(-?\d+)$/;                 # !int
  602.     return 1 if $_[0] =~ /^-?\d+\.\d+$/;              # !float
  603.     return 1 if $_[0] =~ /^-?\d+e[+-]\d+$/;           # !float
  604.     # XXX - Detect date objects someday (or not)
  605.     return 0 if $_[0] =~ /$ESCAPE_CHAR/;
  606.     return 0 if $_[0] =~ /(^\s|\:( |$)|\#( |$)|\s$)/;
  607.     return 1 if $_[0] =~ /^\w/;                       # !str
  608.     return 0;
  609. }
  610.  
  611. # A nested scalar is either block or folded 
  612. sub _emit_nested {
  613.     my ($indicator, $value) = @_;
  614.     $o->{stream} .= $indicator;
  615.     $value =~ /(\n*)\Z/;
  616.     my $chomp = length $1 ? (length $1 > 1) ? '+' : '' : '-';
  617.     $value = '~' if not defined $value;
  618.     $o->{stream} .= $chomp;
  619.     $o->{stream} .= $o->{Indent} if $value =~ /^\s/;
  620.     if ($indicator eq $FOLD_CHAR) {
  621.         $value = fold($value);
  622.         chop $value unless $chomp eq '+';
  623.     }
  624.     $o->{stream} .= indent($value);
  625. }
  626.  
  627. # Simple means that the scalar is unquoted. It is analyzed for its type
  628. # implicitly using regexes.
  629. sub _emit_simple {
  630.     $o->{stream} .= defined $_[0] ? $_[0] : '~';
  631. }
  632.  
  633. # Double quoting is for single lined escaped strings.
  634. sub _emit_double {
  635.     (my $escaped = escape($_[0])) =~ s/"/\\"/g;
  636.     $o->{stream} .= qq{"$escaped"};
  637. }
  638.  
  639. # Single quoting is for single lined unescaped strings.
  640. sub _emit_single {
  641.     $o->{stream} .= "'$_[0]'";
  642. }
  643.  
  644. #==============================================================================
  645. # Read a YAML stream from a file and call Load on it.
  646. sub LoadFile {
  647.     my $filename = shift;
  648.     local $/ = "\n"; # reset special to "sane"
  649.     open MYYAML, $filename or croak YAML_LOAD_ERR_FILE_INPUT($filename, $!);
  650.     my $yaml = join '', <MYYAML>;
  651.     close MYYAML;
  652.     return Load($yaml);
  653. }
  654.  
  655. # Deserialize a YAML stream into a list of data elements
  656. sub Load {
  657.     croak YAML_LOAD_USAGE() unless @_ == 1;
  658.     $o = YAML->new;
  659.     $o->{stream} = defined $_[0] ? $_[0] : '';
  660.     return load();
  661. }
  662.  
  663. # Aliases for Load
  664. *Undent = *Undent = \&Load;
  665. *Eval = *Eval = \&Load;
  666. *thaw = *thaw = \&Load;
  667.  
  668. # OO version of Load
  669. sub load {
  670.     # local $| = 1; # set buffering to "hot" (for testing)
  671.     local $/ = "\n"; # reset special to "sane"
  672.     return _parse();
  673. }
  674.  
  675. # Top level function for parsing. Parse each document in order and
  676. # handle processing for YAML headers.
  677. sub _parse {
  678.     my (%directives, $preface);
  679.     $o->{stream} =~ s|\015\012|\012|g;
  680.     $o->{stream} =~ s|\015|\012|g;
  681.     $o->{line} = 0;
  682.     croak YAML_PARSE_ERR_BAD_CHARS() 
  683.       if $o->{stream} =~ /$ESCAPE_CHAR/;
  684.     croak YAML_PARSE_ERR_NO_FINAL_NEWLINE() 
  685.       if length($o->{stream}) and 
  686.          $o->{stream} !~ s/(.)\n\Z/$1/s;
  687.     @{$o->{lines}} = split /\x0a/, $o->{stream}, -1;
  688.     $o->{line} = 1;
  689.     # Throw away any comments or blanks before the header (or start of
  690.     # content for headerless streams)
  691.     _parse_throwaway_comments();
  692.     $o->{document} = 0;
  693.     $o->{documents} = [];
  694.     # Add an "assumed" header if there is no header and the stream is
  695.     # not empty (after initial throwaways).
  696.     if (not $o->{eos}) {
  697.         if ($o->{lines}[0] !~ /^---(\s|$)/) {
  698.             unshift @{$o->{lines}}, '--- #YAML:1.0';
  699.             $o->{line}--;
  700.         }
  701.     }
  702.  
  703.     # Main Loop. Parse out all the top level nodes and return them.
  704.     while (not $o->{eos}) {
  705.         $o->{anchor2node} = {};
  706.         $o->{document}++;
  707.         $o->{done} = 0;
  708.         $o->{level} = 0;
  709.         $o->{offset}[0] = -1;
  710.  
  711.         if ($o->{lines}[0] =~ /^---\s*(.*)$/) {
  712.             my @words = split /\s+/, $1;
  713.             %directives = ();
  714.             while (@words && $words[0] =~ /^#(\w+):(\S.*)$/) {
  715.                 my ($key, $value) = ($1, $2);
  716.                 shift(@words);
  717.                 if (defined $directives{$key}) {
  718.                     warn YAML_PARSE_WARN_MULTIPLE_DIRECTIVES
  719.                       ($key, $o->{document}) if $^W;
  720.                     next;
  721.                 }
  722.                 $directives{$key} = $value;
  723.             }
  724.             $o->{preface} = join ' ', @words;
  725.         }
  726.         else {
  727.             croak YAML_PARSE_ERR_NO_SEPARATOR();
  728.         }
  729.  
  730.         if (not $o->{done}) {
  731.             _parse_next_line(COLLECTION);
  732.         }
  733.         if ($o->{done}) {
  734.             $o->{indent} = -1;
  735.             $o->{content} = '';
  736.         }
  737.  
  738.         $directives{YAML} ||= '1.0';
  739.         $directives{TAB} ||= 'NONE';
  740.         ($o->{major_version}, $o->{minor_version}) = 
  741.           split /\./, $directives{YAML}, 2;
  742.         croak YAML_PARSE_ERR_BAD_MAJOR_VERSION($directives{YAML})
  743.           if ($o->{major_version} ne '1');
  744.         warn YAML_PARSE_WARN_BAD_MINOR_VERSION($directives{YAML})
  745.           if ($^W and $o->{minor_version} ne '0');
  746.         croak "Unrecognized TAB policy"  # XXX add to ::Error
  747.           unless $directives{TAB} =~ /^(NONE|\d+)(:HARD)?$/;
  748.         
  749.  
  750.         push @{$o->{documents}}, _parse_node();
  751.     }
  752.     return wantarray ? @{$o->{documents}} : $o->{documents}[-1];
  753. }
  754.  
  755. # This function is the dispatcher for parsing each node. Every node
  756. # recurses back through here. (Inlines are an exception as they have
  757. # their own sub-parser.)
  758. sub _parse_node {
  759. # ??????????????????????????????????????    
  760. # $|=1;
  761. # print <<END;
  762. # _parse_node ${\++$YAML::x}
  763. # indent  - $o->{indent}
  764. # preface - $o->{preface}
  765. # content - $o->{content}
  766. # level   - $o->{level}
  767. # offsets - @{$o->{offset}}
  768. # END
  769. # ??????????????????????????????????????    
  770.     my $preface = $o->{preface};
  771.     $o->{preface} = '';
  772.     my ($node, $type, $indicator, $escape, $chomp) = ('') x 5;
  773.     my ($anchor, $alias, $explicit, $implicit, $class) = ('') x 5;
  774.     ($anchor, $alias, $explicit, $implicit, $class, $preface) = 
  775.       _parse_qualifiers($preface);
  776.     if ($anchor) {
  777.         $o->{anchor2node}{$anchor} = CORE::bless [], 'YAML-anchor2node';
  778.     }
  779.     $o->{inline} = '';
  780.     while (length $preface) {
  781.         my $line = $o->{line} - 1;
  782.         # XXX rking suggests refactoring the following regex and its evil twin
  783.         if ($preface =~ s/^($FOLD_CHAR|$BLOCK_CHAR_RX)(-|\+)?\d*\s*//) { 
  784.             $indicator = $1;
  785.             $chomp = $2 if defined($2);
  786.         }
  787.         else {
  788.             croak YAML_PARSE_ERR_TEXT_AFTER_INDICATOR() if $indicator;
  789.             $o->{inline} = $preface;
  790.             $preface = '';
  791.         }
  792.     }
  793.     if ($alias) {
  794.         croak YAML_PARSE_ERR_NO_ANCHOR($alias) 
  795.           unless defined $o->{anchor2node}{$alias};
  796.         if (ref($o->{anchor2node}{$alias}) ne 'YAML-anchor2node') {
  797.             $node = $o->{anchor2node}{$alias};
  798.         }
  799.         else {
  800.             $node = do {my $sv = "*$alias"};
  801.             push @{$o->{anchor2node}{$alias}}, [\$node, $o->{line}]; 
  802.         }
  803.     }
  804.     elsif (length $o->{inline}) {
  805.         $node = _parse_inline(1, $implicit, $explicit, $class);
  806.         if (length $o->{inline}) {
  807.             croak YAML_PARSE_ERR_SINGLE_LINE(); 
  808.         }
  809.     }
  810.     elsif ($indicator eq $BLOCK_CHAR) {
  811.         $o->{level}++;
  812.         $node = _parse_block($chomp);
  813.         $node = _parse_implicit($node) if $implicit;
  814.         $o->{level}--; 
  815.     }
  816.     elsif ($indicator eq $FOLD_CHAR) {
  817.         $o->{level}++;
  818.         $node = _parse_unfold($chomp);
  819.         $node = _parse_implicit($node) if $implicit;
  820.         $o->{level}--;
  821.     }
  822.     else {
  823.         $o->{level}++;
  824.         $o->{offset}[$o->{level}] ||= 0;
  825.         if ($o->{indent} == $o->{offset}[$o->{level}]) {
  826.             if ($o->{content} =~ /^-( |$)/) {
  827.                 $node = _parse_seq($anchor);
  828.             }
  829.             elsif ($o->{content} =~ /(^\?|\:( |$))/) {
  830.                 $node = _parse_mapping($anchor);
  831.             }
  832.             elsif ($preface =~ /^\s*$/) {
  833.                 $node = _parse_implicit('');
  834.             }
  835.             else {
  836.                 croak YAML_PARSE_ERR_BAD_NODE();
  837.             }
  838.         }
  839.         else {
  840.             $node = '';
  841.         }
  842.         $o->{level}--;
  843.     }
  844.     $#{$o->{offset}} = $o->{level};
  845.  
  846.     if ($explicit) {
  847.         if ($class) {
  848.             if (not ref $node) {
  849.                 my $copy = $node;
  850.                 undef $node;
  851.                 $node = \$copy;
  852.             }
  853.             CORE::bless $node, $class;
  854.         }
  855.         else {
  856.             $node = _parse_explicit($node, $explicit);
  857.         }
  858.     }
  859.     if ($anchor) {
  860.         if (ref($o->{anchor2node}{$anchor}) eq 'YAML-anchor2node') {
  861.             # XXX Can't remember what this code actually does
  862.             for my $ref (@{$o->{anchor2node}{$anchor}}) {
  863.                 ${$ref->[0]} = $node;
  864.                 warn YAML_LOAD_WARN_UNRESOLVED_ALIAS($anchor, $ref->[1]) if $^W;
  865.             }
  866.         }
  867.         $o->{anchor2node}{$anchor} = $node;
  868.     }
  869.     return $node;
  870. }
  871.  
  872. # Preprocess the qualifiers that may be attached to any node.
  873. sub _parse_qualifiers {
  874.     my ($preface) = @_;
  875.     my ($anchor, $alias, $explicit, $implicit, $class, $token) = ('') x 6;
  876.     $o->{inline} = '';
  877.     while ($preface =~ /^[&*!]/) {
  878.         my $line = $o->{line} - 1;
  879.         if ($preface =~ s/^\!(\S+)\s*//) {
  880.             croak YAML_PARSE_ERR_MANY_EXPLICIT() if $explicit;
  881.             $explicit = $1;
  882.         }
  883.         elsif ($preface =~ s/^\!\s*//) {
  884.             croak YAML_PARSE_ERR_MANY_IMPLICIT() if $implicit;
  885.             $implicit = 1;
  886.         }
  887.         elsif ($preface =~ s/^\&([^ ,:]+)\s*//) {
  888.             $token = $1;
  889.             croak YAML_PARSE_ERR_BAD_ANCHOR() 
  890.               unless $token =~ /^[a-zA-Z0-9]+$/;
  891.             croak YAML_PARSE_ERR_MANY_ANCHOR() if $anchor;
  892.             croak YAML_PARSE_ERR_ANCHOR_ALIAS() if $alias;
  893.             $anchor = $token;
  894.         }
  895.         elsif ($preface =~ s/^\*([^ ,:]+)\s*//) {
  896.             $token = $1;
  897.             croak YAML_PARSE_ERR_BAD_ALIAS() unless $token =~ /^[a-zA-Z0-9]+$/;
  898.             croak YAML_PARSE_ERR_MANY_ALIAS() if $alias;
  899.             croak YAML_PARSE_ERR_ANCHOR_ALIAS() if $anchor;
  900.             $alias = $token;
  901.         }
  902.     }
  903.     return ($anchor, $alias, $explicit, $implicit, $class, $preface); 
  904. }
  905.  
  906. # Morph a node to it's explicit type  
  907. sub _parse_explicit {
  908.     my ($node, $explicit) = @_;
  909.     if ($explicit =~ m{^(int|float|bool|date|time|datetime|binary)$}) {
  910.         my $handler = "YAML::_load_$1";
  911.         no strict 'refs';
  912.         return &$handler($node);
  913.     }
  914.     elsif ($explicit =~ m{^perl/(glob|regexp|code|ref)\:(\w(\w|\:\:)*)?$}) {
  915.         my ($type, $class) = (($1 || ''), ($2 || ''));
  916.         my $handler = "YAML::_load_perl_$type";
  917.         no strict 'refs';
  918.         if (defined &$handler) {
  919.             return &$handler($node, $class);
  920.         }
  921.         else {
  922.             croak YAML_LOAD_ERR_NO_CONVERT('XXX', $explicit);
  923.         }
  924.     }
  925.     elsif ($explicit =~ m{^perl/(\@|\$)?([a-zA-Z](\w|::)+)$}) {
  926.         my ($package) = ($2);
  927.         my $handler = "${package}::yaml_load";
  928.         no strict 'refs';
  929.         if (defined &$handler) {
  930.             return &$handler(YAML::Node->new($node, $explicit));
  931.         }
  932.         else {
  933.             return CORE::bless $node, $package;
  934.         }
  935.     }
  936.     elsif ($explicit !~ m|/|) {
  937.         croak YAML_LOAD_ERR_NO_CONVERT('XXX', $explicit);
  938.     }
  939.     else {
  940.         return YAML::Node->new($node, $explicit);
  941.     }
  942. }
  943.  
  944. # Morph to a perl reference
  945. sub _load_perl_ref {
  946.     my ($node) = @_;
  947.     croak YAML_LOAD_ERR_NO_DEFAULT_VALUE('ptr') unless exists $node->{&VALUE};
  948.     return \$node->{&VALUE};
  949. }
  950.  
  951. # Morph to a perl regexp
  952. sub _load_perl_regexp {
  953.     my ($node) = @_;
  954.     my ($regexp, $modifiers);
  955.     if (defined $node->{REGEXP}) {
  956.         $regexp = $node->{REGEXP};
  957.         delete $node->{REGEXP};
  958.     }
  959.     else {
  960.         warn YAML_LOAD_WARN_NO_REGEXP_IN_REGEXP() if $^W;
  961.         return undef;
  962.     }
  963.     if (defined $node->{MODIFIERS}) {
  964.         $modifiers = $node->{MODIFIERS};
  965.         delete $node->{MODIFIERS};
  966.     } else {
  967.         $modifiers = '';
  968.     }
  969.     for my $elem (sort keys %$node) {
  970.         warn YAML_LOAD_WARN_BAD_REGEXP_ELEM($elem) if $^W;
  971.     }
  972.     my $value = eval "qr($regexp)$modifiers";
  973.     if ($@) {
  974.         warn YAML_LOAD_WARN_REGEXP_CREATE($regexp, $modifiers, $@) if $^W;
  975.         return undef;
  976.     }
  977.     return $value;
  978. }
  979.  
  980. # Morph to a perl glob
  981. sub _load_perl_glob {
  982.     my ($node) = @_;
  983.     my ($name, $package);
  984.     if (defined $node->{NAME}) {
  985.         $name = $node->{NAME};
  986.         delete $node->{NAME};
  987.     }
  988.     else {
  989.         warn YAML_LOAD_WARN_GLOB_NAME() if $^W;
  990.         return undef;
  991.     }
  992.     if (defined $node->{PACKAGE}) {
  993.         $package = $node->{PACKAGE};
  994.         delete $node->{PACKAGE};
  995.     } else {
  996.         $package = 'main';
  997.     }
  998.     no strict 'refs';
  999.     if (exists $node->{SCALAR}) {
  1000.         *{"${package}::$name"} = \$node->{SCALAR};
  1001.         delete $node->{SCALAR};
  1002.     }
  1003.     for my $elem (qw(ARRAY HASH CODE IO)) {
  1004.         if (exists $node->{$elem}) {
  1005.             if ($elem eq 'IO') {
  1006.                 warn YAML_LOAD_WARN_GLOB_IO() if $^W;
  1007.                 delete $node->{IO};
  1008.                 next;
  1009.             }
  1010.             *{"${package}::$name"} = $node->{$elem};
  1011.             delete $node->{$elem};
  1012.         }
  1013.     }
  1014.     for my $elem (sort keys %$node) {
  1015.         warn YAML_LOAD_WARN_BAD_GLOB_ELEM($elem) if $^W;
  1016.     }
  1017.     return *{"${package}::$name"};
  1018. }
  1019.  
  1020. # Special support for an empty mapping
  1021. #sub _parse_str_to_map {
  1022. #    my ($node) = @_;
  1023. #    croak YAML_LOAD_ERR_NON_EMPTY_STRING('mapping') unless $node eq '';
  1024. #    return {};
  1025. #}
  1026.  
  1027. # Special support for an empty sequence
  1028. #sub _parse_str_to_seq {
  1029. #    my ($node) = @_;
  1030. #    croak YAML_LOAD_ERR_NON_EMPTY_STRING('sequence') unless $node eq '';
  1031. #    return [];
  1032. #}
  1033.  
  1034. # Support for sparse sequences
  1035. #sub _parse_map_to_seq {
  1036. #    my ($node) = @_;
  1037. #    my $seq = [];
  1038. #    for my $index (keys %$node) {
  1039. #        croak YAML_LOAD_ERR_BAD_MAP_TO_SEQ($index) unless $index =~ /^\d+/;
  1040. #        $seq->[$index] = $node->{$index};
  1041. #    }
  1042. #    return $seq;
  1043. #}
  1044.  
  1045. # Support for !int
  1046. sub _load_int {
  1047.     my ($node) = @_;
  1048.     croak YAML_LOAD_ERR_BAD_STR_TO_INT() unless $node =~ /^-?\d+$/;
  1049.     return $node;
  1050. }
  1051.  
  1052. # Support for !date
  1053. sub _load_date {
  1054.     my ($node) = @_;
  1055.     croak YAML_LOAD_ERR_BAD_STR_TO_DATE() unless $node =~ /^\d\d\d\d-\d\d-\d\d$/;
  1056.     return $node;
  1057. }
  1058.  
  1059. # Support for !time
  1060. sub _load_time {
  1061.     my ($node) = @_;
  1062.     croak YAML_LOAD_ERR_BAD_STR_TO_TIME() unless $node =~ /^\d\d:\d\d:\d\d$/;
  1063.     return $node;
  1064. }
  1065.  
  1066. # Support for !perl/code;deparse
  1067. sub _load_perl_code {
  1068.     my ($node, $class) = @_;
  1069.     if ($o->{LoadCode}) {
  1070.         my $code = eval "package main; sub $node";
  1071.         if ($@) {
  1072.             warn YAML_LOAD_WARN_PARSE_CODE($@) if $^W;
  1073.             return sub {};
  1074.         }
  1075.         else {
  1076.             CORE::bless $code, $class if $class;
  1077.             return $code;
  1078.         }
  1079.     }
  1080.     else {
  1081.         return sub {};
  1082.     }
  1083. }
  1084.  
  1085. # Parse a YAML mapping into a Perl hash
  1086. sub _parse_mapping {
  1087.     my ($anchor) = @_;
  1088.     my $mapping = {};
  1089.     $o->{anchor2node}{$anchor} = $mapping;
  1090.     my $key;
  1091.     while (not $o->{done} and $o->{indent} == $o->{offset}[$o->{level}]) {
  1092.         # If structured key:
  1093.         if ($o->{content} =~ s/^\?\s*//) {
  1094.             $o->{preface} = $o->{content};
  1095.             _parse_next_line(COLLECTION);
  1096.             $key = _parse_node();
  1097.             $key = "$key";
  1098.         }
  1099.         # If "default" key (equals sign) 
  1100.         elsif ($o->{content} =~ s/^\=\s*//) {
  1101.             $key = VALUE;
  1102.         }
  1103.         # If "comment" key (slash slash)
  1104.         elsif ($o->{content} =~ s/^\=\s*//) {
  1105.             $key = COMMENT;
  1106.         }
  1107.         # Regular scalar key:
  1108.         else {
  1109.             $o->{inline} = $o->{content};
  1110.             $key = _parse_inline();
  1111.             $key = "$key";
  1112.             $o->{content} = $o->{inline};
  1113.             $o->{inline} = '';
  1114.         }
  1115.             
  1116.         unless ($o->{content} =~ s/^:\s*//) {
  1117.             croak YAML_LOAD_ERR_BAD_MAP_ELEMENT();
  1118.         }
  1119.         $o->{preface} = $o->{content};
  1120.         my $line = $o->{line};
  1121.         _parse_next_line(COLLECTION);
  1122.         my $value = _parse_node();
  1123.         if (exists $mapping->{$key}) {
  1124.             warn YAML_LOAD_WARN_DUPLICATE_KEY() if $^W;
  1125.         }
  1126.         else {
  1127.             $mapping->{$key} = $value;
  1128.         }
  1129.     }
  1130.     return $mapping;
  1131. }
  1132.  
  1133. # Parse a YAML sequence into a Perl array
  1134. sub _parse_seq {
  1135.     my ($anchor) = @_;
  1136.     my $seq = [];
  1137.     $o->{anchor2node}{$anchor} = $seq;
  1138.     while (not $o->{done} and $o->{indent} == $o->{offset}[$o->{level}]) {
  1139.         if ($o->{content} =~ /^-(?: (.*))?$/) {
  1140.             $o->{preface} = defined($1) ? $1 : '';
  1141.         }
  1142.         else {
  1143.             croak YAML_LOAD_ERR_BAD_SEQ_ELEMENT();
  1144.         }
  1145.         if ($o->{preface} =~ /^(\s*)(\w.*\:(?: |$).*)$/) {
  1146.             $o->{indent} = $o->{offset}[$o->{level}] + 2 + length($1);
  1147.             $o->{content} = $2;
  1148.             $o->{offset}[++$o->{level}] = $o->{indent};
  1149.             $o->{preface} = '';
  1150.             push @$seq, _parse_mapping('');
  1151.             $o->{level}--;
  1152.             $#{$o->{offset}} = $o->{level};
  1153.         }
  1154.         else {
  1155.             _parse_next_line(COLLECTION);
  1156.             push @$seq, _parse_node();
  1157.         }
  1158.     }
  1159.     return $seq;
  1160. }
  1161.  
  1162. # Parse an inline value. Since YAML supports inline collections, this is
  1163. # the top level of a sub parsing.
  1164. sub _parse_inline {
  1165.     my ($top, $top_implicit, $top_explicit, $top_class) = (@_, '', '', '', '');
  1166.     $o->{inline} =~ s/^\s*(.*)\s*$/$1/;
  1167.     my ($node, $anchor, $alias, $explicit, $implicit, $class) = ('') x 6;
  1168.     ($anchor, $alias, $explicit, $implicit, $class, $o->{inline}) = 
  1169.       _parse_qualifiers($o->{inline});
  1170.     if ($anchor) {
  1171.         $o->{anchor2node}{$anchor} = CORE::bless [], 'YAML-anchor2node';
  1172.     }
  1173.     $implicit ||= $top_implicit;
  1174.     $explicit ||= $top_explicit;
  1175.     $class ||= $top_class;
  1176.     ($top_implicit, $top_explicit, $top_class) = ('', '', '');
  1177.     if ($alias) {
  1178.         croak YAML_PARSE_ERR_NO_ANCHOR($alias) 
  1179.           unless defined $o->{anchor2node}{$alias};
  1180.         if (ref($o->{anchor2node}{$alias}) ne 'YAML-anchor2node') {
  1181.             $node = $o->{anchor2node}{$alias};
  1182.         }
  1183.         else {
  1184.             $node = do {my $sv = "*$alias"};
  1185.             push @{$o->{anchor2node}{$alias}}, [\$node, $o->{line}]; 
  1186.         }
  1187.     }
  1188.     elsif ($o->{inline} =~ /^\{/) {
  1189.         $node = _parse_inline_mapping($anchor);
  1190.     }
  1191.     elsif ($o->{inline} =~ /^\[/) {
  1192.         $node = _parse_inline_seq($anchor);
  1193.     }
  1194.     elsif ($o->{inline} =~ /^"/) {
  1195.         $node = _parse_inline_double_quoted();
  1196.         $node = _unescape($node);
  1197.         $node = _parse_implicit($node) if $implicit;
  1198.     }
  1199.     elsif ($o->{inline} =~ /^'/) {
  1200.         $node = _parse_inline_single_quoted();
  1201.         $node = _parse_implicit($node) if $implicit;
  1202.     }
  1203.     else {
  1204.         if ($top) {
  1205.             $node = $o->{inline};
  1206.             $o->{inline} = '';
  1207.         }
  1208.         else {
  1209.             $node = _parse_inline_simple();
  1210.         }
  1211.         $node = _parse_implicit($node) unless $explicit;
  1212.     }
  1213.     if ($explicit) {
  1214.         if ($class) {
  1215.             if (not ref $node) {
  1216.                 my $copy = $node;
  1217.                 undef $node;
  1218.                 $node = \$copy;
  1219.             }
  1220.             CORE::bless $node, $class;
  1221.         }
  1222.         else {
  1223.             $node = _parse_explicit($node, $explicit);
  1224.         }
  1225.     }
  1226.     if ($anchor) {
  1227.         if (ref($o->{anchor2node}{$anchor}) eq 'YAML-anchor2node') {
  1228.             for my $ref (@{$o->{anchor2node}{$anchor}}) {
  1229.                 ${$ref->[0]} = $node;
  1230.                 warn YAML_LOAD_WARN_UNRESOLVED_ALIAS($anchor, $ref->[1]) if $^W;
  1231.             }
  1232.         }
  1233.         $o->{anchor2node}{$anchor} = $node;
  1234.     }
  1235.     return $node;
  1236. }
  1237.  
  1238. # Parse the inline YAML mapping into a Perl hash
  1239. sub _parse_inline_mapping {
  1240.     my ($anchor) = @_;
  1241.     my $node = {};
  1242.     $o->{anchor2node}{$anchor} = $node;
  1243.  
  1244.     croak YAML_PARSE_ERR_INLINE_MAP() unless $o->{inline} =~ s/^\{\s*//;
  1245.     while (not $o->{inline} =~ s/^\}//) {
  1246.         my $key = _parse_inline();
  1247.         croak YAML_PARSE_ERR_INLINE_MAP() unless $o->{inline} =~ s/^\: \s*//;
  1248.         my $value = _parse_inline();
  1249.         if (exists $node->{$key}) {
  1250.             warn YAML_LOAD_WARN_DUPLICATE_KEY() if $^W;
  1251.         }
  1252.         else {
  1253.             $node->{$key} = $value;
  1254.         }
  1255.         next if $o->{inline} =~ /^\}/;
  1256.         croak YAML_PARSE_ERR_INLINE_MAP() unless $o->{inline} =~ s/^\,\s*//;
  1257.     }
  1258.     return $node;
  1259. }
  1260.  
  1261. # Parse the inline YAML sequence into a Perl array
  1262. sub _parse_inline_seq {
  1263.     my ($anchor) = @_;
  1264.     my $node = [];
  1265.     $o->{anchor2node}{$anchor} = $node;
  1266.  
  1267.     croak YAML_PARSE_ERR_INLINE_SEQUENCE() unless $o->{inline} =~ s/^\[\s*//;
  1268.     while (not $o->{inline} =~ s/^\]//) {
  1269.         my $value = _parse_inline();
  1270.         push @$node, $value;
  1271.         next if $o->{inline} =~ /^\]/;
  1272.         croak YAML_PARSE_ERR_INLINE_SEQUENCE() 
  1273.           unless $o->{inline} =~ s/^\,\s*//;
  1274.     }
  1275.     return $node;
  1276. }
  1277.  
  1278. # Parse the inline double quoted string.
  1279. sub _parse_inline_double_quoted {
  1280.     my $node;
  1281.     if ($o->{inline} =~ /^"((?:\\"|[^"])*)"\s*(.*)$/) {
  1282.         $node = $1;
  1283.         $o->{inline} = $2;
  1284.         $node =~ s/\\"/"/g;
  1285.     } else {
  1286.         croak YAML_PARSE_ERR_BAD_DOUBLE();
  1287.     }
  1288.     return $node;
  1289. }
  1290.  
  1291.  
  1292. # Parse the inline single quoted string.
  1293. sub _parse_inline_single_quoted {
  1294.     my $node;
  1295.     if ($o->{inline} =~ /^'((?:''|[^'])*)'\s*(.*)$/) {
  1296.         $node = $1;
  1297.         $o->{inline} = $2;
  1298.         $node =~ s/''/'/g;
  1299.     } else {
  1300.         croak YAML_PARSE_ERR_BAD_SINGLE();
  1301.     }
  1302.     return $node;
  1303. }
  1304.  
  1305. # Parse the inline unquoted string and do implicit typing.
  1306. sub _parse_inline_simple {
  1307.     my $value;
  1308.     if ($o->{inline} =~ /^(|[^!@#%^&*].*?)(?=[,[\]{}]|: |- |:\s*$|$)/) {
  1309.         $value = $1;
  1310.         substr($o->{inline}, 0, length($1)) = '';
  1311.     }
  1312.     else {
  1313.         croak YAML_PARSE_ERR_BAD_INLINE_IMPLICIT($value);
  1314.     }
  1315.     return $value;
  1316. }
  1317.  
  1318. # Apply regex matching for YAML's implicit types. !str, !int, !real,
  1319. # !null, !date and !time
  1320. sub _parse_implicit {
  1321.     my ($value) = @_;
  1322.     $value =~ s/\s*$//;
  1323.     return $value if $value eq '';
  1324.     return $value + 0 if $value =~ /^-?\d+$/;
  1325.     return $value * 1.0
  1326.       if ($value =~ /^[+-]?(\d*)(?:\.(\d*))?([Ee][+-]?\d+)?$/) and
  1327.          (defined($3) ? defined($1) : defined($1) || defined($2));
  1328.     return "$value" if $value =~  # XXX Change this to a Time::Object
  1329.       /^\d{4}\-\d\d\-\d\d(T\d\d:\d\d:\d\d(\.\d*[1-9])?(Z|[-+]\d\d(:\d\d)?))?$/;
  1330.     return "$value" if $value =~ /^\w/;
  1331.     return undef if $value =~ /^~$/;
  1332.     return 1 if $value =~ /^\+$/;
  1333.     return 0 if $value =~ /^-$/;
  1334.     croak YAML_PARSE_ERR_BAD_IMPLICIT($value);
  1335. }
  1336.  
  1337. # Unfold a YAML multiline scalar into a single string.
  1338. sub _parse_unfold {
  1339.     my ($chomp) = @_;
  1340.     my $node = '';
  1341.     my $space = 0;
  1342.     while (not $o->{done} and $o->{indent} == $o->{offset}[$o->{level}]) {
  1343.         $node .= "$o->{content}\n";
  1344.         _parse_next_line(LEAF);
  1345.     }
  1346.     $node =~ s/^(\S.*)\n(?=\S)/$1 /gm;
  1347.     $node =~ s/^(\S.*)\n(\n+\S)/$1$2/gm;
  1348.     $node =~ s/\n*\Z// unless $chomp eq '+';
  1349.     $node .= "\n" unless $chomp;
  1350.     return $node;
  1351. }
  1352.  
  1353. # Parse a YAML block style scalar. This is like a Perl here-document.
  1354. sub _parse_block {
  1355.     my ($chomp) = @_;
  1356.     my $node = '';
  1357.     while (not $o->{done} and $o->{indent} == $o->{offset}[$o->{level}]) {
  1358.         $node .= $o->{content} . "\n";
  1359.         _parse_next_line(LEAF);
  1360.     }
  1361.     return $node if '+' eq $chomp;
  1362.     $node =~ s/\n*\Z/\n/;
  1363.     $node =~ s/\n\Z// if $chomp eq '-';
  1364.     return $node;
  1365. }
  1366.  
  1367. # Handle Perl style '#' comments. Comments must be at the same indentation
  1368. # level as the collection line following them.
  1369. sub _parse_throwaway_comments {
  1370.     while (@{$o->{lines}} and
  1371.            $o->{lines}[0] =~ m{^\s*(\#|$)}
  1372.           ) {
  1373.         shift @{$o->{lines}};
  1374.         $o->{line}++;
  1375.     }
  1376.     $o->{eos} = $o->{done} = not @{$o->{lines}};
  1377. }
  1378.  
  1379. # This is the routine that controls what line is being parsed. It gets called
  1380. # once for each line in the YAML stream.
  1381. #
  1382. # This routine must:
  1383. # 1) Skip past the current line
  1384. # 2) Determine the indentation offset for a new level
  1385. # 3) Find the next _content_ line
  1386. #   A) Skip over any throwaways (Comments/blanks)
  1387. #   B) Set $o->{indent}, $o->{content}, $o->{line}
  1388. # 4) Expand tabs appropriately  
  1389. sub _parse_next_line {
  1390.     my ($type) = @_;
  1391.     my $level = $o->{level};
  1392.     my $offset = $o->{offset}[$level];
  1393.     croak YAML_EMIT_ERR_BAD_LEVEL() unless defined $offset;
  1394.     shift @{$o->{lines}};
  1395.     $o->{eos} = $o->{done} = not @{$o->{lines}};
  1396.     return if $o->{eos};
  1397.     $o->{line}++;
  1398.  
  1399.     # Determine the offset for a new leaf node
  1400.     if ($o->{preface} =~ qr/(?:$FOLD_CHAR|$BLOCK_CHAR_RX)(?:-|\+)?(\d*)\s*$/) {
  1401.         croak YAML_PARSE_ERR_ZERO_INDENT() if length($1) and $1 == 0;
  1402.         $type = LEAF;
  1403.         if (length($1)) {
  1404.             $o->{offset}[$level + 1] = $offset + $1;
  1405.         }
  1406.         else {
  1407.             # First get rid of any comments.
  1408.             while (@{$o->{lines}} && ($o->{lines}[0] =~ /^\s*#/)) {
  1409.                 $o->{lines}[0] =~ /^( *)/ or die;
  1410.                 last unless length($1) <= $offset;
  1411.                 shift @{$o->{lines}};
  1412.                 $o->{line}++;
  1413.             }
  1414.             $o->{eos} = $o->{done} = not @{$o->{lines}};
  1415.             return if $o->{eos};
  1416.             if ($o->{lines}[0] =~ /^( *)\S/ and length($1) > $offset) {
  1417.                 $o->{offset}[$level+1] = length($1);
  1418.             }
  1419.             else {
  1420.                 $o->{offset}[$level+1] = $offset + 1;
  1421.             }
  1422.         }
  1423.         $offset = $o->{offset}[++$level];
  1424.     }
  1425.     # Determine the offset for a new collection level
  1426.     elsif ($type == COLLECTION and 
  1427.            $o->{preface} =~ /^(\s*(\!\S*|\&\S+))*\s*$/) {
  1428.         _parse_throwaway_comments();
  1429.         if ($o->{eos}) {
  1430.             $o->{offset}[$level+1] = $offset + 1;
  1431.             return;
  1432.         }
  1433.         else {
  1434.             $o->{lines}[0] =~ /^( *)\S/ or die;
  1435.             if (length($1) > $offset) {
  1436.                 $o->{offset}[$level+1] = length($1);
  1437.             }
  1438.             else {
  1439.                 $o->{offset}[$level+1] = $offset + 1;
  1440.             }
  1441.         }
  1442.         $offset = $o->{offset}[++$level];
  1443.     }
  1444.         
  1445.     if ($type == LEAF) {
  1446.         while (@{$o->{lines}} and
  1447.                $o->{lines}[0] =~ m{^( *)(\#)} and
  1448.                length($1) < $offset
  1449.               ) {
  1450.             shift @{$o->{lines}};
  1451.             $o->{line}++;
  1452.         }
  1453.         $o->{eos} = $o->{done} = not @{$o->{lines}};
  1454.     }
  1455.     else {
  1456.         _parse_throwaway_comments();
  1457.     }
  1458.     return if $o->{eos}; 
  1459.     
  1460.     if ($o->{lines}[0] =~ /^---(\s|$)/) {
  1461.         $o->{done} = 1;
  1462.         return;
  1463.     }
  1464.     if ($type == LEAF and 
  1465.         $o->{lines}[0] =~ /^ {$offset}(.*)$/
  1466.        ) {
  1467.         $o->{indent} = $offset;
  1468.         $o->{content} = $1;
  1469.     }
  1470.     elsif ($o->{lines}[0] =~ /^\s*$/) {
  1471.         $o->{indent} = $offset;
  1472.         $o->{content} = '';
  1473.     }
  1474.     else {
  1475.         $o->{lines}[0] =~ /^( *)(\S.*)$/;
  1476. # print "   indent(${\length($1)})  offsets(@{$o->{offset}}) \n";
  1477.         while ($o->{offset}[$level] > length($1)) {
  1478.             $level--;
  1479.         }
  1480.         croak YAML_PARSE_ERR_INCONSISTENT_INDENTATION() 
  1481.           if $o->{offset}[$level] != length($1);
  1482.         $o->{indent} = length($1);
  1483.         $o->{content} = $2;
  1484.     }
  1485.     croak YAML_PARSE_ERR_INDENTATION() if $o->{indent} - $offset > 1;
  1486. }
  1487.  
  1488. #==============================================================================
  1489. # Utility subroutines.
  1490. #==============================================================================
  1491.  
  1492. # Indent a scalar to the current indentation level.
  1493. sub indent {
  1494.     my ($text) = @_;
  1495.     return $text unless length $text;
  1496.     $text =~ s/\n\Z//;
  1497.     my $indent = ' ' x $o->{offset}[$o->{level}];
  1498.     $text =~ s/^/$indent/gm;
  1499.     $text = "\n$text";
  1500.     return $text;
  1501. }
  1502.  
  1503. # Fold a paragraph to fit within a certain columnar restraint.
  1504. sub fold {
  1505.     my ($text) = @_;
  1506.     my $folded = '';
  1507.     $text =~ s/^(\S.*)\n(?=\S)/$1\n\n/gm;
  1508.     while (length $text > 0) {
  1509.         if ($text =~ s/^([^\n]{0,76})(\n|\Z)//) {
  1510.             $folded .= $1;
  1511.         }
  1512.         elsif ($text =~ s/^(.{0,76})\s//) { 
  1513.             $folded .= $1;
  1514.         }
  1515.         else {
  1516.             croak "bad news" unless $text =~ s/(.*?)(\s|\Z)//;
  1517.             $folded .= $1;
  1518.         }
  1519.         $folded .= "\n";
  1520.     }
  1521.     return $folded;
  1522. }
  1523.  
  1524. # Escapes for unprintable characters
  1525. my @escapes = qw(\z   \x01 \x02 \x03 \x04 \x05 \x06 \a
  1526.                  \x08 \t   \n   \v   \f   \r   \x0e \x0f
  1527.                  \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
  1528.                  \x18 \x19 \x1a \e   \x1c \x1d \x1e \x1f
  1529.                 );
  1530.  
  1531. # Escape the unprintable characters
  1532. sub escape {
  1533.     my ($text) = @_;
  1534.     $text =~ s/\\/\\\\/g;
  1535.     $text =~ s/([\x00-\x1f])/$escapes[ord($1)]/ge;
  1536.     return $text;
  1537. }
  1538.  
  1539. # Printable characters for escapes
  1540. my %unescapes = 
  1541.   (
  1542.    z => "\x00", a => "\x07", t => "\x09",
  1543.    n => "\x0a", v => "\x0b", f => "\x0c",
  1544.    r => "\x0d", e => "\x1b", '\\' => '\\',
  1545.   );
  1546.    
  1547. # Transform all the backslash style escape characters to their literal meaning
  1548. sub _unescape {
  1549.     my ($node) = @_;
  1550.     $node =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/
  1551.               (length($1)>1)?pack("H2",$2):$unescapes{$1}/gex;
  1552.     return $node;
  1553. }
  1554.  
  1555. sub DESTROY () {}
  1556.  
  1557. sub AUTOLOAD {
  1558.     (my $autoload = $YAML::AUTOLOAD) =~ s/^YAML:://;
  1559.     if ($autoload =~ /^[A-Z]/ and 
  1560.         ref($_[0]) eq 'YAML' and
  1561.         defined $_[0]->{$autoload}
  1562.        ) {
  1563.         defined($_[1]) ? (($_[0]->{$autoload} = $_[1]), return $_[0]) 
  1564.                        : return $_[0]->{$autoload};
  1565.         return;
  1566.     }
  1567.         
  1568.     croak "Can't autoload '$YAML::AUTOLOAD'\n"
  1569.       unless $autoload =~ /^YAML_(PARSE|LOAD|DUMP|EMIT)_(ERR|WARN|USAGE)/;
  1570.     require YAML::Error;  
  1571.     $o->{error} = YAML::Error->new($autoload, $o->{line}, $o->{document}, @_);
  1572.     my $o_save = $o;
  1573.     my $dump = $o->{error}->dump;
  1574.     $o = $o_save;
  1575.     return "$dump...\n";
  1576. }
  1577.  
  1578. 1;
  1579.