ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- Dump/FilterContext.pm000064400000003217152344707050010613 0ustar00package Data::Dump::FilterContext; sub new { my($class, $obj, $oclass, $type, $ref, $pclass, $pidx, $idx) = @_; return bless { object => $obj, class => $ref && $oclass, reftype => $type, is_ref => $ref, pclass => $pclass, pidx => $pidx, idx => $idx, }, $class; } sub object_ref { my $self = shift; return $self->{object}; } sub class { my $self = shift; return $self->{class} || ""; } *is_blessed = \&class; sub reftype { my $self = shift; return $self->{reftype}; } sub is_scalar { my $self = shift; return $self->{reftype} eq "SCALAR"; } sub is_array { my $self = shift; return $self->{reftype} eq "ARRAY"; } sub is_hash { my $self = shift; return $self->{reftype} eq "HASH"; } sub is_code { my $self = shift; return $self->{reftype} eq "CODE"; } sub is_ref { my $self = shift; return $self->{is_ref}; } sub container_class { my $self = shift; return $self->{pclass} || ""; } sub container_self { my $self = shift; return "" unless $self->{pclass}; my $idx = $self->{idx}; my $pidx = $self->{pidx}; return Data::Dump::fullname("self", [@$idx[$pidx..(@$idx - 1)]]); } sub expr { my $self = shift; my $top = shift || "var"; $top =~ s/^\$//; # it's always added by fullname() my $idx = $self->{idx}; return Data::Dump::fullname($top, $idx); } sub object_isa { my($self, $class) = @_; return $self->{class} && $self->{class}->isa($class); } sub container_isa { my($self, $class) = @_; return $self->{pclass} && $self->{pclass}->isa($class); } sub depth { my $self = shift; return scalar @{$self->{idx}}; } 1; Dump/Filtered.pm000064400000012321152344707050007553 0ustar00package Data::Dump::Filtered; use Data::Dump (); use Carp (); use base 'Exporter'; our @EXPORT_OK = qw(add_dump_filter remove_dump_filter dump_filtered); sub add_dump_filter { my $filter = shift; unless (ref($filter) eq "CODE") { Carp::croak("add_dump_filter argument must be a code reference"); } push(@Data::Dump::FILTERS, $filter); return $filter; } sub remove_dump_filter { my $filter = shift; @Data::Dump::FILTERS = grep $_ ne $filter, @Data::Dump::FILTERS; } sub dump_filtered { my $filter = pop; if (defined($filter) && ref($filter) ne "CODE") { Carp::croak("Last argument to dump_filtered must be undef or a code reference"); } local @Data::Dump::FILTERS = ($filter ? $filter : ()); return &Data::Dump::dump; } 1; =head1 NAME Data::Dump::Filtered - Pretty printing with filtering =head1 DESCRIPTION The following functions are provided: =over =item add_dump_filter( \&filter ) This registers a filter function to be used by the regular Data::Dump::dump() function. By default no filters are active. Since registering filters has a global effect is might be more appropriate to use the dump_filtered() function instead. =item remove_dump_filter( \&filter ) Unregister the given callback function as filter callback. This undoes the effect of L. =item dump_filtered(..., \&filter ) Works like Data::Dump::dump(), but the last argument should be a filter callback function. As objects are visited the filter callback is invoked at it might influence how objects are dumped. Any filters registered with L are ignored when this interface is invoked. Actually, passing C as \&filter is allowed and C<< dump_filtered(..., undef) >> is the official way to force unfiltered dumps. =back =head2 Filter callback A filter callback is a function that will be invoked with 2 arguments; a context object and reference to the object currently visited. The return value should either be a hash reference or C. sub filter_callback { my($ctx, $object_ref) = @_; ... return { ... } } If the filter callback returns C (or nothing) then normal processing and formatting of the visited object happens. If the filter callback returns a hash it might replace or annotate the representation of the current object. =head2 Filter context The context object provide methods that can be used to determine what kind of object is currently visited and where it's located. The context object has the following interface: =over =item $ctx->object_ref Alternative way to obtain a reference to the current object =item $ctx->class If the object is blessed this return the class. Returns "" for objects not blessed. =item $ctx->reftype Returns what kind of object this is. It's a string like "SCALAR", "ARRAY", "HASH", "CODE",... =item $ctx->is_ref Returns true if a reference was provided. =item $ctx->is_blessed Returns true if the object is blessed. Actually, this is just an alias for C<< $ctx->class >>. =item $ctx->is_array Returns true if the object is an array =item $ctx->is_hash Returns true if the object is a hash =item $ctx->is_scalar Returns true if the object is a scalar (a string or a number) =item $ctx->is_code Returns true if the object is a function (aka subroutine) =item $ctx->container_class Returns the class of the innermost container that contains this object. Returns "" if there is no blessed container. =item $ctx->container_self Returns an textual expression relative to the container object that names this object. The variable C<$self> in this expression is the container itself. =item $ctx->object_isa( $class ) Returns TRUE if the current object is of the given class or is of a subclass. =item $ctx->container_isa( $class ) Returns TRUE if the innermost container is of the given class or is of a subclass. =item $ctx->depth Returns how many levels deep have we recursed into the structure (from the original dump_filtered() arguments). =item $ctx->expr =item $ctx->expr( $top_level_name ) Returns an textual expression that denotes the current object. In the expression C<$var> is used as the name of the top level object dumped. This can be overridden by providing a different name as argument. =back =head2 Filter return hash The following elements has significance in the returned hash: =over =item dump => $string incorporate the given string as the representation for the current value =item object => $value dump the given value instead of the one visited and passed in as $object. Basically the same as specifying C<< dump => Data::Dump::dump($value) >>. =item comment => $comment prefix the value with the given comment string =item bless => $class make it look as if the current object is of the given $class instead of the class it really has (if any). The internals of the object is dumped in the regular way. The $class can be the empty string to make Data::Dump pretend the object wasn't blessed at all. =item hide_keys => ['key1', 'key2',...] =item hide_keys => \&code If the $object is a hash dump is as normal but pretend that the listed keys did not exist. If the argument is a function then the function is called to determine if the given key should be hidden. =back =head1 SEE ALSO L Dump/Trace.pm000064400000023046152344707050007061 0ustar00package Data::Dump::Trace; $VERSION = "0.02"; # Todo: # - prototypes # in/out parameters key/value style # - exception # - wrap class # - configurable colors # - show call depth using indentation # - show nested calls sensibly # - time calls use strict; use base 'Exporter'; our @EXPORT_OK = qw(call mcall wrap autowrap trace); use Carp qw(croak); use overload (); my %obj_name; my %autowrap_class; my %name_count; sub autowrap { while (@_) { my $class = shift; my $info = shift; $info = { prefix => $info } unless ref($info); for ($info->{prefix}) { unless ($_) { $_ = lc($class); s/.*:://; } $_ = '$' . $_ unless /^\$/; } $autowrap_class{$class} = $info; } } sub wrap { my %arg = @_; my $name = $arg{name} || "func"; my $func = $arg{func}; my $proto = $arg{proto}; return sub { call($name, $func, $proto, @_); } if $func; if (my $obj = $arg{obj}) { $name = '$' . $name unless $name =~ /^\$/; $obj_name{overload::StrVal($obj)} = $name; return bless { name => $name, obj => $obj, proto => $arg{proto}, }, "Data::Dump::Trace::Wrapper"; } croak("Either the 'func' or 'obj' option must be given"); } sub trace { my($symbol, $prototype) = @_; no strict 'refs'; no warnings 'redefine'; *{$symbol} = wrap(name => $symbol, func => \&{$symbol}, proto => $prototype); } sub call { my $name = shift; my $func = shift; my $proto = shift; my $fmt = Data::Dump::Trace::Call->new($name, $proto, \@_); if (!defined wantarray) { $func->(@_); return $fmt->return_void(\@_); } elsif (wantarray) { return $fmt->return_list(\@_, $func->(@_)); } else { return $fmt->return_scalar(\@_, scalar $func->(@_)); } } sub mcall { my $o = shift; my $method = shift; my $proto = shift; return if $method eq "DESTROY" && !$o->can("DESTROY"); my $oname = ref($o) ? $obj_name{overload::StrVal($o)} || "\$o" : $o; my $fmt = Data::Dump::Trace::Call->new("$oname->$method", $proto, \@_); if (!defined wantarray) { $o->$method(@_); return $fmt->return_void(\@_); } elsif (wantarray) { return $fmt->return_list(\@_, $o->$method(@_)); } else { return $fmt->return_scalar(\@_, scalar $o->$method(@_)); } } package Data::Dump::Trace::Wrapper; sub AUTOLOAD { my $self = shift; our $AUTOLOAD; my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2); Data::Dump::Trace::mcall($self->{obj}, $method, $self->{proto}{$method}, @_); } package Data::Dump::Trace::Call; use Term::ANSIColor (); use Data::Dump (); *_dump = \&Data::Dump::dump; our %COLOR = ( name => "yellow", output => "cyan", error => "red", debug => "red", ); %COLOR = () unless -t STDOUT; sub _dumpav { return "(" . _dump(@_) . ")" if @_ == 1; return _dump(@_); } sub _dumpkv { return _dumpav(@_) if @_ % 2; my %h = @_; my $str = _dump(\%h); $str =~ s/^\{/(/ && $str =~ s/\}\z/)/; return $str; } sub new { my($class, $name, $proto, $input_args) = @_; my $self = bless { name => $name, proto => $proto, }, $class; my $proto_arg = $self->proto_arg; if ($proto_arg =~ /o/) { for (@$input_args) { push(@{$self->{input_av}}, _dump($_)); } } else { $self->{input} = $proto_arg eq "%" ? _dumpkv(@$input_args) : _dumpav(@$input_args); } return $self; } sub proto_arg { my $self = shift; my($arg, $ret) = split(/\s*=\s*/, $self->{proto} || ""); $arg ||= '@'; return $arg; } sub proto_ret { my $self = shift; my($arg, $ret) = split(/\s*=\s*/, $self->{proto} || ""); $ret ||= '@'; return $ret; } sub color { my($self, $category, $text) = @_; return $text unless $COLOR{$category}; return Term::ANSIColor::colored($text, $COLOR{$category}); } sub print_call { my $self = shift; my $outarg = shift; print $self->color("name", "$self->{name}"); if (my $input = $self->{input}) { $input = "" if $input eq "()" && $self->{name} =~ /->/; print $self->color("input", $input); } else { my $proto_arg = $self->proto_arg; print "("; my $i = 0; for (@{$self->{input_av}}) { print ", " if $i; my $proto = substr($proto_arg, 0, 1, ""); if ($proto ne "o") { print $self->color("input", $_); } if ($proto eq "o" || $proto eq "O") { print " = " if $proto eq "O"; print $self->color("output", _dump($outarg->[$i])); } } continue { $i++; } print ")"; } } sub return_void { my $self = shift; my $arg = shift; $self->print_call($arg); print "\n"; return; } sub return_scalar { my $self = shift; my $arg = shift; $self->print_call($arg); my $s = shift; my $name; my $proto_ret = $self->proto_ret; my $wrap = $autowrap_class{ref($s)}; if ($proto_ret =~ /^\$\w+\z/ && ref($s) && ref($s) !~ /^(?:ARRAY|HASH|CODE|GLOB)\z/) { $name = $proto_ret; } else { $name = $wrap->{prefix} if $wrap; } if ($name) { $name .= $name_count{$name} if $name_count{$name}++; print " = ", $self->color("output", $name), "\n"; $s = Data::Dump::Trace::wrap(name => $name, obj => $s, proto => $wrap->{proto}); } else { print " = ", $self->color("output", _dump($s)); if (!$s && $proto_ret =~ /!/ && $!) { print " ", $self->color("error", errno($!)); } print "\n"; } return $s; } sub return_list { my $self = shift; my $arg = shift; $self->print_call($arg); print " = ", $self->color("output", $self->proto_ret eq "%" ? _dumpkv(@_) : _dumpav(@_)), "\n"; return @_; } sub errno { my $t = ""; for (keys %!) { if ($!{$_}) { $t = $_; last; } } my $n = int($!); return "$t($n) $!"; } 1; __END__ =head1 NAME Data::Dump::Trace - Helpers to trace function and method calls =head1 SYNOPSIS use Data::Dump::Trace qw(autowrap mcall); autowrap("LWP::UserAgent" => "ua", "HTTP::Response" => "res"); use LWP::UserAgent; $ua = mcall(LWP::UserAgent => "new"); # instead of LWP::UserAgent->new; $ua->get("http://www.example.com")->dump; =head1 DESCRIPTION The following functions are provided: =over =item autowrap( $class ) =item autowrap( $class => $prefix ) =item autowrap( $class1 => $prefix1, $class2 => $prefix2, ... ) =item autowrap( $class1 => \%info1, $class2 => \%info2, ... ) Register classes whose objects are automatically wrapped when returned by one of the call functions below. If $prefix is provided it will be used as to name the objects. Alternative is to pass an %info hash for each class. The recognized keys are: =over =item prefix => $string The prefix string used to name objects of this type. =item proto => \%hash A hash of prototypes to use for the methods when an object is wrapped. =back =item wrap( name => $str, func => \&func, proto => $proto ) =item wrap( name => $str, obj => $obj, proto => \%hash ) Returns a wrapped function or object. When a wrapped function is invoked then a trace is printed after the underlying function has returned. When a method on a wrapped object is invoked then a trace is printed after the methods on the underlying objects has returned. See L for description of the C argument. =item call( $name, \&func, $proto, @ARGS ) Calls the given function with the given arguments. The trace will use $name as the name of the function. See L for description of the $proto argument. =item mcall( $class, $method, $proto, @ARGS ) =item mcall( $object, $method, $proto, @ARGS ) Calls the given method with the given arguments. See L for description of the $proto argument. =item trace( $symbol, $prototype ) Replaces the function given by $symbol with a wrapped function. =back =head2 Prototypes B. The $proto argument to call() and mcall() can optionally provide a prototype for the function call. This give the tracer hints about how to best format the argument lists and if there are I or I arguments. The general form for the prototype string is: = The default prototype is "@ = @"; list of values as input and list of values as output. The value '%' can be used for both arguments and return value to say that key/value pair style lists are used. Alternatively, individual positional arguments can be listed each represented by a letter: =over =item C input argument =item C output argument =item C both input and output argument =back If the return value prototype has C appended, then it signals that this function sets errno ($!) when it returns a false value. The trace will display the current value of errno in that case. If the return value prototype looks like a variable name (with C<$> prefix), and the function returns a blessed object, then the variable name will be used as prefix and the returned object automatically traced. =head1 SEE ALSO L =head1 AUTHOR Copyright 2009 Gisle Aas. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Dump.pm000064400000043633152344707050006027 0ustar00package Data::Dump; use strict; use vars qw(@EXPORT @EXPORT_OK $VERSION $DEBUG); use subs qq(dump); require Exporter; *import = \&Exporter::import; @EXPORT = qw(dd ddx); @EXPORT_OK = qw(dump pp dumpf quote); $VERSION = "1.23"; $DEBUG = 0; use overload (); use vars qw(%seen %refcnt @dump @fixup %require $TRY_BASE64 @FILTERS $INDENT); $TRY_BASE64 = 50 unless defined $TRY_BASE64; $INDENT = " " unless defined $INDENT; sub dump { local %seen; local %refcnt; local %require; local @fixup; require Data::Dump::FilterContext if @FILTERS; my $name = "a"; my @dump; for my $v (@_) { my $val = _dump($v, $name, [], tied($v)); push(@dump, [$name, $val]); } continue { $name++; } my $out = ""; if (%require) { for (sort keys %require) { $out .= "require $_;\n"; } } if (%refcnt) { # output all those with refcounts first for (@dump) { my $name = $_->[0]; if ($refcnt{$name}) { $out .= "my \$$name = $_->[1];\n"; undef $_->[1]; } } for (@fixup) { $out .= "$_;\n"; } } my $paren = (@dump != 1); $out .= "(" if $paren; $out .= format_list($paren, undef, map {defined($_->[1]) ? $_->[1] : "\$".$_->[0]} @dump ); $out .= ")" if $paren; if (%refcnt || %require) { $out .= ";\n"; $out =~ s/^/$INDENT/gm; $out = "do {\n$out}"; } print STDERR "$out\n" unless defined wantarray; $out; } *pp = \&dump; sub dd { print dump(@_), "\n"; } sub ddx { my(undef, $file, $line) = caller; $file =~ s,.*[\\/],,; my $out = "$file:$line: " . dump(@_) . "\n"; $out =~ s/^/# /gm; print $out; } sub dumpf { require Data::Dump::Filtered; goto &Data::Dump::Filtered::dump_filtered; } sub _dump { my $ref = ref $_[0]; my $rval = $ref ? $_[0] : \$_[0]; shift; my($name, $idx, $dont_remember, $pclass, $pidx) = @_; my($class, $type, $id); my $strval = overload::StrVal($rval); # Parse $strval without using regexps, in order not to clobber $1, $2,... if ((my $i = rindex($strval, "=")) >= 0) { $class = substr($strval, 0, $i); $strval = substr($strval, $i+1); } if ((my $i = index($strval, "(0x")) >= 0) { $type = substr($strval, 0, $i); $id = substr($strval, $i + 2, -1); } else { die "Can't parse " . overload::StrVal($rval); } if ($] < 5.008 && $type eq "SCALAR") { $type = "REF" if $ref eq "REF"; } warn "\$$name(@$idx) $class $type $id ($ref)" if $DEBUG; my $out; my $comment; my $hide_keys; if (@FILTERS) { my $pself = ""; $pself = fullname("self", [@$idx[$pidx..(@$idx - 1)]]) if $pclass; my $ctx = Data::Dump::FilterContext->new($rval, $class, $type, $ref, $pclass, $pidx, $idx); my @bless; for my $filter (@FILTERS) { if (my $f = $filter->($ctx, $rval)) { if (my $v = $f->{object}) { local @FILTERS; $out = _dump($v, $name, $idx, 1); $dont_remember++; } if (defined(my $c = $f->{bless})) { push(@bless, $c); } if (my $c = $f->{comment}) { $comment = $c; } if (defined(my $c = $f->{dump})) { $out = $c; $dont_remember++; } if (my $h = $f->{hide_keys}) { if (ref($h) eq "ARRAY") { $hide_keys = sub { for my $k (@$h) { return 1 if $k eq $_[0]; } return 0; }; } } } } push(@bless, "") if defined($out) && !@bless; if (@bless) { $class = shift(@bless); warn "More than one filter callback tried to bless object" if @bless; } } unless ($dont_remember) { if (my $s = $seen{$id}) { my($sname, $sidx) = @$s; $refcnt{$sname}++; my $sref = fullname($sname, $sidx, ($ref && $type eq "SCALAR")); warn "SEEN: [\$$name(@$idx)] => [\$$sname(@$sidx)] ($ref,$sref)" if $DEBUG; return $sref unless $sname eq $name; $refcnt{$name}++; push(@fixup, fullname($name,$idx)." = $sref"); return "do{my \$fix}" if @$idx && $idx->[-1] eq '$'; return "'fix'"; } $seen{$id} = [$name, $idx]; } if ($class) { $pclass = $class; $pidx = @$idx; } if (defined $out) { # keep it } elsif ($type eq "SCALAR" || $type eq "REF" || $type eq "REGEXP") { if ($ref) { if ($class && $class eq "Regexp") { my $v = "$rval"; my $mod = ""; if ($v =~ /^\(\?\^?([msix-]*):([\x00-\xFF]*)\)\z/) { $mod = $1; $v = $2; $mod =~ s/-.*//; } my $sep = '/'; my $sep_count = ($v =~ tr/\///); if ($sep_count) { # see if we can find a better one for ('|', ',', ':', '#') { my $c = eval "\$v =~ tr/\Q$_\E//"; #print "SEP $_ $c $sep_count\n"; if ($c < $sep_count) { $sep = $_; $sep_count = $c; last if $sep_count == 0; } } } $v =~ s/\Q$sep\E/\\$sep/g; $out = "qr$sep$v$sep$mod"; undef($class); } else { delete $seen{$id} if $type eq "SCALAR"; # will be seen again shortly my $val = _dump($$rval, $name, [@$idx, "\$"], 0, $pclass, $pidx); $out = $class ? "do{\\(my \$o = $val)}" : "\\$val"; } } else { if (!defined $$rval) { $out = "undef"; } elsif (do {no warnings 'numeric'; $$rval + 0 eq $$rval}) { $out = $$rval; } else { $out = str($$rval); } if ($class && !@$idx) { # Top is an object, not a reference to one as perl needs $refcnt{$name}++; my $obj = fullname($name, $idx); my $cl = quote($class); push(@fixup, "bless \\$obj, $cl"); } } } elsif ($type eq "GLOB") { if ($ref) { delete $seen{$id}; my $val = _dump($$rval, $name, [@$idx, "*"], 0, $pclass, $pidx); $out = "\\$val"; if ($out =~ /^\\\*Symbol::/) { $require{Symbol}++; $out = "Symbol::gensym()"; } } else { my $val = "$$rval"; $out = "$$rval"; for my $k (qw(SCALAR ARRAY HASH)) { my $gval = *$$rval{$k}; next unless defined $gval; next if $k eq "SCALAR" && ! defined $$gval; # always there my $f = scalar @fixup; push(@fixup, "RESERVED"); # overwritten after _dump() below $gval = _dump($gval, $name, [@$idx, "*{$k}"], 0, $pclass, $pidx); $refcnt{$name}++; my $gname = fullname($name, $idx); $fixup[$f] = "$gname = $gval"; #XXX indent $gval } } } elsif ($type eq "ARRAY") { my @vals; my $tied = tied_str(tied(@$rval)); my $i = 0; for my $v (@$rval) { push(@vals, _dump($v, $name, [@$idx, "[$i]"], $tied, $pclass, $pidx)); $i++; } $out = "[" . format_list(1, $tied, @vals) . "]"; } elsif ($type eq "HASH") { my(@keys, @vals); my $tied = tied_str(tied(%$rval)); # statistics to determine variation in key lengths my $kstat_max = 0; my $kstat_sum = 0; my $kstat_sum2 = 0; my @orig_keys = keys %$rval; if ($hide_keys) { @orig_keys = grep !$hide_keys->($_), @orig_keys; } my $text_keys = 0; for (@orig_keys) { $text_keys++, last unless /^[-+]?(?:0|[1-9]\d*)(?:\.\d+)?\z/; } if ($text_keys) { @orig_keys = sort { lc($a) cmp lc($b) } @orig_keys; } else { @orig_keys = sort { $a <=> $b } @orig_keys; } my $quote; for my $key (@orig_keys) { next if $key =~ /^-?[a-zA-Z_]\w*\z/; next if $key =~ /^-?[1-9]\d{0,8}\z/; $quote++; last; } for my $key (@orig_keys) { my $val = \$rval->{$key}; # capture value before we modify $key $key = quote($key) if $quote; $kstat_max = length($key) if length($key) > $kstat_max; $kstat_sum += length($key); $kstat_sum2 += length($key)*length($key); push(@keys, $key); push(@vals, _dump($$val, $name, [@$idx, "{$key}"], $tied, $pclass, $pidx)); } my $nl = ""; my $klen_pad = 0; my $tmp = "@keys @vals"; if (length($tmp) > 60 || $tmp =~ /\n/ || $tied) { $nl = "\n"; # Determine what padding to add if ($kstat_max < 4) { $klen_pad = $kstat_max; } elsif (@keys >= 2) { my $n = @keys; my $avg = $kstat_sum/$n; my $stddev = sqrt(($kstat_sum2 - $n * $avg * $avg) / ($n - 1)); # I am not actually very happy with this heuristics if ($stddev / $kstat_max < 0.25) { $klen_pad = $kstat_max; } if ($DEBUG) { push(@keys, "__S"); push(@vals, sprintf("%.2f (%d/%.1f/%.1f)", $stddev / $kstat_max, $kstat_max, $avg, $stddev)); } } } $out = "{$nl"; $out .= "$INDENT# $tied$nl" if $tied; while (@keys) { my $key = shift @keys; my $val = shift @vals; my $vpad = $INDENT . (" " x ($klen_pad ? $klen_pad + 4 : 0)); $val =~ s/\n/\n$vpad/gm; my $kpad = $nl ? $INDENT : " "; $key .= " " x ($klen_pad - length($key)) if $nl && $klen_pad > length($key); $out .= "$kpad$key => $val,$nl"; } $out =~ s/,$/ / unless $nl; $out .= "}"; } elsif ($type eq "CODE") { $out = 'sub { ... }'; } elsif ($type eq "VSTRING") { $out = sprintf +($ref ? '\v%vd' : 'v%vd'), $$rval; } else { warn "Can't handle $type data"; $out = "'#$type#'"; } if ($class && $ref) { $out = "bless($out, " . quote($class) . ")"; } if ($comment) { $comment =~ s/^/# /gm; $comment .= "\n" unless $comment =~ /\n\z/; $comment =~ s/^#[ \t]+\n/\n/; $out = "$comment$out"; } return $out; } sub tied_str { my $tied = shift; if ($tied) { if (my $tied_ref = ref($tied)) { $tied = "tied $tied_ref"; } else { $tied = "tied"; } } return $tied; } sub fullname { my($name, $idx, $ref) = @_; substr($name, 0, 0) = "\$"; my @i = @$idx; # need copy in order to not modify @$idx if ($ref && @i && $i[0] eq "\$") { shift(@i); # remove one deref $ref = 0; } while (@i && $i[0] eq "\$") { shift @i; $name = "\$$name"; } my $last_was_index; for my $i (@i) { if ($i eq "*" || $i eq "\$") { $last_was_index = 0; $name = "$i\{$name}"; } elsif ($i =~ s/^\*//) { $name .= $i; $last_was_index++; } else { $name .= "->" unless $last_was_index++; $name .= $i; } } $name = "\\$name" if $ref; $name; } sub format_list { my $paren = shift; my $comment = shift; my $indent_lim = $paren ? 0 : 1; if (@_ > 3) { # can we use range operator to shorten the list? my $i = 0; while ($i < @_) { my $j = $i + 1; my $v = $_[$i]; while ($j < @_) { # XXX allow string increment too? if ($v eq "0" || $v =~ /^-?[1-9]\d{0,9}\z/) { $v++; } elsif ($v =~ /^"([A-Za-z]{1,3}\d*)"\z/) { $v = $1; $v++; $v = qq("$v"); } else { last; } last if $_[$j] ne $v; $j++; } if ($j - $i > 3) { splice(@_, $i, $j - $i, "$_[$i] .. $_[$j-1]"); } $i++; } } my $tmp = "@_"; if ($comment || (@_ > $indent_lim && (length($tmp) > 60 || $tmp =~ /\n/))) { my @elem = @_; for (@elem) { s/^/$INDENT/gm; } return "\n" . ($comment ? "$INDENT# $comment\n" : "") . join(",\n", @elem, ""); } else { return join(", ", @_); } } sub str { if (length($_[0]) > 20) { for ($_[0]) { # Check for repeated string if (/^(.)\1\1\1/s) { # seems to be a repeating sequence, let's check if it really is # without backtracking unless (/[^\Q$1\E]/) { my $base = quote($1); my $repeat = length; return "($base x $repeat)" } } # Length protection because the RE engine will blow the stack [RT#33520] if (length($_) < 16 * 1024 && /^(.{2,5}?)\1*\z/s) { my $base = quote($1); my $repeat = length($_)/length($1); return "($base x $repeat)"; } } } local $_ = "e; if (length($_) > 40 && !/\\x\{/ && length($_) > (length($_[0]) * 2)) { # too much binary data, better to represent as a hex/base64 string # Base64 is more compact than hex when string is longer than # 17 bytes (not counting any require statement needed). # But on the other hand, hex is much more readable. if ($TRY_BASE64 && length($_[0]) > $TRY_BASE64 && (defined &utf8::is_utf8 && !utf8::is_utf8($_[0])) && eval { require MIME::Base64 }) { $require{"MIME::Base64"}++; return "MIME::Base64::decode(\"" . MIME::Base64::encode($_[0],"") . "\")"; } return "pack(\"H*\",\"" . unpack("H*", $_[0]) . "\")"; } return $_; } my %esc = ( "\a" => "\\a", "\b" => "\\b", "\t" => "\\t", "\n" => "\\n", "\f" => "\\f", "\r" => "\\r", "\e" => "\\e", ); # put a string value in double quotes sub quote { local($_) = $_[0]; # If there are many '"' we might want to use qq() instead s/([\\\"\@\$])/\\$1/g; return qq("$_") unless /[^\040-\176]/; # fast exit s/([\a\b\t\n\f\r\e])/$esc{$1}/g; # no need for 3 digits in escape for these s/([\0-\037])(?!\d)/sprintf('\\%o',ord($1))/eg; s/([\0-\037\177-\377])/sprintf('\\x%02X',ord($1))/eg; s/([^\040-\176])/sprintf('\\x{%X}',ord($1))/eg; return qq("$_"); } 1; __END__ =head1 NAME Data::Dump - Pretty printing of data structures =head1 SYNOPSIS use Data::Dump qw(dump); $str = dump(@list); @copy_of_list = eval $str; # or use it for easy debug printout use Data::Dump; dd localtime; =head1 DESCRIPTION This module provide a few functions that traverse their argument and produces a string as its result. The string contains Perl code that, when Ced, produces a deep copy of the original arguments. The main feature of the module is that it strives to produce output that is easy to read. Example: @a = (1, [2, 3], {4 => 5}); dump(@a); Produces: "(1, [2, 3], { 4 => 5 })" If you dump just a little data, it is output on a single line. If you dump data that is more complex or there is a lot of it, line breaks are automatically added to keep it easy to read. The following functions are provided (only the dd* functions are exported by default): =over =item dump( ... ) =item pp( ... ) Returns a string containing a Perl expression. If you pass this string to Perl's built-in eval() function it should return a copy of the arguments you passed to dump(). If you call the function with multiple arguments then the output will be wrapped in parenthesis "( ..., ... )". If you call the function with a single argument the output will not have the wrapping. If you call the function with a single scalar (non-reference) argument it will just return the scalar quoted if needed, but never break it into multiple lines. If you pass multiple arguments or references to arrays of hashes then the return value might contain line breaks to format it for easier reading. The returned string will never be "\n" terminated, even if contains multiple lines. This allows code like this to place the semicolon in the expected place: print '$obj = ', dump($obj), ";\n"; If dump() is called in void context, then the dump is printed on STDERR and then "\n" terminated. You might find this useful for quick debug printouts, but the dd*() functions might be better alternatives for this. There is no difference between dump() and pp(), except that dump() shares its name with a not-so-useful perl builtin. Because of this some might want to avoid using that name. =item quote( $string ) Returns a quoted version of the provided string. It differs from C in that it will quote even numbers and not try to come up with clever expressions that might shorten the output. If a non-scalar argument is provided then it's just stringified instead of traversed. =item dd( ... ) =item ddx( ... ) These functions will call dump() on their argument and print the result to STDOUT (actually, it's the currently selected output handle, but STDOUT is the default for that). The difference between them is only that ddx() will prefix the lines it prints with "# " and mark the first line with the file and line number where it was called. This is meant to be useful for debug printouts of state within programs. =item dumpf( ..., \&filter ) Short hand for calling the dump_filtered() function of L. This works like dump(), but the last argument should be a filter callback function. As objects are visited the filter callback is invoked and it can modify how the objects are dumped. =back =head1 CONFIGURATION There are a few global variables that can be set to modify the output generated by the dump functions. It's wise to localize the setting of these. =over =item $Data::Dump::INDENT This holds the string that's used for indenting multiline data structures. It's default value is " " (two spaces). Set it to "" to suppress indentation. Setting it to "| " makes for nice visuals even if the dump output then fails to be valid Perl. =item $Data::Dump::TRY_BASE64 How long must a binary string be before we try to use the base64 encoding for the dump output. The default is 50. Set it to 0 to disable base64 dumps. =back =head1 LIMITATIONS Code references will be dumped as C<< sub { ... } >>. Thus, Cing them will not reproduce the original routine. The C<...>-operator used will also require perl-5.12 or better to be evaled. If you forget to explicitly import the C function, your code will core dump. That's because you just called the builtin C function by accident, which intentionally dumps core. Because of this you can also import the same function as C, mnemonic for "pretty-print". =head1 HISTORY The C module grew out of frustration with Sarathy's in-most-cases-excellent C. Basic ideas and some code are shared with Sarathy's module. The C module provides a much simpler interface than C. No OO interface is available and there are fewer configuration options to worry about. The other benefit is that the dump produced does not try to set any variables. It only returns what is needed to produce a copy of the arguments. This means that C simply returns C<'"foo"'>, and C simply returns C<'(1, 2, 3)'>. =head1 SEE ALSO L, L, L, L, L =head1 AUTHORS The C module is written by Gisle Aas , based on C by Gurusamy Sarathy . Copyright 1998-2010 Gisle Aas. Copyright 1996-1998 Gurusamy Sarathy. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Section.pm000064400000042070152344707050006520 0ustar00use strict; use warnings; package Data::Section; # ABSTRACT: read multiple hunks of data out of your DATA section $Data::Section::VERSION = '0.200007'; use Encode qw/decode/; use MRO::Compat 0.09; use Sub::Exporter 0.979 -setup => { groups => { setup => \'_mk_reader_group' }, collectors => { INIT => sub { $_[0] = { into => $_[1]->{into} } } }, }; #pod =head1 SYNOPSIS #pod #pod package Letter::Resignation; #pod use Data::Section -setup; #pod #pod sub quit { #pod my ($class, $angry, %arg) = @_; #pod #pod my $template = $self->section_data( #pod ($angry ? "angry_" : "professional_") . "letter" #pod ); #pod #pod return fill_in($$template, \%arg); #pod } #pod #pod __DATA__ #pod __[ angry_letter ]__ #pod Dear jerks, #pod #pod I quit! #pod #pod -- #pod {{ $name }} #pod __[ professional_letter ]__ #pod Dear {{ $boss }}, #pod #pod I quit, jerks! #pod #pod #pod -- #pod {{ $name }} #pod #pod =head1 DESCRIPTION #pod #pod Data::Section provides an easy way to access multiple named chunks of #pod line-oriented data in your module's DATA section. It was written to allow #pod modules to store their own templates, but probably has other uses. #pod #pod =head1 WARNING #pod #pod You will need to use C<__DATA__> sections and not C<__END__> sections. Yes, it #pod matters. Who knew! #pod #pod =head1 EXPORTS #pod #pod To get the methods exported by Data::Section, you must import like this: #pod #pod use Data::Section -setup; #pod #pod Optional arguments may be given to Data::Section like this: #pod #pod use Data::Section -setup => { ... }; #pod #pod Valid arguments are: #pod #pod encoding - if given, gives the encoding needed to decode bytes in #pod data sections; default; UTF-8 #pod #pod the special value "bytes" will leave the bytes in the string #pod verbatim #pod #pod inherit - if true, allow packages to inherit the data of the packages #pod from which they inherit; default: true #pod #pod header_re - if given, changes the regex used to find section headers #pod in the data section; it should leave the section name in $1 #pod #pod default_name - if given, allows the first section to has no header and set #pod its name #pod #pod Three methods are exported by Data::Section: #pod #pod =head2 section_data #pod #pod my $string_ref = $pkg->section_data($name); #pod #pod This method returns a reference to a string containing the data from the name #pod section, either in the invocant's C section or in that of one of its #pod ancestors. (The ancestor must also derive from the class that imported #pod Data::Section.) #pod #pod By default, named sections are delimited by lines that look like this: #pod #pod __[ name ]__ #pod #pod You can use as many underscores as you want, and the space around the name is #pod optional. This pattern can be configured with the C option (see #pod above). If present, a single leading C<\> is removed, so that sections can #pod encode lines that look like section delimiters. #pod #pod When a line containing only C<__END__> is reached, all processing of sections #pod ends. #pod #pod =head2 section_data_names #pod #pod my @names = $pkg->section_data_names; #pod #pod This returns a list of all the names that will be recognized by the #pod C method. #pod #pod =head2 merged_section_data #pod #pod my $data = $pkg->merged_section_data; #pod #pod This method returns a hashref containing all the data extracted from the #pod package data for all the classes from which the invocant inherits -- as long as #pod those classes also inherit from the package into which Data::Section was #pod imported. #pod #pod In other words, given this inheritance tree: #pod #pod A #pod \ #pod B C #pod \ / #pod D #pod #pod ...if Data::Section was imported by A, then when D's C is #pod invoked, C's data section will not be considered. (This prevents the read #pod position of C's data handle from being altered unexpectedly.) #pod #pod The keys in the returned hashref are the section names, and the values are #pod B the strings extracted from the data sections. #pod #pod =head2 merged_section_data_names #pod #pod my @names = $pkg->merged_section_data_names; #pod #pod This returns a list of all the names that will be recognized by the #pod C method. #pod #pod =head2 local_section_data #pod #pod my $data = $pkg->local_section_data; #pod #pod This method returns a hashref containing all the data extracted from the #pod package on which the method was invoked. If called on an object, it will #pod operate on the package into which the object was blessed. #pod #pod This method needs to be used carefully, because it's weird. It returns only #pod the data for the package on which it was invoked. If the package on which it #pod was invoked has no data sections, it returns an empty hashref. #pod #pod =head2 local_section_data_names #pod #pod my @names = $pkg->local_section_data_names; #pod #pod This returns a list of all the names that will be recognized by the #pod C method. #pod #pod =cut sub _mk_reader_group { my ($mixin, $name, $arg, $col) = @_; my $base = $col->{INIT}{into}; my $default_header_re = qr/ \A # start _+\[ # __[ \s* # any whitespace ([^\]]+?) # this is the actual name of the section \s* # any whitespace \]_+ # ]__ [\x0d\x0a]{1,2} # possible cariage return for windows files \z # end /x; my $header_re = $arg->{header_re} || $default_header_re; $arg->{inherit} = 1 unless exists $arg->{inherit}; my $default_encoding = defined $arg->{encoding} ? $arg->{encoding} : 'UTF-8'; my %export; my %stash = (); $export{local_section_data} = sub { my ($self) = @_; my $pkg = ref $self ? ref $self : $self; return $stash{ $pkg } if $stash{ $pkg }; my $template = $stash{ $pkg } = { }; my $dh = do { no strict 'refs'; \*{"$pkg\::DATA"} }; ## no critic Strict return $stash{ $pkg } unless defined fileno *$dh; binmode( $dh, ":raw :bytes" ); my ($current, $current_line); if ($arg->{default_name}) { $current = $arg->{default_name}; $template->{ $current } = \(my $blank = q{}); } LINE: while (my $line = <$dh>) { if ($line =~ $header_re) { $current = $1; $current_line = 0; $template->{ $current } = \(my $blank = q{}); next LINE; } last LINE if $line =~ /^__END__/; next LINE if !defined $current and $line =~ /^\s*$/; Carp::confess("bogus data section: text outside of named section") unless defined $current; $current_line++; unless ($default_encoding eq 'bytes') { my $decoded_line = eval { decode($default_encoding, $line, Encode::FB_CROAK) } or warn "Invalid character encoding in $current, line $current_line\n"; $line = $decoded_line if defined $decoded_line; } $line =~ s/\A\\//; ${$template->{$current}} .= $line; } return $stash{ $pkg }; }; $export{local_section_data_names} = sub { my ($self) = @_; my $method = $export{local_section_data}; return keys %{ $self->$method }; }; $export{merged_section_data} = !$arg->{inherit} ? $export{local_section_data} : sub { my ($self) = @_; my $pkg = ref $self ? ref $self : $self; my $lsd = $export{local_section_data}; my %merged; for my $class (@{ mro::get_linear_isa($pkg) }) { # in case of c3 + non-$base item showing up next unless $class->isa($base); my $sec_data = $class->$lsd; # checking for truth is okay, since things must be undef or a ref # -- rjbs, 2008-06-06 $merged{ $_ } ||= $sec_data->{$_} for keys %$sec_data; } return \%merged; }; $export{merged_section_data_names} = sub { my ($self) = @_; my $method = $export{merged_section_data}; return keys %{ $self->$method }; }; $export{section_data} = sub { my ($self, $name) = @_; my $pkg = ref $self ? ref $self : $self; my $prefix = $arg->{inherit} ? 'merged' : 'local'; my $method = "$prefix\_section_data"; my $data = $self->$method; return $data->{ $name }; }; $export{section_data_names} = sub { my ($self) = @_; my $prefix = $arg->{inherit} ? 'merged' : 'local'; my $method = "$prefix\_section_data_names"; return $self->$method; }; return \%export; } #pod =head1 TIPS AND TRICKS #pod #pod =head2 MooseX::Declare and namespace::autoclean #pod #pod The L library automatically cleans #pod foreign routines from a class, including those imported by Data::Section. #pod #pod L does the same thing, and can also cause your #pod C<__DATA__> section to appear outside your class's package. #pod #pod These are easy to address. The #pod L library provides an #pod installer that will cause installed methods to appear to come from the class #pod and avoid autocleaning. Using an explicit C statement will keep the #pod data section in the correct package. #pod #pod package Foo; #pod #pod use MooseX::Declare; #pod class Foo { #pod #pod # Utility to tell Sub::Exporter modules to export methods. #pod use Sub::Exporter::ForMethods qw( method_installer ); #pod #pod # method_installer returns a sub. #pod use Data::Section { installer => method_installer }, -setup; #pod #pod method my_method { #pod my $content_ref = $self->section_data('SectionA'); #pod #pod print $$content_ref; #pod } #pod } #pod #pod __DATA__ #pod __[ SectionA ]__ #pod Hello, world. #pod #pod =head1 SEE ALSO #pod #pod =begin :list #pod #pod * L
#pod #pod * L does something that is at first look similar, #pod but it works with source filters, and contains the warning: #pod #pod It is possible that this module may overwrite the source code in files that #pod use it. To protect yourself against this possibility, you are strongly #pod advised to use the -backup option described in "Safety first". #pod #pod Enough said. #pod #pod =end :list #pod #pod =cut 1; __END__ =pod =encoding UTF-8 =head1 NAME Data::Section - read multiple hunks of data out of your DATA section =head1 VERSION version 0.200007 =head1 SYNOPSIS package Letter::Resignation; use Data::Section -setup; sub quit { my ($class, $angry, %arg) = @_; my $template = $self->section_data( ($angry ? "angry_" : "professional_") . "letter" ); return fill_in($$template, \%arg); } __DATA__ __[ angry_letter ]__ Dear jerks, I quit! -- {{ $name }} __[ professional_letter ]__ Dear {{ $boss }}, I quit, jerks! -- {{ $name }} =head1 DESCRIPTION Data::Section provides an easy way to access multiple named chunks of line-oriented data in your module's DATA section. It was written to allow modules to store their own templates, but probably has other uses. =head1 WARNING You will need to use C<__DATA__> sections and not C<__END__> sections. Yes, it matters. Who knew! =head1 EXPORTS To get the methods exported by Data::Section, you must import like this: use Data::Section -setup; Optional arguments may be given to Data::Section like this: use Data::Section -setup => { ... }; Valid arguments are: encoding - if given, gives the encoding needed to decode bytes in data sections; default; UTF-8 the special value "bytes" will leave the bytes in the string verbatim inherit - if true, allow packages to inherit the data of the packages from which they inherit; default: true header_re - if given, changes the regex used to find section headers in the data section; it should leave the section name in $1 default_name - if given, allows the first section to has no header and set its name Three methods are exported by Data::Section: =head2 section_data my $string_ref = $pkg->section_data($name); This method returns a reference to a string containing the data from the name section, either in the invocant's C section or in that of one of its ancestors. (The ancestor must also derive from the class that imported Data::Section.) By default, named sections are delimited by lines that look like this: __[ name ]__ You can use as many underscores as you want, and the space around the name is optional. This pattern can be configured with the C option (see above). If present, a single leading C<\> is removed, so that sections can encode lines that look like section delimiters. When a line containing only C<__END__> is reached, all processing of sections ends. =head2 section_data_names my @names = $pkg->section_data_names; This returns a list of all the names that will be recognized by the C method. =head2 merged_section_data my $data = $pkg->merged_section_data; This method returns a hashref containing all the data extracted from the package data for all the classes from which the invocant inherits -- as long as those classes also inherit from the package into which Data::Section was imported. In other words, given this inheritance tree: A \ B C \ / D ...if Data::Section was imported by A, then when D's C is invoked, C's data section will not be considered. (This prevents the read position of C's data handle from being altered unexpectedly.) The keys in the returned hashref are the section names, and the values are B the strings extracted from the data sections. =head2 merged_section_data_names my @names = $pkg->merged_section_data_names; This returns a list of all the names that will be recognized by the C method. =head2 local_section_data my $data = $pkg->local_section_data; This method returns a hashref containing all the data extracted from the package on which the method was invoked. If called on an object, it will operate on the package into which the object was blessed. This method needs to be used carefully, because it's weird. It returns only the data for the package on which it was invoked. If the package on which it was invoked has no data sections, it returns an empty hashref. =head2 local_section_data_names my @names = $pkg->local_section_data_names; This returns a list of all the names that will be recognized by the C method. =head1 TIPS AND TRICKS =head2 MooseX::Declare and namespace::autoclean The L library automatically cleans foreign routines from a class, including those imported by Data::Section. L does the same thing, and can also cause your C<__DATA__> section to appear outside your class's package. These are easy to address. The L library provides an installer that will cause installed methods to appear to come from the class and avoid autocleaning. Using an explicit C statement will keep the data section in the correct package. package Foo; use MooseX::Declare; class Foo { # Utility to tell Sub::Exporter modules to export methods. use Sub::Exporter::ForMethods qw( method_installer ); # method_installer returns a sub. use Data::Section { installer => method_installer }, -setup; method my_method { my $content_ref = $self->section_data('SectionA'); print $$content_ref; } } __DATA__ __[ SectionA ]__ Hello, world. =head1 SEE ALSO =over 4 =item * L
=item * L does something that is at first look similar, but it works with source filters, and contains the warning: It is possible that this module may overwrite the source code in files that use it. To protect yourself against this possibility, you are strongly advised to use the -backup option described in "Safety first". Enough said. =back =head1 AUTHOR Ricardo SIGNES =head1 CONTRIBUTORS =for stopwords Christian Walde Dan Kogai David Golden Steinbrunner Karen Etheridge Kenichi Ishigaki kentfredric Tatsuhiko Miyagawa =over 4 =item * Christian Walde =item * Dan Kogai =item * David Golden =item * David Steinbrunner =item * Karen Etheridge =item * Kenichi Ishigaki =item * kentfredric =item * Tatsuhiko Miyagawa =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2008 by Ricardo SIGNES. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut OptList.pm000064400000026672152344707050006524 0ustar00use strict; use warnings; package Data::OptList; # ABSTRACT: parse and validate simple name/value option pairs $Data::OptList::VERSION = '0.110'; use List::Util (); use Params::Util (); use Sub::Install 0.921 (); #pod =head1 SYNOPSIS #pod #pod use Data::OptList; #pod #pod my $options = Data::OptList::mkopt([ #pod qw(key1 key2 key3 key4), #pod key5 => { ... }, #pod key6 => [ ... ], #pod key7 => sub { ... }, #pod key8 => { ... }, #pod key8 => [ ... ], #pod ]); #pod #pod ...is the same thing, more or less, as: #pod #pod my $options = [ #pod [ key1 => undef, ], #pod [ key2 => undef, ], #pod [ key3 => undef, ], #pod [ key4 => undef, ], #pod [ key5 => { ... }, ], #pod [ key6 => [ ... ], ], #pod [ key7 => sub { ... }, ], #pod [ key8 => { ... }, ], #pod [ key8 => [ ... ], ], #pod ]); #pod #pod =head1 DESCRIPTION #pod #pod Hashes are great for storing named data, but if you want more than one entry #pod for a name, you have to use a list of pairs. Even then, this is really boring #pod to write: #pod #pod $values = [ #pod foo => undef, #pod bar => undef, #pod baz => undef, #pod xyz => { ... }, #pod ]; #pod #pod Just look at all those undefs! Don't worry, we can get rid of those: #pod #pod $values = [ #pod map { $_ => undef } qw(foo bar baz), #pod xyz => { ... }, #pod ]; #pod #pod Aaaauuugh! We've saved a little typing, but now it requires thought to read, #pod and thinking is even worse than typing... and it's got a bug! It looked right, #pod didn't it? Well, the C<< xyz => { ... } >> gets consumed by the map, and we #pod don't get the data we wanted. #pod #pod With Data::OptList, you can do this instead: #pod #pod $values = Data::OptList::mkopt([ #pod qw(foo bar baz), #pod xyz => { ... }, #pod ]); #pod #pod This works by assuming that any defined scalar is a name and any reference #pod following a name is its value. #pod #pod =func mkopt #pod #pod my $opt_list = Data::OptList::mkopt($input, \%arg); #pod #pod Valid arguments are: #pod #pod moniker - a word used in errors to describe the opt list; encouraged #pod require_unique - if true, no name may appear more than once #pod must_be - types to which opt list values are limited (described below) #pod name_test - a coderef used to test whether a value can be a name #pod (described below, but you probably don't want this) #pod #pod This produces an array of arrays; the inner arrays are name/value pairs. #pod Values will be either "undef" or a reference. #pod #pod Positional parameters may be used for compatibility with the old C #pod interface: #pod #pod my $opt_list = Data::OptList::mkopt($input, $moniker, $req_uni, $must_be); #pod #pod Valid values for C<$input>: #pod #pod undef -> [] #pod hashref -> [ [ key1 => value1 ] ... ] # non-ref values become undef #pod arrayref -> every name followed by a non-name becomes a pair: [ name => ref ] #pod every name followed by undef becomes a pair: [ name => undef ] #pod otherwise, it becomes [ name => undef ] like so: #pod [ "a", "b", [ 1, 2 ] ] -> [ [ a => undef ], [ b => [ 1, 2 ] ] ] #pod #pod By default, a I is any defined non-reference. The C parameter #pod can be a code ref that tests whether the argument passed it is a name or not. #pod This should be used rarely. Interactions between C and #pod C are not yet particularly elegant, as C just tests #pod string equality. B #pod #pod The C parameter is either a scalar or array of scalars; it defines #pod what kind(s) of refs may be values. If an invalid value is found, an exception #pod is thrown. If no value is passed for this argument, any reference is valid. #pod If C specifies that values must be CODE, HASH, ARRAY, or SCALAR, then #pod Params::Util is used to check whether the given value can provide that #pod interface. Otherwise, it checks that the given value is an object of the kind. #pod #pod In other words: #pod #pod [ qw(SCALAR HASH Object::Known) ] #pod #pod Means: #pod #pod _SCALAR0($value) or _HASH($value) or _INSTANCE($value, 'Object::Known') #pod #pod =cut my %test_for; BEGIN { %test_for = ( CODE => \&Params::Util::_CODELIKE, ## no critic HASH => \&Params::Util::_HASHLIKE, ## no critic ARRAY => \&Params::Util::_ARRAYLIKE, ## no critic SCALAR => \&Params::Util::_SCALAR0, ## no critic ); } sub mkopt { my ($opt_list) = shift; my ($moniker, $require_unique, $must_be); # the old positional args my ($name_test, $is_a); if (@_) { if (@_ == 1 and Params::Util::_HASHLIKE($_[0])) { ($moniker, $require_unique, $must_be, $name_test) = @{$_[0]}{ qw(moniker require_unique must_be name_test) }; } else { ($moniker, $require_unique, $must_be) = @_; } # Transform the $must_be specification into a closure $is_a # that will check if a value matches the spec if (defined $must_be) { $must_be = [ $must_be ] unless ref $must_be; my @checks = map { my $class = $_; $test_for{$_} || sub { $_[1] = $class; goto \&Params::Util::_INSTANCE } } @$must_be; $is_a = (@checks == 1) ? $checks[0] : sub { my $value = $_[0]; List::Util::first { defined($_->($value)) } @checks }; $moniker = 'unnamed' unless defined $moniker; } } return [] unless $opt_list; $name_test ||= sub { ! ref $_[0] }; $opt_list = [ map { $_ => (ref $opt_list->{$_} ? $opt_list->{$_} : ()) } keys %$opt_list ] if ref $opt_list eq 'HASH'; my @return; my %seen; for (my $i = 0; $i < @$opt_list; $i++) { ## no critic my $name = $opt_list->[$i]; if ($require_unique) { Carp::croak "multiple definitions provided for $name" if $seen{$name}++; } my $value; if ($i < $#$opt_list) { if (not defined $opt_list->[$i+1]) { $i++ } elsif (! $name_test->($opt_list->[$i+1])) { $value = $opt_list->[++$i]; if ($is_a && !$is_a->($value)) { my $ref = ref $value; Carp::croak "$ref-ref values are not valid in $moniker opt list"; } } } push @return, [ $name => $value ]; } return \@return; } #pod =func mkopt_hash #pod #pod my $opt_hash = Data::OptList::mkopt_hash($input, $moniker, $must_be); #pod #pod Given valid C> input, this routine returns a reference to a hash. It #pod will throw an exception if any name has more than one value. #pod #pod =cut sub mkopt_hash { my ($opt_list, $moniker, $must_be) = @_; return {} unless $opt_list; $opt_list = mkopt($opt_list, $moniker, 1, $must_be); my %hash = map { $_->[0] => $_->[1] } @$opt_list; return \%hash; } #pod =head1 EXPORTS #pod #pod Both C and C may be exported on request. #pod #pod =cut BEGIN { *import = Sub::Install::exporter { exports => [qw(mkopt mkopt_hash)], }; } 1; __END__ =pod =encoding UTF-8 =head1 NAME Data::OptList - parse and validate simple name/value option pairs =head1 VERSION version 0.110 =head1 SYNOPSIS use Data::OptList; my $options = Data::OptList::mkopt([ qw(key1 key2 key3 key4), key5 => { ... }, key6 => [ ... ], key7 => sub { ... }, key8 => { ... }, key8 => [ ... ], ]); ...is the same thing, more or less, as: my $options = [ [ key1 => undef, ], [ key2 => undef, ], [ key3 => undef, ], [ key4 => undef, ], [ key5 => { ... }, ], [ key6 => [ ... ], ], [ key7 => sub { ... }, ], [ key8 => { ... }, ], [ key8 => [ ... ], ], ]); =head1 DESCRIPTION Hashes are great for storing named data, but if you want more than one entry for a name, you have to use a list of pairs. Even then, this is really boring to write: $values = [ foo => undef, bar => undef, baz => undef, xyz => { ... }, ]; Just look at all those undefs! Don't worry, we can get rid of those: $values = [ map { $_ => undef } qw(foo bar baz), xyz => { ... }, ]; Aaaauuugh! We've saved a little typing, but now it requires thought to read, and thinking is even worse than typing... and it's got a bug! It looked right, didn't it? Well, the C<< xyz => { ... } >> gets consumed by the map, and we don't get the data we wanted. With Data::OptList, you can do this instead: $values = Data::OptList::mkopt([ qw(foo bar baz), xyz => { ... }, ]); This works by assuming that any defined scalar is a name and any reference following a name is its value. =head1 FUNCTIONS =head2 mkopt my $opt_list = Data::OptList::mkopt($input, \%arg); Valid arguments are: moniker - a word used in errors to describe the opt list; encouraged require_unique - if true, no name may appear more than once must_be - types to which opt list values are limited (described below) name_test - a coderef used to test whether a value can be a name (described below, but you probably don't want this) This produces an array of arrays; the inner arrays are name/value pairs. Values will be either "undef" or a reference. Positional parameters may be used for compatibility with the old C interface: my $opt_list = Data::OptList::mkopt($input, $moniker, $req_uni, $must_be); Valid values for C<$input>: undef -> [] hashref -> [ [ key1 => value1 ] ... ] # non-ref values become undef arrayref -> every name followed by a non-name becomes a pair: [ name => ref ] every name followed by undef becomes a pair: [ name => undef ] otherwise, it becomes [ name => undef ] like so: [ "a", "b", [ 1, 2 ] ] -> [ [ a => undef ], [ b => [ 1, 2 ] ] ] By default, a I is any defined non-reference. The C parameter can be a code ref that tests whether the argument passed it is a name or not. This should be used rarely. Interactions between C and C are not yet particularly elegant, as C just tests string equality. B The C parameter is either a scalar or array of scalars; it defines what kind(s) of refs may be values. If an invalid value is found, an exception is thrown. If no value is passed for this argument, any reference is valid. If C specifies that values must be CODE, HASH, ARRAY, or SCALAR, then Params::Util is used to check whether the given value can provide that interface. Otherwise, it checks that the given value is an object of the kind. In other words: [ qw(SCALAR HASH Object::Known) ] Means: _SCALAR0($value) or _HASH($value) or _INSTANCE($value, 'Object::Known') =head2 mkopt_hash my $opt_hash = Data::OptList::mkopt_hash($input, $moniker, $must_be); Given valid C> input, this routine returns a reference to a hash. It will throw an exception if any name has more than one value. =head1 EXPORTS Both C and C may be exported on request. =head1 AUTHOR Ricardo Signes =head1 CONTRIBUTORS =for stopwords Olivier Mengué Ricardo SIGNES =over 4 =item * Olivier Mengué =item * Ricardo SIGNES =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2006 by Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Dumper.pm000064400000131323152344761230006350 0ustar00# # Data/Dumper.pm # # convert perl data structures into perl syntax suitable for both printing # and eval # # Documentation at the __END__ # package Data::Dumper; BEGIN { $VERSION = '2.167'; # Don't forget to set version and release } # date in POD below! #$| = 1; use 5.006_001; require Exporter; use Carp (); BEGIN { @ISA = qw(Exporter); @EXPORT = qw(Dumper); @EXPORT_OK = qw(DumperX); # if run under miniperl, or otherwise lacking dynamic loading, # XSLoader should be attempted to load, or the pure perl flag # toggled on load failure. eval { require XSLoader; XSLoader::load( 'Data::Dumper' ); 1 } or $Useperl = 1; } my $IS_ASCII = ord 'A' == 65; # module vars and their defaults $Indent = 2 unless defined $Indent; $Trailingcomma = 0 unless defined $Trailingcomma; $Purity = 0 unless defined $Purity; $Pad = "" unless defined $Pad; $Varname = "VAR" unless defined $Varname; $Useqq = 0 unless defined $Useqq; $Terse = 0 unless defined $Terse; $Freezer = "" unless defined $Freezer; $Toaster = "" unless defined $Toaster; $Deepcopy = 0 unless defined $Deepcopy; $Quotekeys = 1 unless defined $Quotekeys; $Bless = "bless" unless defined $Bless; #$Expdepth = 0 unless defined $Expdepth; $Maxdepth = 0 unless defined $Maxdepth; $Pair = ' => ' unless defined $Pair; $Useperl = 0 unless defined $Useperl; $Sortkeys = 0 unless defined $Sortkeys; $Deparse = 0 unless defined $Deparse; $Sparseseen = 0 unless defined $Sparseseen; $Maxrecurse = 1000 unless defined $Maxrecurse; # # expects an arrayref of values to be dumped. # can optionally pass an arrayref of names for the values. # names must have leading $ sign stripped. begin the name with * # to cause output of arrays and hashes rather than refs. # sub new { my($c, $v, $n) = @_; Carp::croak("Usage: PACKAGE->new(ARRAYREF, [ARRAYREF])") unless (defined($v) && (ref($v) eq 'ARRAY')); $n = [] unless (defined($n) && (ref($n) eq 'ARRAY')); my($s) = { level => 0, # current recursive depth indent => $Indent, # various styles of indenting trailingcomma => $Trailingcomma, # whether to add comma after last elem pad => $Pad, # all lines prefixed by this string xpad => "", # padding-per-level apad => "", # added padding for hash keys n such sep => "", # list separator pair => $Pair, # hash key/value separator: defaults to ' => ' seen => {}, # local (nested) refs (id => [name, val]) todump => $v, # values to dump [] names => $n, # optional names for values [] varname => $Varname, # prefix to use for tagging nameless ones purity => $Purity, # degree to which output is evalable useqq => $Useqq, # use "" for strings (backslashitis ensues) terse => $Terse, # avoid name output (where feasible) freezer => $Freezer, # name of Freezer method for objects toaster => $Toaster, # name of method to revive objects deepcopy => $Deepcopy, # do not cross-ref, except to stop recursion quotekeys => $Quotekeys, # quote hash keys 'bless' => $Bless, # keyword to use for "bless" # expdepth => $Expdepth, # cutoff depth for explicit dumping maxdepth => $Maxdepth, # depth beyond which we give up maxrecurse => $Maxrecurse, # depth beyond which we abort useperl => $Useperl, # use the pure Perl implementation sortkeys => $Sortkeys, # flag or filter for sorting hash keys deparse => $Deparse, # use B::Deparse for coderefs noseen => $Sparseseen, # do not populate the seen hash unless necessary }; if ($Indent > 0) { $s->{xpad} = " "; $s->{sep} = "\n"; } return bless($s, $c); } # Packed numeric addresses take less memory. Plus pack is faster than sprintf # Most users of current versions of Data::Dumper will be 5.008 or later. # Anyone on 5.6.1 and 5.6.2 upgrading will be rare (particularly judging by # the bug reports from users on those platforms), so for the common case avoid # complexity, and avoid even compiling the unneeded code. sub init_refaddr_format { } sub format_refaddr { require Scalar::Util; pack "J", Scalar::Util::refaddr(shift); }; if ($] < 5.008) { eval <<'EOC' or die; no warnings 'redefine'; my $refaddr_format; sub init_refaddr_format { require Config; my $f = $Config::Config{uvxformat}; $f =~ tr/"//d; $refaddr_format = "0x%" . $f; } sub format_refaddr { require Scalar::Util; sprintf $refaddr_format, Scalar::Util::refaddr(shift); } 1 EOC } # # add-to or query the table of already seen references # sub Seen { my($s, $g) = @_; if (defined($g) && (ref($g) eq 'HASH')) { init_refaddr_format(); my($k, $v, $id); while (($k, $v) = each %$g) { if (defined $v) { if (ref $v) { $id = format_refaddr($v); if ($k =~ /^[*](.*)$/) { $k = (ref $v eq 'ARRAY') ? ( "\\\@" . $1 ) : (ref $v eq 'HASH') ? ( "\\\%" . $1 ) : (ref $v eq 'CODE') ? ( "\\\&" . $1 ) : ( "\$" . $1 ) ; } elsif ($k !~ /^\$/) { $k = "\$" . $k; } $s->{seen}{$id} = [$k, $v]; } else { Carp::carp("Only refs supported, ignoring non-ref item \$$k"); } } else { Carp::carp("Value of ref must be defined; ignoring undefined item \$$k"); } } return $s; } else { return map { @$_ } values %{$s->{seen}}; } } # # set or query the values to be dumped # sub Values { my($s, $v) = @_; if (defined($v)) { if (ref($v) eq 'ARRAY') { $s->{todump} = [@$v]; # make a copy return $s; } else { Carp::croak("Argument to Values, if provided, must be array ref"); } } else { return @{$s->{todump}}; } } # # set or query the names of the values to be dumped # sub Names { my($s, $n) = @_; if (defined($n)) { if (ref($n) eq 'ARRAY') { $s->{names} = [@$n]; # make a copy return $s; } else { Carp::croak("Argument to Names, if provided, must be array ref"); } } else { return @{$s->{names}}; } } sub DESTROY {} sub Dump { return &Dumpxs unless $Data::Dumper::Useperl || (ref($_[0]) && $_[0]->{useperl}) # Use pure perl version on earlier releases on EBCDIC platforms || (! $IS_ASCII && $] lt 5.021_010); return &Dumpperl; } # # dump the refs in the current dumper object. # expects same args as new() if called via package name. # sub Dumpperl { my($s) = shift; my(@out, $val, $name); my($i) = 0; local(@post); init_refaddr_format(); $s = $s->new(@_) unless ref $s; for $val (@{$s->{todump}}) { @post = (); $name = $s->{names}[$i++]; $name = $s->_refine_name($name, $val, $i); my $valstr; { local($s->{apad}) = $s->{apad}; $s->{apad} .= ' ' x (length($name) + 3) if $s->{indent} >= 2 and !$s->{terse}; $valstr = $s->_dump($val, $name); } $valstr = "$name = " . $valstr . ';' if @post or !$s->{terse}; my $out = $s->_compose_out($valstr, \@post); push @out, $out; } return wantarray ? @out : join('', @out); } # wrap string in single quotes (escaping if needed) sub _quote { my $val = shift; $val =~ s/([\\\'])/\\$1/g; return "'" . $val . "'"; } # Old Perls (5.14-) have trouble resetting vstring magic when it is no # longer valid. use constant _bad_vsmg => defined &_vstring && (_vstring(~v0)||'') eq "v0"; # # twist, toil and turn; # and recurse, of course. # sometimes sordidly; # and curse if no recourse. # sub _dump { my($s, $val, $name) = @_; my($out, $type, $id, $sname); $type = ref $val; $out = ""; if ($type) { # Call the freezer method if it's specified and the object has the # method. Trap errors and warn() instead of die()ing, like the XS # implementation. my $freezer = $s->{freezer}; if ($freezer and UNIVERSAL::can($val, $freezer)) { eval { $val->$freezer() }; warn "WARNING(Freezer method call failed): $@" if $@; } require Scalar::Util; my $realpack = Scalar::Util::blessed($val); my $realtype = $realpack ? Scalar::Util::reftype($val) : ref $val; $id = format_refaddr($val); # Note: By this point $name is always defined and of non-zero length. # Keep a tab on it so that we do not fall into recursive pit. if (exists $s->{seen}{$id}) { if ($s->{purity} and $s->{level} > 0) { $out = ($realtype eq 'HASH') ? '{}' : ($realtype eq 'ARRAY') ? '[]' : 'do{my $o}' ; push @post, $name . " = " . $s->{seen}{$id}[0]; } else { $out = $s->{seen}{$id}[0]; if ($name =~ /^([\@\%])/) { my $start = $1; if ($out =~ /^\\$start/) { $out = substr($out, 1); } else { $out = $start . '{' . $out . '}'; } } } return $out; } else { # store our name $s->{seen}{$id} = [ ( ($name =~ /^[@%]/) ? ('\\' . $name ) : ($realtype eq 'CODE' and $name =~ /^[*](.*)$/) ? ('\\&' . $1 ) : $name ), $val ]; } my $no_bless = 0; my $is_regex = 0; if ( $realpack and ($] >= 5.009005 ? re::is_regexp($val) : $realpack eq 'Regexp') ) { $is_regex = 1; $no_bless = $realpack eq 'Regexp'; } # If purity is not set and maxdepth is set, then check depth: # if we have reached maximum depth, return the string # representation of the thing we are currently examining # at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)'). if (!$s->{purity} and defined($s->{maxdepth}) and $s->{maxdepth} > 0 and $s->{level} >= $s->{maxdepth}) { return qq['$val']; } # avoid recursing infinitely [perl #122111] if ($s->{maxrecurse} > 0 and $s->{level} >= $s->{maxrecurse}) { die "Recursion limit of $s->{maxrecurse} exceeded"; } # we have a blessed ref my ($blesspad); if ($realpack and !$no_bless) { $out = $s->{'bless'} . '( '; $blesspad = $s->{apad}; $s->{apad} .= ' ' if ($s->{indent} >= 2); } $s->{level}++; my $ipad = $s->{xpad} x $s->{level}; if ($is_regex) { my $pat; my $flags = ""; if (defined(*re::regexp_pattern{CODE})) { ($pat, $flags) = re::regexp_pattern($val); } else { $pat = "$val"; } $pat =~ s <(\\.)|/> { $1 || '\\/' }ge; $out .= "qr/$pat/$flags"; } elsif ($realtype eq 'SCALAR' || $realtype eq 'REF' || $realtype eq 'VSTRING') { if ($realpack) { $out .= 'do{\\(my $o = ' . $s->_dump($$val, "\${$name}") . ')}'; } else { $out .= '\\' . $s->_dump($$val, "\${$name}"); } } elsif ($realtype eq 'GLOB') { $out .= '\\' . $s->_dump($$val, "*{$name}"); } elsif ($realtype eq 'ARRAY') { my($pad, $mname); my($i) = 0; $out .= ($name =~ /^\@/) ? '(' : '['; $pad = $s->{sep} . $s->{pad} . $s->{apad}; ($name =~ /^\@(.*)$/) ? ($mname = "\$" . $1) : # omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar} ($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) : ($mname = $name . '->'); $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/; for my $v (@$val) { $sname = $mname . '[' . $i . ']'; $out .= $pad . $ipad . '#' . $i if $s->{indent} >= 3; $out .= $pad . $ipad . $s->_dump($v, $sname); $out .= "," if $i++ < $#$val || ($s->{trailingcomma} && $s->{indent} >= 1); } $out .= $pad . ($s->{xpad} x ($s->{level} - 1)) if $i; $out .= ($name =~ /^\@/) ? ')' : ']'; } elsif ($realtype eq 'HASH') { my ($k, $v, $pad, $lpad, $mname, $pair); $out .= ($name =~ /^\%/) ? '(' : '{'; $pad = $s->{sep} . $s->{pad} . $s->{apad}; $lpad = $s->{apad}; $pair = $s->{pair}; ($name =~ /^\%(.*)$/) ? ($mname = "\$" . $1) : # omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar} ($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) : ($mname = $name . '->'); $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/; my $sortkeys = defined($s->{sortkeys}) ? $s->{sortkeys} : ''; my $keys = []; if ($sortkeys) { if (ref($s->{sortkeys}) eq 'CODE') { $keys = $s->{sortkeys}($val); unless (ref($keys) eq 'ARRAY') { Carp::carp("Sortkeys subroutine did not return ARRAYREF"); $keys = []; } } else { $keys = [ sort keys %$val ]; } } # Ensure hash iterator is reset keys(%$val); my $key; while (($k, $v) = ! $sortkeys ? (each %$val) : @$keys ? ($key = shift(@$keys), $val->{$key}) : () ) { my $nk = $s->_dump($k, ""); # _dump doesn't quote numbers of this form if ($s->{quotekeys} && $nk =~ /^(?:0|-?[1-9][0-9]{0,8})\z/) { $nk = $s->{useqq} ? qq("$nk") : qq('$nk'); } elsif (!$s->{quotekeys} and $nk =~ /^[\"\']([A-Za-z_]\w*)[\"\']$/) { $nk = $1 } $sname = $mname . '{' . $nk . '}'; $out .= $pad . $ipad . $nk . $pair; # temporarily alter apad $s->{apad} .= (" " x (length($nk) + 4)) if $s->{indent} >= 2; $out .= $s->_dump($val->{$k}, $sname) . ","; $s->{apad} = $lpad if $s->{indent} >= 2; } if (substr($out, -1) eq ',') { chop $out if !$s->{trailingcomma} || !$s->{indent}; $out .= $pad . ($s->{xpad} x ($s->{level} - 1)); } $out .= ($name =~ /^\%/) ? ')' : '}'; } elsif ($realtype eq 'CODE') { if ($s->{deparse}) { require B::Deparse; my $sub = 'sub ' . (B::Deparse->new)->coderef2text($val); $pad = $s->{sep} . $s->{pad} . $s->{apad} . $s->{xpad} x ($s->{level} - 1); $sub =~ s/\n/$pad/gs; $out .= $sub; } else { $out .= 'sub { "DUMMY" }'; Carp::carp("Encountered CODE ref, using dummy placeholder") if $s->{purity}; } } else { Carp::croak("Can't handle '$realtype' type"); } if ($realpack and !$no_bless) { # we have a blessed ref $out .= ', ' . _quote($realpack) . ' )'; $out .= '->' . $s->{toaster} . '()' if $s->{toaster} ne ''; $s->{apad} = $blesspad; } $s->{level}--; } else { # simple scalar my $ref = \$_[1]; my $v; # first, catalog the scalar if ($name ne '') { $id = format_refaddr($ref); if (exists $s->{seen}{$id}) { if ($s->{seen}{$id}[2]) { $out = $s->{seen}{$id}[0]; #warn "[<$out]\n"; return "\${$out}"; } } else { #warn "[>\\$name]\n"; $s->{seen}{$id} = ["\\$name", $ref]; } } $ref = \$val; if (ref($ref) eq 'GLOB') { # glob my $name = substr($val, 1); $name =~ s/^main::(?!\z)/::/; if ($name =~ /\A(?:[A-Z_a-z][0-9A-Z_a-z]*)?::(?:[0-9A-Z_a-z]+::)*[0-9A-Z_a-z]*\z/ && $name ne 'main::') { $sname = $name; } else { $sname = $s->_dump( $name eq 'main::' || $] < 5.007 && $name eq "main::\0" ? '' : $name, "", ); $sname = '{' . $sname . '}'; } if ($s->{purity}) { my $k; local ($s->{level}) = 0; for $k (qw(SCALAR ARRAY HASH)) { my $gval = *$val{$k}; next unless defined $gval; next if $k eq "SCALAR" && ! defined $$gval; # always there # _dump can push into @post, so we hold our place using $postlen my $postlen = scalar @post; $post[$postlen] = "\*$sname = "; local ($s->{apad}) = " " x length($post[$postlen]) if $s->{indent} >= 2; $post[$postlen] .= $s->_dump($gval, "\*$sname\{$k\}"); } } $out .= '*' . $sname; } elsif (!defined($val)) { $out .= "undef"; } elsif (defined &_vstring and $v = _vstring($val) and !_bad_vsmg || eval $v eq $val) { $out .= $v; } elsif (!defined &_vstring and ref $ref eq 'VSTRING' || eval{Scalar::Util::isvstring($val)}) { $out .= sprintf "%vd", $val; } # \d here would treat "1\x{660}" as a safe decimal number elsif ($val =~ /^(?:0|-?[1-9][0-9]{0,8})\z/) { # safe decimal number $out .= $val; } else { # string if ($s->{useqq} or $val =~ tr/\0-\377//c) { # Fall back to qq if there's Unicode $out .= qquote($val, $s->{useqq}); } else { $out .= _quote($val); } } } if ($id) { # if we made it this far, $id was added to seen list at current # level, so remove it to get deep copies if ($s->{deepcopy}) { delete($s->{seen}{$id}); } elsif ($name) { $s->{seen}{$id}[2] = 1; } } return $out; } # # non-OO style of earlier version # sub Dumper { return Data::Dumper->Dump([@_]); } # compat stub sub DumperX { return Data::Dumper->Dumpxs([@_], []); } # # reset the "seen" cache # sub Reset { my($s) = shift; $s->{seen} = {}; return $s; } sub Indent { my($s, $v) = @_; if (defined($v)) { if ($v == 0) { $s->{xpad} = ""; $s->{sep} = ""; } else { $s->{xpad} = " "; $s->{sep} = "\n"; } $s->{indent} = $v; return $s; } else { return $s->{indent}; } } sub Trailingcomma { my($s, $v) = @_; defined($v) ? (($s->{trailingcomma} = $v), return $s) : $s->{trailingcomma}; } sub Pair { my($s, $v) = @_; defined($v) ? (($s->{pair} = $v), return $s) : $s->{pair}; } sub Pad { my($s, $v) = @_; defined($v) ? (($s->{pad} = $v), return $s) : $s->{pad}; } sub Varname { my($s, $v) = @_; defined($v) ? (($s->{varname} = $v), return $s) : $s->{varname}; } sub Purity { my($s, $v) = @_; defined($v) ? (($s->{purity} = $v), return $s) : $s->{purity}; } sub Useqq { my($s, $v) = @_; defined($v) ? (($s->{useqq} = $v), return $s) : $s->{useqq}; } sub Terse { my($s, $v) = @_; defined($v) ? (($s->{terse} = $v), return $s) : $s->{terse}; } sub Freezer { my($s, $v) = @_; defined($v) ? (($s->{freezer} = $v), return $s) : $s->{freezer}; } sub Toaster { my($s, $v) = @_; defined($v) ? (($s->{toaster} = $v), return $s) : $s->{toaster}; } sub Deepcopy { my($s, $v) = @_; defined($v) ? (($s->{deepcopy} = $v), return $s) : $s->{deepcopy}; } sub Quotekeys { my($s, $v) = @_; defined($v) ? (($s->{quotekeys} = $v), return $s) : $s->{quotekeys}; } sub Bless { my($s, $v) = @_; defined($v) ? (($s->{'bless'} = $v), return $s) : $s->{'bless'}; } sub Maxdepth { my($s, $v) = @_; defined($v) ? (($s->{'maxdepth'} = $v), return $s) : $s->{'maxdepth'}; } sub Maxrecurse { my($s, $v) = @_; defined($v) ? (($s->{'maxrecurse'} = $v), return $s) : $s->{'maxrecurse'}; } sub Useperl { my($s, $v) = @_; defined($v) ? (($s->{'useperl'} = $v), return $s) : $s->{'useperl'}; } sub Sortkeys { my($s, $v) = @_; defined($v) ? (($s->{'sortkeys'} = $v), return $s) : $s->{'sortkeys'}; } sub Deparse { my($s, $v) = @_; defined($v) ? (($s->{'deparse'} = $v), return $s) : $s->{'deparse'}; } sub Sparseseen { my($s, $v) = @_; defined($v) ? (($s->{'noseen'} = $v), return $s) : $s->{'noseen'}; } # used by qquote below my %esc = ( "\a" => "\\a", "\b" => "\\b", "\t" => "\\t", "\n" => "\\n", "\f" => "\\f", "\r" => "\\r", "\e" => "\\e", ); my $low_controls = ($IS_ASCII) # This includes \177, because traditionally it has been # output as octal, even though it isn't really a "low" # control ? qr/[\0-\x1f\177]/ # EBCDIC low controls. : qr/[\0-\x3f]/; # put a string value in double quotes sub qquote { local($_) = shift; s/([\\\"\@\$])/\\$1/g; # This efficiently changes the high ordinal characters to \x{} if the utf8 # flag is on. On ASCII platforms, the high ordinals are all the # non-ASCII's. On EBCDIC platforms, we don't include in these the non-ASCII # controls whose ordinals are less than SPACE, excluded below by the range # \0-\x3f. On ASCII platforms this range just compiles as part of :ascii:. # On EBCDIC platforms, there is just one outlier high ordinal control, and # it gets output as \x{}. my $bytes; { use bytes; $bytes = length } s/([^[:ascii:]\0-\x3f])/sprintf("\\x{%x}",ord($1))/ge if $bytes > length # The above doesn't get the EBCDIC outlier high ordinal control when # the string is UTF-8 but there are no UTF-8 variant characters in it. # We want that to come out as \x{} anyway. We need is_utf8() to do # this. || (! $IS_ASCII && $] ge 5.008_001 && utf8::is_utf8($_)); return qq("$_") unless /[[:^print:]]/; # fast exit if only printables # Here, there is at least one non-printable to output. First, translate the # escapes. s/([\a\b\t\n\f\r\e])/$esc{$1}/g; # no need for 3 digits in escape for octals not followed by a digit. s/($low_controls)(?!\d)/'\\'.sprintf('%o',ord($1))/eg; # But otherwise use 3 digits s/($low_controls)/'\\'.sprintf('%03o',ord($1))/eg; # all but last branch below not supported --BEHAVIOR SUBJECT TO CHANGE-- my $high = shift || ""; if ($high eq "iso8859") { # Doesn't escape the Latin1 printables if ($IS_ASCII) { s/([\200-\240])/'\\'.sprintf('%o',ord($1))/eg; } elsif ($] ge 5.007_003) { my $high_control = utf8::unicode_to_native(0x9F); s/$high_control/sprintf('\\%o',ord($1))/eg; } } elsif ($high eq "utf8") { # Some discussion of what to do here is in # https://rt.perl.org/Ticket/Display.html?id=113088 # use utf8; # $str =~ s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge; } elsif ($high eq "8bit") { # leave it as it is } else { s/([[:^ascii:]])/'\\'.sprintf('%03o',ord($1))/eg; #s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge; } return qq("$_"); } # helper sub to sort hash keys in Perl < 5.8.0 where we don't have # access to sortsv() from XS sub _sortkeys { [ sort keys %{$_[0]} ] } sub _refine_name { my $s = shift; my ($name, $val, $i) = @_; if (defined $name) { if ($name =~ /^[*](.*)$/) { if (defined $val) { $name = (ref $val eq 'ARRAY') ? ( "\@" . $1 ) : (ref $val eq 'HASH') ? ( "\%" . $1 ) : (ref $val eq 'CODE') ? ( "\*" . $1 ) : ( "\$" . $1 ) ; } else { $name = "\$" . $1; } } elsif ($name !~ /^\$/) { $name = "\$" . $name; } } else { # no names provided $name = "\$" . $s->{varname} . $i; } return $name; } sub _compose_out { my $s = shift; my ($valstr, $postref) = @_; my $out = ""; $out .= $s->{pad} . $valstr . $s->{sep}; if (@{$postref}) { $out .= $s->{pad} . join(';' . $s->{sep} . $s->{pad}, @{$postref}) . ';' . $s->{sep}; } return $out; } 1; __END__ =head1 NAME Data::Dumper - stringified perl data structures, suitable for both printing and C =head1 SYNOPSIS use Data::Dumper; # simple procedural interface print Dumper($foo, $bar); # extended usage with names print Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]); # configuration variables { local $Data::Dumper::Purity = 1; eval Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]); } # OO usage $d = Data::Dumper->new([$foo, $bar], [qw(foo *ary)]); ... print $d->Dump; ... $d->Purity(1)->Terse(1)->Deepcopy(1); eval $d->Dump; =head1 DESCRIPTION Given a list of scalars or reference variables, writes out their contents in perl syntax. The references can also be objects. The content of each variable is output in a single Perl statement. Handles self-referential structures correctly. The return value can be Ced to get back an identical copy of the original reference structure. (Please do consider the security implications of eval'ing code from untrusted sources!) Any references that are the same as one of those passed in will be named C<$VAR>I (where I is a numeric suffix), and other duplicate references to substructures within C<$VAR>I will be appropriately labeled using arrow notation. You can specify names for individual values to be dumped if you use the C method, or you can change the default C<$VAR> prefix to something else. See C<$Data::Dumper::Varname> and C<$Data::Dumper::Terse> below. The default output of self-referential structures can be Ced, but the nested references to C<$VAR>I will be undefined, since a recursive structure cannot be constructed using one Perl statement. You should set the C flag to 1 to get additional statements that will correctly fill in these references. Moreover, if Ced when strictures are in effect, you need to ensure that any variables it accesses are previously declared. In the extended usage form, the references to be dumped can be given user-specified names. If a name begins with a C<*>, the output will describe the dereferenced type of the supplied reference for hashes and arrays, and coderefs. Output of names will be avoided where possible if the C flag is set. In many cases, methods that are used to set the internal state of the object will return the object itself, so method calls can be conveniently chained together. Several styles of output are possible, all controlled by setting the C flag. See L below for details. =head2 Methods =over 4 =item I->new(I, I) Returns a newly created C object. The first argument is an anonymous array of values to be dumped. The optional second argument is an anonymous array of names for the values. The names need not have a leading C<$> sign, and must be comprised of alphanumeric characters. You can begin a name with a C<*> to specify that the dereferenced type must be dumped instead of the reference itself, for ARRAY and HASH references. The prefix specified by C<$Data::Dumper::Varname> will be used with a numeric suffix if the name for a value is undefined. Data::Dumper will catalog all references encountered while dumping the values. Cross-references (in the form of names of substructures in perl syntax) will be inserted at all possible points, preserving any structural interdependencies in the original set of values. Structure traversal is depth-first, and proceeds in order from the first supplied value to the last. =item I<$OBJ>->Dump I I->Dump(I, I) Returns the stringified form of the values stored in the object (preserving the order in which they were supplied to C), subject to the configuration options below. In a list context, it returns a list of strings corresponding to the supplied values. The second form, for convenience, simply calls the C method on its arguments before dumping the object immediately. =item I<$OBJ>->Seen(I<[HASHREF]>) Queries or adds to the internal table of already encountered references. You must use C to explicitly clear the table if needed. Such references are not dumped; instead, their names are inserted wherever they are encountered subsequently. This is useful especially for properly dumping subroutine references. Expects an anonymous hash of name => value pairs. Same rules apply for names as in C. If no argument is supplied, will return the "seen" list of name => value pairs, in a list context. Otherwise, returns the object itself. =item I<$OBJ>->Values(I<[ARRAYREF]>) Queries or replaces the internal array of values that will be dumped. When called without arguments, returns the values as a list. When called with a reference to an array of replacement values, returns the object itself. When called with any other type of argument, dies. =item I<$OBJ>->Names(I<[ARRAYREF]>) Queries or replaces the internal array of user supplied names for the values that will be dumped. When called without arguments, returns the names. When called with an array of replacement names, returns the object itself. If the number of replacement names exceeds the number of values to be named, the excess names will not be used. If the number of replacement names falls short of the number of values to be named, the list of replacement names will be exhausted and remaining values will not be renamed. When called with any other type of argument, dies. =item I<$OBJ>->Reset Clears the internal table of "seen" references and returns the object itself. =back =head2 Functions =over 4 =item Dumper(I) Returns the stringified form of the values in the list, subject to the configuration options below. The values will be named C<$VAR>I in the output, where I is a numeric suffix. Will return a list of strings in a list context. =back =head2 Configuration Variables or Methods Several configuration variables can be used to control the kind of output generated when using the procedural interface. These variables are usually Cized in a block so that other parts of the code are not affected by the change. These variables determine the default state of the object created by calling the C method, but cannot be used to alter the state of the object thereafter. The equivalent method names should be used instead to query or set the internal state of the object. The method forms return the object itself when called with arguments, so that they can be chained together nicely. =over 4 =item * $Data::Dumper::Indent I I<$OBJ>->Indent(I<[NEWVAL]>) Controls the style of indentation. It can be set to 0, 1, 2 or 3. Style 0 spews output without any newlines, indentation, or spaces between list items. It is the most compact format possible that can still be called valid perl. Style 1 outputs a readable form with newlines but no fancy indentation (each level in the structure is simply indented by a fixed amount of whitespace). Style 2 (the default) outputs a very readable form which takes into account the length of hash keys (so the hash value lines up). Style 3 is like style 2, but also annotates the elements of arrays with their index (but the comment is on its own line, so array output consumes twice the number of lines). Style 2 is the default. =item * $Data::Dumper::Trailingcomma I I<$OBJ>->Trailingcomma(I<[NEWVAL]>) Controls whether a comma is added after the last element of an array or hash. Even when true, no comma is added between the last element of an array or hash and a closing bracket when they appear on the same line. The default is false. =item * $Data::Dumper::Purity I I<$OBJ>->Purity(I<[NEWVAL]>) Controls the degree to which the output can be Ced to recreate the supplied reference structures. Setting it to 1 will output additional perl statements that will correctly recreate nested references. The default is 0. =item * $Data::Dumper::Pad I I<$OBJ>->Pad(I<[NEWVAL]>) Specifies the string that will be prefixed to every line of the output. Empty string by default. =item * $Data::Dumper::Varname I I<$OBJ>->Varname(I<[NEWVAL]>) Contains the prefix to use for tagging variable names in the output. The default is "VAR". =item * $Data::Dumper::Useqq I I<$OBJ>->Useqq(I<[NEWVAL]>) When set, enables the use of double quotes for representing string values. Whitespace other than space will be represented as C<[\n\t\r]>, "unsafe" characters will be backslashed, and unprintable characters will be output as quoted octal integers. The default is 0. =item * $Data::Dumper::Terse I I<$OBJ>->Terse(I<[NEWVAL]>) When set, Data::Dumper will emit single, non-self-referential values as atoms/terms rather than statements. This means that the C<$VAR>I names will be avoided where possible, but be advised that such output may not always be parseable by C. =item * $Data::Dumper::Freezer I $I->Freezer(I<[NEWVAL]>) Can be set to a method name, or to an empty string to disable the feature. Data::Dumper will invoke that method via the object before attempting to stringify it. This method can alter the contents of the object (if, for instance, it contains data allocated from C), and even rebless it in a different package. The client is responsible for making sure the specified method can be called via the object, and that the object ends up containing only perl data types after the method has been called. Defaults to an empty string. If an object does not support the method specified (determined using UNIVERSAL::can()) then the call will be skipped. If the method dies a warning will be generated. =item * $Data::Dumper::Toaster I $I->Toaster(I<[NEWVAL]>) Can be set to a method name, or to an empty string to disable the feature. Data::Dumper will emit a method call for any objects that are to be dumped using the syntax CMETHOD()>. Note that this means that the method specified will have to perform any modifications required on the object (like creating new state within it, and/or reblessing it in a different package) and then return it. The client is responsible for making sure the method can be called via the object, and that it returns a valid object. Defaults to an empty string. =item * $Data::Dumper::Deepcopy I $I->Deepcopy(I<[NEWVAL]>) Can be set to a boolean value to enable deep copies of structures. Cross-referencing will then only be done when absolutely essential (i.e., to break reference cycles). Default is 0. =item * $Data::Dumper::Quotekeys I $I->Quotekeys(I<[NEWVAL]>) Can be set to a boolean value to control whether hash keys are quoted. A defined false value will avoid quoting hash keys when it looks like a simple string. Default is 1, which will always enclose hash keys in quotes. =item * $Data::Dumper::Bless I $I->Bless(I<[NEWVAL]>) Can be set to a string that specifies an alternative to the C builtin operator used to create objects. A function with the specified name should exist, and should accept the same arguments as the builtin. Default is C. =item * $Data::Dumper::Pair I $I->Pair(I<[NEWVAL]>) Can be set to a string that specifies the separator between hash keys and values. To dump nested hash, array and scalar values to JavaScript, use: C<$Data::Dumper::Pair = ' : ';>. Implementing C in JavaScript is left as an exercise for the reader. A function with the specified name exists, and accepts the same arguments as the builtin. Default is: C< =E >. =item * $Data::Dumper::Maxdepth I $I->Maxdepth(I<[NEWVAL]>) Can be set to a positive integer that specifies the depth beyond which we don't venture into a structure. Has no effect when C is set. (Useful in debugger when we often don't want to see more than enough). Default is 0, which means there is no maximum depth. =item * $Data::Dumper::Maxrecurse I $I->Maxrecurse(I<[NEWVAL]>) Can be set to a positive integer that specifies the depth beyond which recursion into a structure will throw an exception. This is intended as a security measure to prevent perl running out of stack space when dumping an excessively deep structure. Can be set to 0 to remove the limit. Default is 1000. =item * $Data::Dumper::Useperl I $I->Useperl(I<[NEWVAL]>) Can be set to a boolean value which controls whether the pure Perl implementation of C is used. The C module is a dual implementation, with almost all functionality written in both pure Perl and also in XS ('C'). Since the XS version is much faster, it will always be used if possible. This option lets you override the default behavior, usually for testing purposes only. Default is 0, which means the XS implementation will be used if possible. =item * $Data::Dumper::Sortkeys I $I->Sortkeys(I<[NEWVAL]>) Can be set to a boolean value to control whether hash keys are dumped in sorted order. A true value will cause the keys of all hashes to be dumped in Perl's default sort order. Can also be set to a subroutine reference which will be called for each hash that is dumped. In this case C will call the subroutine once for each hash, passing it the reference of the hash. The purpose of the subroutine is to return a reference to an array of the keys that will be dumped, in the order that they should be dumped. Using this feature, you can control both the order of the keys, and which keys are actually used. In other words, this subroutine acts as a filter by which you can exclude certain keys from being dumped. Default is 0, which means that hash keys are not sorted. =item * $Data::Dumper::Deparse I $I->Deparse(I<[NEWVAL]>) Can be set to a boolean value to control whether code references are turned into perl source code. If set to a true value, C will be used to get the source of the code reference. In older versions, using this option imposed a significant performance penalty when dumping parts of a data structure other than code references, but that is no longer the case. Caution : use this option only if you know that your coderefs will be properly reconstructed by C. =item * $Data::Dumper::Sparseseen I $I->Sparseseen(I<[NEWVAL]>) By default, Data::Dumper builds up the "seen" hash of scalars that it has encountered during serialization. This is very expensive. This seen hash is necessary to support and even just detect circular references. It is exposed to the user via the C call both for writing and reading. If you, as a user, do not need explicit access to the "seen" hash, then you can set the C option to allow Data::Dumper to eschew building the "seen" hash for scalars that are known not to possess more than one reference. This speeds up serialization considerably if you use the XS implementation. Note: If you turn on C, then you must not rely on the content of the seen hash since its contents will be an implementation detail! =back =head2 Exports =over 4 =item Dumper =back =head1 EXAMPLES Run these code snippets to get a quick feel for the behavior of this module. When you are through with these examples, you may want to add or change the various configuration variables described above, to see their behavior. (See the testsuite in the Data::Dumper distribution for more examples.) use Data::Dumper; package Foo; sub new {bless {'a' => 1, 'b' => sub { return "foo" }}, $_[0]}; package Fuz; # a weird REF-REF-SCALAR object sub new {bless \($_ = \ 'fu\'z'), $_[0]}; package main; $foo = Foo->new; $fuz = Fuz->new; $boo = [ 1, [], "abcd", \*foo, {1 => 'a', 023 => 'b', 0x45 => 'c'}, \\"p\q\'r", $foo, $fuz]; ######## # simple usage ######## $bar = eval(Dumper($boo)); print($@) if $@; print Dumper($boo), Dumper($bar); # pretty print (no array indices) $Data::Dumper::Terse = 1; # don't output names where feasible $Data::Dumper::Indent = 0; # turn off all pretty print print Dumper($boo), "\n"; $Data::Dumper::Indent = 1; # mild pretty print print Dumper($boo); $Data::Dumper::Indent = 3; # pretty print with array indices print Dumper($boo); $Data::Dumper::Useqq = 1; # print strings in double quotes print Dumper($boo); $Data::Dumper::Pair = " : "; # specify hash key/value separator print Dumper($boo); ######## # recursive structures ######## @c = ('c'); $c = \@c; $b = {}; $a = [1, $b, $c]; $b->{a} = $a; $b->{b} = $a->[1]; $b->{c} = $a->[2]; print Data::Dumper->Dump([$a,$b,$c], [qw(a b c)]); $Data::Dumper::Purity = 1; # fill in the holes for eval print Data::Dumper->Dump([$a, $b], [qw(*a b)]); # print as @a print Data::Dumper->Dump([$b, $a], [qw(*b a)]); # print as %b $Data::Dumper::Deepcopy = 1; # avoid cross-refs print Data::Dumper->Dump([$b, $a], [qw(*b a)]); $Data::Dumper::Purity = 0; # avoid cross-refs print Data::Dumper->Dump([$b, $a], [qw(*b a)]); ######## # deep structures ######## $a = "pearl"; $b = [ $a ]; $c = { 'b' => $b }; $d = [ $c ]; $e = { 'd' => $d }; $f = { 'e' => $e }; print Data::Dumper->Dump([$f], [qw(f)]); $Data::Dumper::Maxdepth = 3; # no deeper than 3 refs down print Data::Dumper->Dump([$f], [qw(f)]); ######## # object-oriented usage ######## $d = Data::Dumper->new([$a,$b], [qw(a b)]); $d->Seen({'*c' => $c}); # stash a ref without printing it $d->Indent(3); print $d->Dump; $d->Reset->Purity(0); # empty the seen cache print join "----\n", $d->Dump; ######## # persistence ######## package Foo; sub new { bless { state => 'awake' }, shift } sub Freeze { my $s = shift; print STDERR "preparing to sleep\n"; $s->{state} = 'asleep'; return bless $s, 'Foo::ZZZ'; } package Foo::ZZZ; sub Thaw { my $s = shift; print STDERR "waking up\n"; $s->{state} = 'awake'; return bless $s, 'Foo'; } package main; use Data::Dumper; $a = Foo->new; $b = Data::Dumper->new([$a], ['c']); $b->Freezer('Freeze'); $b->Toaster('Thaw'); $c = $b->Dump; print $c; $d = eval $c; print Data::Dumper->Dump([$d], ['d']); ######## # symbol substitution (useful for recreating CODE refs) ######## sub foo { print "foo speaking\n" } *other = \&foo; $bar = [ \&other ]; $d = Data::Dumper->new([\&other,$bar],['*other','bar']); $d->Seen({ '*foo' => \&foo }); print $d->Dump; ######## # sorting and filtering hash keys ######## $Data::Dumper::Sortkeys = \&my_filter; my $foo = { map { (ord, "$_$_$_") } 'I'..'Q' }; my $bar = { %$foo }; my $baz = { reverse %$foo }; print Dumper [ $foo, $bar, $baz ]; sub my_filter { my ($hash) = @_; # return an array ref containing the hash keys to dump # in the order that you want them to be dumped return [ # Sort the keys of %$foo in reverse numeric order $hash eq $foo ? (sort {$b <=> $a} keys %$hash) : # Only dump the odd number keys of %$bar $hash eq $bar ? (grep {$_ % 2} keys %$hash) : # Sort keys in default order for all other hashes (sort keys %$hash) ]; } =head1 BUGS Due to limitations of Perl subroutine call semantics, you cannot pass an array or hash. Prepend it with a C<\> to pass its reference instead. This will be remedied in time, now that Perl has subroutine prototypes. For now, you need to use the extended usage form, and prepend the name with a C<*> to output it as a hash or array. C cheats with CODE references. If a code reference is encountered in the structure being processed (and if you haven't set the C flag), an anonymous subroutine that contains the string '"DUMMY"' will be inserted in its place, and a warning will be printed if C is set. You can C the result, but bear in mind that the anonymous sub that gets created is just a placeholder. Even using the C flag will in some cases produce results that behave differently after being passed to C; see the documentation for L. SCALAR objects have the weirdest looking C workaround. Pure Perl version of C escapes UTF-8 strings correctly only in Perl 5.8.0 and later. =head2 NOTE Starting from Perl 5.8.1 different runs of Perl will have different ordering of hash keys. The change was done for greater security, see L. This means that different runs of Perl will have different Data::Dumper outputs if the data contains hashes. If you need to have identical Data::Dumper outputs from different runs of Perl, use the environment variable PERL_HASH_SEED, see L. Using this restores the old (platform-specific) ordering: an even prettier solution might be to use the C filter of Data::Dumper. =head1 AUTHOR Gurusamy Sarathy gsar@activestate.com Copyright (c) 1996-2017 Gurusamy Sarathy. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 VERSION Version 2.167 (January 4 2017) =head1 SEE ALSO perl(1) =cut UUID.pm000044400000010650152345035570005661 0ustar00package Data::UUID; use strict; use Carp; require Exporter; require DynaLoader; require Digest::MD5; our @ISA = qw(Exporter DynaLoader); our @EXPORT = qw( NameSpace_DNS NameSpace_OID NameSpace_URL NameSpace_X500 ); our $VERSION = '1.227'; bootstrap Data::UUID $VERSION; 1; __END__ =head1 NAME Data::UUID - Globally/Universally Unique Identifiers (GUIDs/UUIDs) =head1 SEE INSTEAD? The module L provides another interface for generating GUIDs. Right now, it relies on Data::UUID, but it may not in the future. Its interface may be just a little more straightforward for the average Perl programmer. =head1 SYNOPSIS use Data::UUID; $ug = Data::UUID->new; $uuid1 = $ug->create(); $uuid2 = $ug->create_from_name(, ); $res = $ug->compare($uuid1, $uuid2); $str = $ug->to_string( $uuid ); $uuid = $ug->from_string( $str ); =head1 DESCRIPTION This module provides a framework for generating v3 UUIDs (Universally Unique Identifiers, also known as GUIDs (Globally Unique Identifiers). A UUID is 128 bits long, and is guaranteed to be different from all other UUIDs/GUIDs generated until 3400 CE. UUIDs were originally used in the Network Computing System (NCS) and later in the Open Software Foundation's (OSF) Distributed Computing Environment. Currently many different technologies rely on UUIDs to provide unique identity for various software components. Microsoft COM/DCOM for instance, uses GUIDs very extensively to uniquely identify classes, applications and components across network-connected systems. The algorithm for UUID generation, used by this extension, is described in the Internet Draft "UUIDs and GUIDs" by Paul J. Leach and Rich Salz. (See RFC 4122.) It provides reasonably efficient and reliable framework for generating UUIDs and supports fairly high allocation rates -- 10 million per second per machine -- and therefore is suitable for identifying both extremely short-lived and very persistent objects on a given system as well as across the network. This modules provides several methods to create a UUID. In all methods, C<< >> is a UUID and C<< >> is a free form string. # creates binary (16 byte long binary value) UUID. $ug->create(); $ug->create_bin(); # creates binary (16-byte long binary value) UUID based on particular # namespace and name string. $ug->create_from_name(, ); $ug->create_from_name_bin(, ); # creates UUID string, using conventional UUID string format, # such as: 4162F712-1DD2-11B2-B17E-C09EFE1DC403 # Note that digits A-F are capitalized, which is contrary to rfc4122 $ug->create_str(); $ug->create_from_name_str(, ); # creates UUID string as a hex string, # such as: 0x4162F7121DD211B2B17EC09EFE1DC403 # Note that digits A-F are capitalized, which is contrary to rfc4122 $ug->create_hex(); $ug->create_from_name_hex(, ); # creates UUID string as a Base64-encoded string $ug->create_b64(); $ug->create_from_name_b64(, ); Binary UUIDs can be converted to printable strings using following methods: # convert to conventional string representation $ug->to_string(); # convert to hex string (using upper, rather than lower, case letters) $ug->to_hexstring(); # convert to Base64-encoded string $ug->to_b64string(); Conversely, string UUIDs can be converted back to binary form: # recreate binary UUID from string $ug->from_string(); $ug->from_hexstring(); # recreate binary UUID from Base64-encoded string $ug->from_b64string(); Finally, two binary UUIDs can be compared using the following method: # returns -1, 0 or 1 depending on whether uuid1 less # than, equals to, or greater than uuid2 $ug->compare(, ); Examples: use Data::UUID; # this creates a new UUID in string form, based on the standard namespace # UUID NameSpace_URL and name "www.mycompany.com" $ug = Data::UUID->new; print $ug->create_from_name_str(NameSpace_URL, "www.mycompany.com"); =head2 EXPORT The module allows exporting of several standard namespace UUIDs: =over =item NameSpace_DNS =item NameSpace_URL =item NameSpace_OID =item NameSpace_X500 =back =head1 AUTHOR Alexander Golomshtok =head1 SEE ALSO The Internet Draft "UUIDs and GUIDs" by Paul J. Leach and Rich Salz (RFC 4122) =cut UUID/.packlist000064400000000173152345600310007125 0ustar00/usr/local/lib64/perl5/Data/UUID.pm /usr/local/lib64/perl5/auto/Data/UUID/UUID.so /usr/local/share/man/man3/Data::UUID.3pm UUID/UUID.so000055500000365350152345600310006437 0ustar00ELF> @@8 @%$HH HLHL HL h `L`L `L 888$$pHpHpH StdpHpHpH Ptd$C$C$CQtdRtdHLHL HL GNU0Ţe|E~魵1@ 134BE|qXgT4;%* Dbae[ U'ph4q , F"\M @P P @P o 8__gmon_start___ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalizelibpthread.so.0PL_thr_keypthread_getspecificPerl_sv_2pv_flagsPerl_sv_newmortalPerl_sv_derived_fromPerl_sv_2iv_flagsPerl_sv_setiv_mgPerl_croak_nocontextPerl_croak_xs_usagePerl_push_scopePerl_savetmpsPerl_newSVpvPerl_sv_2mortalPerl_call_methodPerl_newSVsvPerl_pop_scopePerl_free_tmpsPerl_stack_growPerl_markstack_grow__stack_chk_failgettimeofdaygethostidgethostnamemallocreallocmemsetPL_memory_wrappthread_mutex_lockpthread_mutex_unlockfree__errno_locationPerl_sv_setref_pv__sprintf_chksrandstrlensscanfboot_Data__UUIDPerl_xs_handshakePerl_newXS_deffilePerl_gv_stashpvcallocpthread_mutex_initPerl_newCONSTSUBPerl_xs_boot_epiloglibperl.so.5.26libc.so.6_edata__bss_start_endGLIBC_2.2.5GLIBC_2.3.4GLIBC_2.4U ui %ti 1ii =ui %HL PL XL XL O O O O O *O ,xN N N N N N N N  N  N  N  N  N N N N N O O O O  O (O 0O 8O @O HO PO  XO !`O "hO #pO $xO %O &O 'O (O )O +O ,O -O .O /O 0HHI? HtH5= %= hhhhhhhhqhah Qh Ah 1h !h hhhhhhhhhhqhahQhAh1h!hhhh h!h"h#h$h%h&h'qh(ah)Qh*A%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%: D%}: D%u: D%m: D%e: D%]: D%U: D%M: D%E: D%=: D%5: D%-: D%%: D%: D%: D% : D%: D%9 D%9 D%9 D%9 D%9 D%9 D%9 D%9 D%9 D%9 D%9 DH=: H: H9tH9 Ht H=9 H59 H)HHH?HHtHu9 HtfD=9 u+UH=R9 Ht H=5 d}9 ]wAWAVIAUATUSHH-8 }}L }HPxHJHHxHcH@HI)IA(}DcDkMc}H@J@ % =y}H@N$i1LHIƋ}HcF}H@H؋@ % =@#}H@H1HHqINj}}H@@#HIċ}IcL,H@H@ }}H@H4Ht$Ht$H$%Ho}o}H@HH@@ % =UH}H@HHX4HHA1A9tۃAGfA9FtۃAGfA9FtۃAGA8FtۃAG A8F tۃ @A A8BGHHu}Hc}H@Nt(AD$ %AwEAL$ I\$Mf}G}HX;IL(H[]A\A]A^A_fD}HXH@H@L$)fDfDH@HLxfH@JLpff.}HLHBH=%1H5#L8ATUSHM5 ;^;H(TH ;EH ;6;HPxLbL`x#L;>;HH+HHHA$;H@ H)H;H1H5z"H;ILH;HEH(;H52#Hl;AH(A;LeHfLH ;IQH(;G;HhPA>H(A>HPxHJHHxkIH@Db(HcHH)HJA>DkHc7A>H@H؋@ % =A>H@H1HHbHA>McJ4H@Ht$J@ A>A>H@JHC HHA>A>H@JH@@ % =dA>H@JHXPHHEGAUA3HHLl$ 3L% HH9D$4E1 Aw6HHCAD$=t DAL4HHH9uD$48L|$Ht$(1HXH|$ .LHA>A>HXIL8HD$8dH3%( HH[]A\A]A^A_fH)D$ E<0L|$ Ld$MoCH<-LH5H1HugD$IHSAGM9uD$ fD$$fD$&ȉD$ P FH@HHhF}xkH]E^HH=_1=H=> 1/H55LDH=L1 f.AWAVAUIATUSHH ;;H(;HPxHJHHxLc2H@JH)HH= iH- ;EfOHtnH}tgHEL}HD$fDHD$J,HtH5uH;8H!H5lHr;H@(HH5^HK;H@(HH5PH$;H@(HH5?H;H@(HH53H;H@(uHH5'H;H@(NHwH5H;1H*H5 Hk;1H5HIH@HH@t1H=[ H-| HE;H5 H;HHLHH;rH5 HN;HTHLHSHO;8H5L H;HHLH'H;H5 H;HLHHH;HD[H]A\A]/ƹ:Hh1H=hHHself, u1, u2Data::UUIDDigest::MD5adddigest%sselfUUID.xsclass%8.8X-%4.4X-%4.4X-%2.2X%2.2X-0x%8.8X%4.4X%4.4X%2.2X%2.2Xinvalid type: %d self, uuidself, nsid, nameself, str%2xfrom_string(%s) failed... invalid type %d klass1.227v5.26.0UUID.cData::UUID::newData::UUID::createData::UUID::create_b64Data::UUID::create_binData::UUID::create_hexData::UUID::create_strData::UUID::create_from_nameData::UUID::compareData::UUID::to_b64stringData::UUID::to_hexstringData::UUID::to_stringData::UUID::from_b64stringData::UUID::from_hexstringData::UUID::from_stringData::UUID::CLONEData::UUID::DESTROYNameSpace_DNSNameSpace_URLNameSpace_OIDNameSpace_X500self is not of type Data::UUIDcouldn't construct new Digest::MD5 objectDigest::MD5->digest hasn't returned a scalarDigest::MD5->digest returned not 16 bytespanic: MUTEX_LOCK (%d) [%s:%d]panic: MUTEX_UNLOCK (%d) [%s:%d]Data::UUID::create_from_name_b64Data::UUID::create_from_name_binData::UUID::create_from_name_hexData::UUID::create_from_name_strpanic: MUTEX_INIT (%d) [%s:%d]>?456789:;<=  !"#$%&'()*+,-./0123ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/;L\@pl !{p!{ @@ E" ON/ lX90  L   =  L L5  ()/ 4  z (  W 4  ( d <R T# >U#W VW I8(v 7xy !yE  zy |E <y f 5Bf 9+8u1E(C H#E2FHG {X L'*HQ Zm%  y /+"h q#p <*$x ,'  L @  L *!1%N6O _ L r! ;'C v( y@ )H _ L*Syb@ 4A 8 9: B'; ?7 )A y X%B y C Gh 9I B'J K O 9Q B'R @S y u@T +U a Ic 4 )d 4^eg Y* 9[ 4 ]f ,h  lN An (o y t v 4 7w y xE p3]5!<6D_rtL7p7Vh%3iBp*=yN y L $ D ,& y k( y * y {0 y 4{ |eye4DP  L@q^&_&*p,!($p@2 ya77 y; y 9 /< d4 @ A {Q L Q1\\fqq{3 B6 9 1  6  = 'W  ; l? "  \  g g q )| |  *   8   -<   V   < a v    W ' l 2  =  H  S  ^  i # 6 T!t x{w M ]= M> k L w L  L ? a  1  -M L s?. F>0 ?35  I = => @  l(A {C y$ !E ( [J 0 75N@8 T&PL@ ~[/H K0\/X 9#]/h /j x d. L p> L@ . @0 y[  @ . B0 y]   y ]!4 =!6 y #!7 y  ) "-pQ5".p 4# : # p =#  #y :#  $bo $d p -$e  T$fy $gy @+$h  } $ <$ pJ?$ Z$yb0$ p)$D 7$F pu1$G '@$Hy 9%> t% ;% H$%9 s0% - I%! > {N L&%% t%' ;%( H$%)9 s0%*- I%+ >DIR&6IV'vUV'wLNV'E=!( y'/ OP'1 op() )1 #)1 2)|J )Hg))E   )E 5)E ?)E ()E C<)E )E /3)E )0" )0#COP'2  copP*yF*z1#*z12*z|J *zH!g)*zE  ! *zE !5*zE !?*zE !(*zE !C<*zE !*zE !/3*zE *z0"*z0#*}_1$G*H(@=* p0* ,18U * ,1<%*\P@t.* bPH'8 S r`) )1 #)1 2)|J )Hg))E   )E 5)E ?)E ()E C<)E )E /3)E )0" )0# ) 1( v3) 10()H8,5),1@X) JH)JP/,) 1X!'< >P))1#)12)|J )H!g))E  ! )E !5)E !?)E !()E !C<)E !)E !/3)E )0")0#) 1(v3) 10) 18) 1@!) 1H 'G " '% B/+#1#Iop+$1 0+%1 +'1 ;>+(1 +*_( +,10 +-14 ?+/_8 g +01@ } +11D +31H a:+4P +5X (+6` #!+8,1h +:_p f<+<_x a+=_ +A0 y+C E2+E1 $+HJ %5+KA V+LA /+N1 =+O1 M<+^ 1 Y+`0 @+a0 5+b1 s(+n0 ,+u0 {=+z1 $+{1 :/+}FS +~1 0+_ 5+1$i=+$+1$+1$+A$t+ _ $? +&_($&+I0$#+%8$ $+%P$z +%h$)+N0$ +N0%ISv+1$+,_$41+1%Ina+$N+M $+M $7&+1 $"+1(%Irs+10$+18$+1@$?+1H$+P$?+1X$=+1`$9+1h$P+1p$+qQx$i+qQ$ 1+?P$+1`$"8+7h$+1p$9+1x$+1$(+1$+1$;+p$ +$,+ 1$t;+0$g +1$+1$2+1$+1&+2_& + ^&+/ ^&+=^&5+?&?+@p&+B,1&9+D,1&+Fy&W+Iy&a+J & +K1(&+L10&:6+M18&%+Np@&:7+OH&u +P1P&A+Q1X&:+T1`&+UB_h&8+Vp& +X1x& +Y1y& +Z1z& +[1{& +\1|&R +]1}&+^1~&+_1&+ap&+b1&+d&O+f1&*+h1&P+l1&j:+oy&)+pH_&#+s1&+t1&Q+u1&5+v1& +w1&@+z1&:+}1&,+1&+1&>+1&7+1& +1&X6+1&:+1& +N_ & +18&"+1@&I=+1H& +1P&+1X&+1`&+1h& +1p&:+1x&+p&JB+f<&P+1& +1&6(+1&X+1&r'+FS&<+y&"+y&,+p&7+^_&1+p&+1& "+1&$+1&0+y&^+1&fA+1&7+1&$++ 1&+y&+1& <+1&7+d_&1+1&4+j_&/+ & +f<p&B+Ix&+H&A+H& *+f<&,2+y&+,1&+$+1&+1&F +1&+1&A+&n+&+&4+'Ian+ ,1&@+ ,1&%+,1&$+,1&/+,1&3+& +p&+t4&+!p_&0+#=1`& +%,1d&!+'kZh&7+)1p&5++1x&"+,H&+.H&-+/H&[?+1H&+3H&;+6p&^"+7&+8&+9,1&6+:0&+;1&9+=0&/+>1&26+F1&;+G1&P +L]&*+N1&i+SS&+Wy&%+Y1&v4+[p&l8+\1&A +a1&" +b1&j,+c1 &<+d1 &+f1 &+g1 &w,+j1 &1A+k1( &+l10 &0+m18 &W#+n1@ &b6+o1H &L++p1P &)+r_X &?+s_ &>+t_( &82+u1 &!+v1 &m#+w1 &,+x1 &#+y1 &+z1 &+|1 &,+}D &2+~ &t+_ &A+0 &N7+1 &@+1 &4+1 &-+1 &;+_ &%+1 &+9+4 & +1( &6+10 & +_8 &K%+H@ &+HH &6+_P &.+1X &~+1` & +\4h &.+_p &+_x &>+1 &+1 &>+1 &o)+1 &"+1 &=+1 &+,^ &I+1 &++1 &n>+ &+Z &&*+Z &$+Z &0)+Z &?&+Z &s +Z &_ +1 &1'+1 &z +1 &^ +1 &}!+1 &>+1( &6+_0 &A+^_8 &W+]@ &;+^ &?+ _ &0+ y &9+,Z & +"_ &A+-H &+/ SV'O 0%%sv,q% ,,4 ',,1 ,,1 ,5AV'P }%av,% ,,q9 ',,1 ,,1 ,8HV'Q %hv, & ,,9 ',,1 ,,1 ,w9CV'R &cv,X& ,,8 ',,1 ,,1 ,g84'S e&,&,,7',,1,,1 ,:GP'T &gpP- g' <- 1 $- H 4- f< &- ,1 - ,1 H7- 1 4- 1( 5- f<0  - 185-E@&-E@ '- ;HGV'U s'gv,' ,,a8 ',,1 ,,1 ,7 io,',,:',,1,,1 ,9'W ( `*?$()*CTu<`*(g* 0#* 04* 1H* 1K* 1)* 1 0* FS?B* A=* * 1(,*R0('Z ( ~0.P) (. ; . gU 9. 1 sA. { $. 0 2.  . 1 04. p(XPV'[ ]) xpv ,)/,1&,;v,0,;'\ )(,*/,1&,;v,0,;=,b; 'b * ~@(/ b* // 1 &/ ; 3/  =/  '/ 1 b'c o*  0* /0 1 &0; <,0 0'd *0,4!+/,51&,5;v,50,5$<=,6b; ",7;('e .+ {Ah1 + /11 &1; v1 01I A-11 11I( E1I0 1I8 &1p@ A 1JH [1f<P 81,1X 1I<\ y711`'h +,^ -/,_1&,_;v,_0,_x<=,`b; / ,b7("B,o<0*,q 8,r @|*,s H;,t pP0,u 1X,v p`+=,w 1h5,x pp9 ,y 1x3,z {,{ 0('i - - @. - . T s=. T . U ':. T 8. T M@. BU( A8. aU0 ,. T8ANY'j -(any'.) ' 4)['1):'1)c'1)h'1)'1)'1)'p) ')8' 1)' ,1)' )' )W;' )V/' 1)' w1):' 1z5'{.>'|ZP;'}# '~ 4'l .n40'4/''Z!'  ' '&Z'Z 'Z( 'm A/B(,b/,1,c1$,d),e1B,f1 ,g1  'q / 2/ < 2  J2&$I 2' ,1 M22( ,1PAD'r q%'s / (2+N0 2,  <2-RI 42.   2/H  20 ,1  't [0 * 02L0 A2Mp B52M1 #2M^I n22M,1 .2M,1 (2M,1 6=2My$ +2M0( 2M0)I83SU83-0I163f0U1639 1I323y1U323E,1*,1 81M1+B1Y<3M13< ,1w14l10'w 6X@'y %111g'q%%11141 ?41t3 $43y 46 p 47 p 748 p f149 p +4: p( 4; p0 4< p8 4= p@ 4@ pH b4A pP 4B pX Y.4D3` =4F3h .4Hyp (4Iyt '4J x 744M9 4NS 4O3 74Q3 )?4Y 4[3 4\3 ?4]3 "4^ 4 ?4_  =4`y G 4b3?51,4+31 {3 L333 {3 Lc63t3.63X 63a,7 y 4+ 4>74`,7 y=748<K4qr8>\4?428No4$97kK-:4:: 1m': pl': 1,: 1K-:4-E,?5.m%.b. .!.d9..&. .4. . .c .i . .!.. HE,J5he0 ~5 60$ 7 G0% ; 0)OHEK,5hek 0-5 .0.,1 0/1 5053,A6\,p,,,,1,7<,1,7,7 ,7 );7 /;1 &;; v; 0;= $;> =;=( %';10 "=;,18 $;@ ;H q;P w:;>X (;,1` :;,1d 2;4h ;,1p +;,1t ;>x ; ] ;p x;1 ); @; ; ; ;E*;E  ;f<A67?5&P4,a8\,p,,,,1,7<,1,7,7 ,7*,8\,p,,,,1,7<,1,7,7 ,7!+,q9\,p,,,,1,7<,1,7,7 ,7*,9\,p,,,,1,7<,1,7,7 ,7b*/,:)\,p),),),),1),7)<,1),7),7) ,7+/,;)\,p),),),),1),7)<,1),7),7) ,70`*,b;), )4, 1)@1, _1)V@, 10=,;)), )1, )?, ;)l, 1~50 B,;)z, ;)%, (/,;)!,)6 ,p/,$<)!,)6 ,p/,5I<)!,5)6 ,5p2,: ,1f<1f< &V<//,_<)!,_)6 ,_p/,l<)&,m<)`;,n 4 4<+<&<< [;= $;0 u0; 0 1; 1[;< " (;&t= X;'  ;(  F;) 1 A;* 1 ;+  ;-= 6;. 0 #;/= %== L 2;:= c ;; #end;<  ;C 2;D=X&=;>!;6 ;p $h;> <;G? ;? ;? 89;? ;? A;@( ;=@0 >;a@8 ;@@ \(;@H ,;?P 9;@X <;A`>>t==);A6 2;? $4;  F;?.;>1=G?11,1.?11?1=ppp14,1M?1p?1=1pp81?"??11?1=??1=?@1='11?2@1='18@+%2@@11a@1=8@'1C@11@1=1181g@11@1=8@81@14@1=@4/@1=A11y1>=A,1,11@2P;h A3rex;i A&5;jAx;l1] ;np);o  @;p ( ;q 0';r;83pos;s @;t 0H>F1;uA2 ;| B1;}B;~LB;B; pA@ x;LB ; y ; p3u;PGB"u;\B2 ;]H&;^Bx&>;^"BRB_/;AW; 12;B<;LB2; C<;LB; ,1+; ,1 3cp;B2 ;YC<;LB; ,1+; ,1 3cp;B';YC=2@;D<;LB; ,1+; ,1 3cp;B,; ,1 ; 1 ;D 3me;YC(Y ; D0D; ,18; 1< ; 1> 102@;D<;LB;LB-;$LBO ;=3cp;B T?;B$;,1(3B;YC0~ ;p82;D<;LB6; 10; 1 3me;YC2 ; 'E<; LB; LB;  1l@; p2;@E3val; y28;E<;LB;LB3me;YC3B;YC3cp;B O ; 1$ ; y(!;" y,;# p02(;&1F<;(LBw&;)LB3cp;*BT?;+B;, p6;- 1 *;. 1$2`;1F<;3LB3c1;4 y3c2;4y 3cp;5B;6 ,1+;7 ,1/;8 1!;9 1 O ;: 1$3A;;YC(3B;;YC03me;<YC8;;=F@ ;>FN 0G L 2h;AG;B ,13cp;CB;D ,1+;E ,1 3c1;F y3c2;FyC4;G pW";H p !;I y(3min;J y,3max;Jy03A;KYC83B;KYC@;;LFH ;MFV/h;H)h/;B)1; A4yes;B) ; B),; C)!*;_C)U;D),;D)},;D)t;'E)|&;$@E)<;/E)P;?1F);NG@ ;QB HH L u;_RBO=KL'22 2!I 12"I 2# I 2$ I//2FI:2 FI2%LIIHXIN02MI22M1$2Mf<1I!16 1p1I,11&1-1Id#111l<1JS-1181;1*J1r<14) aJ&?)Hsv)1iv)uv)38)*J11|J1mJaJ/)J)r )1):) H) &)1/) J)[) 1)()  H %0>1HK >3 p I'>4 p 6>6  {<>7  F3>8 p >9 p 7>: p(  ?*K _)?, p %?- p 0%?.  37?/ 2@HK *@MK$W@VK$ @[K$/@bL$@i{$@nL {K5L {L5L {L5L {0L5Lw >HA+L A- p V A. p A/ A0 v A1 6A2( 3A40 A68 @A8L@6PBh yOBjpl Bk BqyO4Bup-Bv  7ByHK(wBzpHA9B{ PPB}OXB `E Bp7B ~BO5By[BpB 1B 2-Bp B )BO /By<B &=Bp&B &BO&FBJ&cBpH&D;B P& BOX&Bo `& 'Bp&,B &ABO&B0L&Bp&B &BO&dBO&B & BO&N,BO&-B & BO &+Bp(&_B 0&.Bp8&?B @&+B yHKHK   Jo 0L N"BL10&O30'1j0(  * 9P Y>*!9P 9*" *# y >*$ 1 *% 1O *(O@*WP 0KP|'(*'P# *( 1** I3cv*+ f<,*- 1=*. 1 y#(*3Q# *4 1*6 I3cv*7 f<3gv*9 1h7*: 1 O0*uqQ# *v 1#*x 1N(*y 1,B*z 13cv*{ f< 2*|qQ(?P/*Q4svp* 14gv* 12*Q3ary* 13ix* 2*Q%2* 13ix* 2*R3cur* 3end* 2*5R3cur* 13end* 1/*tR4ary*Q)6 *Q)4*Q)9*R>0*R* R&*wQE,*13*5R* I(x2*R>*1-* 1/0*FS)#*hP)w6*P)3!*Q)6*tR)R)*RW=X*T9* 0k* 0* 1 * 1p* /* * p* 1 j0*  1(q&*  p0k&*  p8*  p@*  4H*=P/`*@DT)"*A$()T=*BLS10*T3 * 1K*T*T7*T~* 1 !* 1$z* 1(* 1,'DT(*DT1yT11;T1,1U11;T1yBU11;11U1yaU1;@HU - C U#valC 4 C f C 1 C f< CmU (CV CV C 1 v%C p >C p [ C 1 U8C U>C"Y -C&Y 3C'4 {(C(y rC+y W C-y 6 C.Y C/Y(#psC0Y0 0C4 18 C5 1< C6 p@ !C7 pH /C8 0P &C9 0Q P"C; 0R %,C< 1S C= 1T C> 1X 83C? 1` C@ 1h CA 1p %CB 1r CC 1t CD 1x ] CE 1 CF 1 !CG  g?CH  ACI1 'CJ 0 CK 1 \'CL 1 !1CM 1 .CN 1 kCOY CP 1 y%CQ p =CT p =CU p CV p ?ACW p CX p CY p L&C^ _1 1C_ 1 -&C` 0 ZCa 0$d+Cb 1$Cc 7$@Cd 1$TCf Y$0Cg Y@$K:Ch 0T$(&Ci 0U$1Cj 0V$Ck 0W$4Cl FSX$Cm >`$x?Cn _1`$)Co _1d$7Crh$IACsp$9Ct{x$A#Cv1y7w$CxEx7CyEx7CzE x7k3C{E x$&C}1{$VC~ 0|VU V 4Y L 1 Z L>CV.Z!Z'eZ'1'$eZ>'$eZ,Z'Q}ZkZZ1yZ1'RZZZ11'S}Z:'UZZ11Z11b'VZZ[1 [+[ 8'u[9'w[c'y['{['}[i'[:'[7'['[+'[2'[N'[ [ L['[`!'[8'[5'[('[T:'['[*'[E'[ '['[!'[' 0U!' 0' 0 \ L@\_'\'[ \ L\ '\'\'4 ]+\o5']f'<~8'<'<('< -R]+'G]'< w]+;'l]'[8 $E']...1:.VA.3.q/.c$'4,>H'F]3pad'G] % ^ L#'P^^,^114'a9^?^11X^111"%'f|J'gr^x^11^11'h^f*'i^^1y^1pO'lZ's_3fn't 13ptr'u 45'v^-1THH Z pB_ Ly ^_ L_,1 4_ L 1_ L 1_ L 0_ L .1Ob4P)4 1_ L"/'1 '13D4+D&4 X^"`+6D` e^:`+q Dc/`cDM1 1_`+T`%D _` 1|`+q`$/D |`D [ D _` 0`+`#0D `'E&}1{E(1fE-1E11S1E41*EKt4T9ELt4@"EX}1DE[H_1?E\y6E]yQ$Ea.Ee}18Ef}1?Ei7' E}1#E}1@Ey&Eyb.E^0E1 E E}1E%JE1 -b LEa/'4xZ'6xZ-EF=b...D.7%.1.!.b .-.2.m" . + . .?@ .C! ."-.p9.. . )..9.p+.3.).r..a>./.*.S0..3; c Lb8Fc -'c LcPF 'c 0Hc L8cp'N Hc 1ec+Zc&#'bec 'cec'dec<'eec<)'fec7'gec-EGe. .:... .);.:...9< .$ .q ." .* .H. ..B....n. ..B....m. ....+.$ .!!.J1".2 #.+$.%."&.;'.+(.& ).i;*.c+.(,.z-...'/.0.'1.42.K3.44.J5.X6.;$7.W8.:$9.:.-(;.5<.5=.>.d ?.@.@A.#B.S'C.;D.IE.F. G.(H.4I.@J.K/'Ze4nv'Z4u8'Zee 0e LY*'Ze/'[e4nv'[4u8'[eei'[eH=E?H>93H?-)H@-L*HB#HR9f a2Hblf !Hc lf {|f Lb2HdQf A(Hff 1Hg f :Hhf W3Hif 0Hj!f rHk!f ^Hlf -ff LB(Hmff Ho8g#tsHpEf ^Hq|f#csHrfHsg &Hulg Hv8g 4Hw|f&HxDg9H\ B -g L9Hg A ;Eg >Fg#keyG#valH4g;Igg *N5h#aryO5h#maxP Q@h5hg*RhFh9mh P Fhmh9V}1 P 9o!)f 0P 990f  P 97 7f P 9#>f P :`82s; `1axe 1?},e 1@spe 1?e 1AD=j {>B` i>_pz 40.B i>_p| 4USB i>_p~ 4zxB j>_p 4B #j>_p 4BP Aj>_p 4B _j>_p 4 B }j>_p 431B j>_p 4XVBj>_p 4}{B@j>_p 4Bpj>_p 4Bk>_p 4B1k>_p 4BOk>_p 464B0mk>_p 4[YB`:nC/61~Dlen7 B lC:yE5<ܧkFU P FT0G]=FU AFQ =FR :H;9hlIJ$ E;NlFUHG<FU@FT8K;E;lFT =FQ0KD<EX<*lFT 0P FQ@Kb<Ew<7mFT|FQ ?FRvK~<E<*3mFT  P FQ@K<E<7kmFT|FQ ?FRvK<E<*mFT P FQ@K<E<7mFT|FQ  @FRvK<E=*nFT P FQ@K=G%=7FT|FQ @FRvK8E8DnFU  FQ {>FR s>FX m>K8K8K8E9QnFT >FQ P%K9E+9QoFT >FQ /K<9ER9QNoFT >FQ /Kc9Ey9QoFT >FQ /K9E9QoFT >FQ /K9E9QoFT >FQ /K9E9Q2pFT ?FQ ,K9E:QkpFT  AFQ ,K&:E<:QpFT HAFQ ,KM:Ec:QpFT pAFQ ,Kt:E:QqFT AFQ ,K:E:QOqFT ?FQ K:E:QqFT 2?FQ *K:E:QqFT K?FQ *K;E;QqFT d?FQ *K-;EC;Q3rFT z?FQ 03KT;Ej;QlrFT ?FQ 03K{;E;QrFT ?FQ 03K;E;QrFT ?FQ  7K;E;QsFT ?FQ "K,=LA=^M<4"^w; 41ZVsp6 1>ax6 1G7C},6 1C6 1NLBwC7:wC!"@fd$3?%Bt>tmpD +%K#K#K#E#ktFT|FQ2K$BuC(yztE#xtFU P GN%FU @FQ =FR (BuC,yE{$?uFU P E$^uFU P G%FU @FQ =FR ,H$ ) 3vN  NP L I J Oӣ$`z N N N I`J" JK E KS#Kt#K#E#vFT}FQ =K]$Eo$VvFU~FT|FQ}E$vFU|K$E$VvFU~FT|FQ G#%FU (@P$ZwCY K$K$H8#P6 wNI K #K#K-#G2%FU}FT =lgM" 7wJ{; "1 sp$ 1 >ax$ 1 C},$ 1] Y C$ 1 B xCy E7xxFU P Gl8FU @FQ =FR B0 RyCy; 5 E 8"yFU P G8FU @FQ =FR P$8yC. K.8K98H8M7 $ yNI Q;77szR^RHNi NT Su7gJv J20S7JJWUT77*zR#N|zR U7*J.K7G8VFU~FTwFQ}K7KC7KM7Kc7K7G{8FU}FT g>MJ403; 1 sp 1>ax 1RBC}, 1C 1}>ix1P3/|>_p4B #?7w>str p_UAfC3p>topyqVcy>iEVbufB@ /}@tmp Ke4K4K4E4k!}FTsFQ2K6P5t}C~zK5K5Q44 }NNNH6p ~N-+NSQNywH6 ",~N+Q866"X~RIQ866"~RIK3K3K3E3~FTsFQ0FR2K 4K34KC4EU4FTsFQ =E4ƨ1FUsE45ƨIFUvE5ƨaFUvK5E5uFQ0Ef6ӨFUsFT 7>FQ|K6E6FU ;>FTvE6FU (@G7FU V>FT|H8o3  KNIKd3Ko3K3E7FUFT ->K7 - LM*ƃ; 1sp 1>ax 1C}, 1e]C 1>ix1P"+>_p4RNBU?7wCƃB-@tmp K+K,K0,E@,kFT|FQ2K,Pn,rCKu,K,KV+Kx+K+E+FTvFQ0FR2K+K+K+E+FTFQ =KS,Eg,u,FQ}K,G,FU (@H8 +` }NIK+K +K"+G,FUFT >fM7Ç; 1sp 1>ax 1A/C}, 1C 1B0 ?7w>u1ƃ>u2ƃ >iyYUC"yC 1=7B`V@tmp KKKEkHFTsFQ2KBC KyKHGVFT|FQsKTKwKEFT|FQ0FR2KKKE;FTsFQ0FR2KKKK.KHK]EqFTFQ =KWKKK K%GiFU (@PRCKKH8 zNIKKK%GxFU~FT =MM,Z; M1 spO 1>axO 1#C},O 1CO 1  >ixP1Q M P2->_pP4 B0،?7VwCWƃ C4Y1! >ctx1P!L!A.ZAfAfBp@tmpc K$.KJ.K].Em.kFT|FQ2K/PW/݉C!!K^/Ki/Hm.#N+!!Q8..#1RIQ8..#]RIH.4N!!N ""W.ҊN;"9"NԤa"_"NȤ""W.@ N+""W8/p RIO8/ RIKg-K-K-E-}FT~FQ0FR2K-K-K-K.E.؋FT~FQ =K.K.E.*FTFQ@K.E.5FT~E.ޘMFU|E.ޘkFU|FTE.FUFT|K:/EP/uFQ}K/G/FU (@H8-O NI""K-K-K2-E/LFUFT >K/ -j LM'/Lʑ; 1""#6#= y>sp 1##>ax 1##C}, 1$$C 1$$>ix 1.%$%P30O>_p 4%%B LC7&w%%Ca~EfE&A&C f&&Af@fd3?B@ 1>tmp0  ''K0K0K0E0k#FTvFQ2K2P 2vC'|'K2K2HX 1 Ne''I XqE91ÏFU~G2FU hP H$l1 <I XKK1Ep2-FU~K2H1 YRN١((N͡=(;(O1 TNe(c(NԤ((NȤ((Kc0K0K0E0FT|FQ =K1E2u0FQG3FU (@H80 tNI((K0K0K30K3G,3FUFT =M#P%; 1)(sp 1))>ax 1*)C}, 1**C 1**B@fd`3AaZ?abEf?c>oned++C"wW+Q+B HCny++E%xFU P G&FU @FQ =FR nB`Cpy++E*&FU P G&FU @FQ =FR pP2&L?C 1D,>,K@&KP&KZ&Eo&*1FT}FQ =FRvKv&Q%%jN,,NԤ,,NȤ,,E%FUHE%ŞFUwK%7K&G&VFU}FTvFQ1P~&;C-,K&K&H8% cNI=-;-K%K%K%E&FU}FT =K&MB:: 0ؘ;.:%ؘh-`-tmp< p.}.Vlen= @Cv>1..>sp?1//B@ɖC,C_//KHK[KoKKCQRN&0$0NԤL0J0NȤq0o0K K*K2PK9KA]KKEFT~KKEjȗFT =FQ2KK,K6KAKNKVwKEFFTvFQwFR2KKKEFTvFQvFR1K E FU @G FU x@-M) @sp*1r1b1BC,-_$22KKKKKCK\KfKnPKuK}]KKKK E!j4FT =FQ4K(K2K<KGKTLdwKoKwKE̚FTvFQvFR1KGFT|FQ|FR1Z 1u>res122C<y22>sp1C333BC,_33KKKKK'CKKKPKK]KKE&*9FT =FQ0K0E;^FT|KFKPEdjFT >FQ2KnKEΜFT|KKKKKwKKKE YFTvFQvFR1G=FU H@[Y 1'\u'g]u0.yQ^buf93U_toؘ^lenV^iyXWK'!RRRWV0)ERsRgWV)@iRsRgWV*RsRgOV*RsRg {5L4`9 |a+ؘF4>4bctx144c  ; #t "| ^r;}T  N 44N55G FUsFT K E ũڟFUsFT0K K E!*FTsFQ K !E!8FTsE"!ޘPFUvE-!nFU}FTvKS! {5L`* baL/L5D5^tpPEB ũFUwFT0K Efdu $eƃe.ؘf0*rfX9M9sy `P g7tEfdW eaW1g7XEf9"YEf hP 9 Zf dP 9M9[y pP dfE eFƃe:GfeaHEfe^I|fhinc! ;e !1ient!#@hiud!.4g!"df e 1it.shicb8e j4jg< ;h_i jg7@h1@h4d e #1it9shikeyOivala6_ent@hkgP; 4j_idg it2sh_ary5hgY2g% _i jg5hg5h_ent"@hf9x4itx0ãikeyxF_entzΣRhgȣf#h@hith5ãikeyhK_entj@hg.k f2Wmh/_tY mhlf1Ve  1mo"yi__s"ve" nm">4ez0>4e>ye>mj4ez0;eeo"yp4pp'f?18en1f!"mVen"mq`!ܧNТ55Nڢ66N66NĢ77J@7:7Wӣ`!pN77N77NZ8X8IpJ8}8J88r!:J9 9S!%sT""ǧN*5939N*5939U"J4^9X9J@99JL99JXO:G:W@"AN::N::N;;GS"ѩFUsv"FT0FQ| ~"3$tb nscJou;q;J{;;T/""G"FU =G "ܩFTv4$G!FUHuI uJuOOKu77KuI`uJ{uJ u>>JXuJu J/ u  Juy>y>J uI uI u33J u88K3 u::Jbu : :J u@@Luww6 v??u[8[8J u((Jz u/@/@J uffK ueeK u==J w77"% u%%Ju00J uJB uJuJ u~3~3Ju~$~$Jn uJ u"~ uw !D x""MuK%% $ > &I: ; 9 I$ >  7I I  : ; 9  : ; 9 I8 I !I/  : ; 9  : ; 9  : ; 9 I< : ; 9  : ; 9 I'I4: ;9 I?<&4: ; 9 I?< : ;9  : ;9 I8  : ; 9 : ; 9 I: ;9 I: ;9 I : ; 9  : ; 9 I 8  : ;9 ! : ;9 I 8 " : ;9 # : ; 9 I8 $ : ; 9 I8% : ; 9 I8& : ;9 I8' : ;9 I8( : ;9 ) : ;9 I*5I+!,: ; 9 -> I: ; 9 .( / : ;9 0 : ;9 1'I2 : ;9 3 : ;9 I8 4 : ;9 I5!I/6 : ;9 7 : ; 9 I 88> I: ;9 94: ; 9 I:.?: ;9 '@B;: ;9 IB<: ;9 IB=.?: ;9 'I<>4: ;9 IB?4: ;9 I@4: ;9 IA4: ;9 IB UC4: ;9 IBD4: ;9 I E1FBG1H1RB UX YW I UJ41BK1LB1M.: ;9 '@BN1BO1RB UX Y W P Q1RB X YW R1S 1T1RB X Y W U V4: ;9 IW1RB UX Y W X41Y1Z.: ;9 'I@B[.: ; 9 'I@B\: ; 9 I]: ; 9 I^4: ; 9 I_4: ; 9 I`.: ; 9 '@Ba: ; 9 IBb4: ; 9 IBc : ; 9 d.: ; 9 ' e: ; 9 If.: ; 9 'I g4: ; 9 Ih.: ; 9 ' i: ; 9 Ij k l.: ; 9 ' m.?: ; 9 'I 4no.?: ;9 'I 4p: ;9 Iq.1@Br 1s41t 1Uu.?<n: ;9 v.?<nw.?<n: ; 9 x.?<n: ; #g /usr/lib64/perl5/CORE/usr/include/bits/usr/include/sys/usr/include/bits/types/usr/lib/gcc/x86_64-redhat-linux/8/include/usr/include/usr/include/netinetUUID.cinline.hUUID.xsstring_fortified.hunistd.hptable.hstdio2.hbyteswap.htypes.htypes.htime_t.hstddef.h__sigset_t.hstruct_timeval.hstruct_timespec.hthread-shared-types.hpthreadtypes.hstdint-uintn.h__locale_t.hlocale_t.hsetjmp.hsetjmp.h__sigval_t.hsiginfo_t.hsignal.hunistd.hgetopt_core.hsockaddr.hsocket.hin.hstat.htime.htime.herrno.hnetdb.hnetdb.hdirent.hdirent.hperl.hmath.hop.hcop.hintrpvar.hsv.hgv.hmg.hav.hhv.hcv.hpad.hhandy.hstruct_FILE.hFILE.hstdio.hsys_errlist.hperlio.hiperlsys.hperly.hregexp.hutf8.hutil.hpwd.hgrp.hcrypt.hshadow.hreentr.hparser.hopcode.hperlvars.hmg_vtable.hoverload.hUUID.hpthread.hproto.hstdlib.hstring.h K  Xf|X#  |<J . X tJ<K$$.$*$f<t$~1*<K~ ;/X%X.%<.;<.G<.<[Z!XYY8Jf << X< XLf($w$ pn }N,> J ffX-KW?  -=X> fJ ,> V?t~tt X, ,אY-= J tfY-XJK-JW?v,>u-=J-yt f9 .%9o.Z,> J ffX-KW?  -/X>  <K }=.. w(ot XyXSX?  ~ ?o.t<Y!@2KJJ 50/  :Z dLY  Y s=J<XYJ  K H 4fL. 4L. 4fL. 4J L < 4N <JJK  <Yf3 J q   X K K J= K K I .JY RWK 9Y=< ? A?. AJX KL9Kg<<\<Y=J=Kx<JK  <f  K sKKZj.tzJp} P%N /s .XX}X#  }.J < X JJ<K~~:>YK} Z rhXtte:Z-=XK tt.`< ~X4 '~ ~"4X ~J4X ~X4</~  < HI/f<= tX<  1$J^r<iJ$J:<$=:;$K:;)J< .u1:J=:; K:I)Jt <u \pJU g <X< uC1$J >$H:<#/:;K:;)J. .u u\tU ; 5R,~ X#< <u r ~ . ~X ~X  ~X. ~ ~.t ~XX~J Z u$~ . ~X ~X  ~X. ~ ~.t ~J<~J Z  XK  XX{X#  {.J . X ;KK t<L&f& &XJf(.K~ . X J <K&o xs , Ks .XX|X#  |.J . X ;KK t<L&& &) Xw<< Xw.~/(.K~} !L }f.!dK|| Y -=X .<XY }  ffJ |.X .K  XJY  XJK$t X JX <KtJ&\< fk) Ks .XX|X#  |.J < X ;K ;J=K Lft~f(.|Jf=~ Y }  tw X/s uJY} 1}1}JJY}.Z XJX Z3J3< <h XK5Xt"<h XKo<"< ofX < t J <=}|   JXXJ.R 7/   Z''I K,z`|  Jg |f. K||Xu~ Jl~K  XXzX#  z.J < X JJ<K} }XXu  K IYgu ~tdKt"(JX  JfJXX.}t} 8N  X)Xt   -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y-< uXY  -< uX Y -< uX Y -< uX Y -< uX Y -< uX Y,< vXZ}|tX=|[ = X  |tLXt3:::vH>><,|Xuuidptable_storeIlaststatvallong long intold_parserPL_locale_mutexblku_oldsaveixIorigargcIorigargvsi_errnokeeper__pad0tbl_arena_next_spent_sizeIin_utf8_CTYPE_localeRETVALSVhostentls_prevclose_parenPL_no_localize_reflex_stuffIlast_swash_hvxpvgv_readdir_ptrIstatcache_freeres_bufIcompilingIdbargsnew_perlblku_oldspsub_error_countformat_uuid_v1format_uuid_v3xpvhvPERL_CONTEXT_asctime_bufferInumeric_standardsigngamprevcomppadIe_scriptsv_u_servent_structPL_sv_placeholderIpreambleavIDBcontrolxpvioxpvivtbl_maxsi_tidImy_cxt_sizeblku_old_tmpsfloorImain_rootxcv_outsideblku_type_PerlIO__localeshe_valuIutf8_totitle_spent_structnamed_buffwant_vtbl_hintselemPL_freqh_lengthop_firstXS_Data__UUID_create_from_nameIdoswitches_netent_sizethrhook_proc_tnext_branchPL_op_namePerl_newCONSTSUBblock_evals_port__in6_uPL_no_wrongrefin_port_tgp_refcntprev_markIdef_layerlistsaw_infix_sigilIrestartjmpenvsave_lastlocIwarn_locale_spent_bufferIcolorsmg_objje_old_delaymagicfallback_amgmulti_endPerlIO_list_sPerlIO_list_tCOPHHscream_posIargvgvmake_retdespatch_signals_proc_trshift_ass_amggetdate_errxio_flagsIsharehookold_regmatch_statexcv_xsubnextwordIminus_EIcheckavpad_1pad_2ImarkstackPL_bitcountIdump_re_max_lenxcv_flagsPL_warn_nlIstatusvalueIDBsingleutf8_substr__u6_addr8min_offsetPL_warn_nosemipmopsscanfst_atimsival_intIlast_in_gvIreg_curpmshare_proc_tIhash_rand_bits_enabled_uuid_state_t_call_addrlong doubleop_privatelex_formbrackSVt_LAST__chsbu_dstrIrunopsIpsig_pend_ctime_bufferIcomppad_namePL_magic_vtablesImarkstack_maxsbu_iterssi_type_IO_wide_datainternalIreentrant_retintreallocINonL1NonFinalFold__spinsmax_amg_coderandomness__blkcnt_tPTR_TBL_tPerl_call_methodxhv_max_protoent_sizeperl_uuid_time_t__bufPL_no_symrefhent_hek_grent_ptr_getlogin_bufferxivu_eval_seenPL_curinterp__locale_data_eC_pthread_mutex_lockPL_hash_seedpos_flagsIstack_baseexecMD5UpdateImax_intro_pendingposcacheop_pmstashstartuto_gv_amggroupsbu_strendsmart_amgre_scream_pos_data_scop_stashoffs_addrst_sizePL_opargssge_amgpthread_key_tIperldblastparensi_addr_lsbIinplace__locale_t_pkeyPerl_pop_scopeIDBlinewant_vtbl_nkeysPL_bincompat_optionssin_amgIsv_arenarootjumpPL_uudmapgp_egvnewvalpadnamestatesxio_bottom_gv_unused2Iphaseyylensubbegcos_amg_asctime_sizeIblockhooksend_shift__nuserssbu_oldsaveix_pwent_ptrIosnamen_addrtypelex_casemodslex_brackstacknumbered_buff_STOREIefloatsizePADLISTIpeeppPADNAMEIregex_padretopprogram_invocation_namexcv_padlist_uminmodsp_pwdpIutf8_foldclosuresPL_checkIsv_yesparenfloorPL_op_private_bitfieldsbranchlikeJMPENVImain_startqr_anoncvIstashpad_archmy_perlPerl___notusedIenvgvIperlioIpadname_constPerl_xs_boot_epilogpow_ass_amgmult_ass_amgIregmatch_stateprev_rexstderrIisarevIutf8localeIsignalhook__ownerPL_Noop_optc2_utf8__ino64_tgettimeofdaysa_family_tsockaddr_inarp__pthread_list_tsubcoffsetsvu_fpyy_stack_frameIdebstashtopwordwant_vtbl_ovrldreg_substr_datumsi_stackxpadl_maxInomemok__uint8_tfirstposwant_vtbl_debugvarIdiehookprev_recurse_locinputany_ptr_readdir64_ptrCLONE_PARAMSIcompcv_vtable_offsetconcat_ass_amglex_repltimespecPL_interp_size_5_18_0PerlInterpreterxpadnl_max_namedPL_check_mutexxpvlenu_pvILatin1st_nlinkIminus_Fre_eval_strIscopestack_ixsp_maxIscopestack_maxiter_amgIminus_aany_pvpIminus_cIminus_lIminus_nIminus_pIargvout_stackPL_op_seqIinitavPerl_newXS_deffilesin6_familytbl_itemsbase64Perl_ophook_tcache_maskPL_no_dir_funcfirstcharsImaxsysfdIlocalizingsrandlex_sharedretvalservent_crypt_struct_bufferPL_op_private_labelsrxfreencmp_amg_IO_save_endpw_namesp_lstchgcurly_getlogin_sizenomethod_amgadd_amgPL_sig_nameIunicode__fmtblku_subqr_package__errno_locationneg_amgIrestartop__timezonePL_thr_keygofs__mask_was_savedPERL_PHASE_CONSTRUCTIlastgotoprobecop_lineIsecondgvnet_nsid__locale_structIsavebeginwant_vtbl_vecinitializedXPVAVto_av_amguserdataSTRLENexitlistentryabs_amgop_ppaddrxpadnl_allocIcheckav_saveIdebug_pad_IO_backup_base__jmp_buf_tagconcat_amglex_flagsIendavblku_oldscopespIutf8_idcontIcomppad_name_fillmy_opIHasMultiCharFoldglobhook_ttmpXSoffXPVCVpthread_mutex_unlockPerl_savetmpsPL_sh_pathmark_stack_entry_sys_errlistPL_hash_seed_setregnodestdinIperl_destruct_levelsi_cxixmg_virtualpadnamelistXS_Data__UUID_CLONEoptoptinterpreterPL_warn_reservedgethostidPMOPIstashpadixPerl_xs_handshakest_uidlongfoldsp_min_IO_read_endxcv_xsubanyPADOFFSETPL_valid_types_RVIstatbufsbxor_amgtimestampsbu_rflagsxpv_cur__gethostname_aliasxpadn_flagsIstderrgvxio_page_lenperl_memory_debug_header_IO_save_baseIin_clean_allmark_nameop_flagsold_regmatch_slab__ino_treg_substr_datalex_super_state_grent_structxcv_root_ucurlymsettingPL_uuemapPL_nanPL_magic_dataIcustom_op_descsPL_hexdigitsi_prevXPVGV_addr_bndsp_namp_IO_write_endlex_startsinstancesIsavestacksi_codeImodcountprev_curlyxIsortstashPL_mod_latin1_ucIstdingvsvt_localsp_warnIcustom_opssbor_ass_amgCHECKPOINTXPVHVany_avsprintf_grent_buffersne_amglast_uni_IO_buf_baseXPVIOsp_expireXPVIV__uint16_tminlenretIofsgvunsigned32TARGi_ivIdelaymagic_gidxcv_gv_uIcollxfrm_multtbl_arena_endIsavestack_ixwant_vtbl_defelemPL_C_locale_objmallocsockaddr_x25SVt_PVAVsin6_flowinfoxmg_magicsvu_gpany_dptrintuitIbody_rootssi_sigvalhek_lenIcollation_ixtokenbufwant_vtbl_packelemop_nextopline_tget_current_timemgvtblPL_valid_types_NVXPL_runops_dbg_readdir64_sizeIutf8_xidcontsi_cxstackinstances_mutexptable_walkyyerrstatus_hostent_ptrsbu_rxMD5InitS_croak_memory_wrapxcv_padlist_IO_markerPL_revisionsvt_get_Boolsvu_iv__prevIsort_RealCmpsbu_rxtaintedseq_amgdiv_ass_amgop_moresib_flags2xpv_len_uIpatchlevel_pwent_structnextvalsvu_pvany_gvmemcpynot_amgIhash_rand_bitssbu_origcurentp_IO_lock_t__gid_t_IO_read_ptrIparserboot_Data__UUIDxpadlarr_dbgstack_max1runops_proc_tany_hvPL_subversionIpadlist_generationSVt_PVFM__environxpadnl_maxIdefoutgv_lowerIstatusvalue_posix_pwent_buffer__ctype_tolowersiginfo_tany_ivmax_offsetsv_flagsIchopsetIrpeeppoldcomppadPL_fold_localesbu_rxresSVt_PVGVIincgvsi_markoffxpadnl_fillwant_vtbl_arylenS_POPMARKPL_no_usymtv_nsecnexttypesig_slurpywant_vtbl_backrefIcurpm_underlshift_ass_amgclock_seq_lowSighandler_tpthread_getspecificsvu_hashin6addr_loopbacksvu_nvsband_amglex_inpatlast_lopsockaddr_ax25PL_isa_DOESptr_tbl_arenaSVt_PVIOSVt_PVIVfilteredIlastfdptablewant_vtbl_collxfrmPL_perlio_fd_refcntIeval_start_readdir_structIlast_swash_keyls_linestrPerl_check_t_readdir_size__alignPerl_gv_stashpvPADNAMELISTSVt_PVCVPERL_PHASE_START__srcxcv_hscxtany_u32Perl_croak_nocontextXS_Data__UUID_to_string_ctime_sizeget_random_inforepeat_ass_amgop_pmreplrootuptable_splitd_inotv_usecIsavestack_maxwant_vtbl_arylen_pIlocalpatchesIsv_rootSVt_PVLVp5rxop_next__saved_masksvu_rvsvu_rxsockaddr_eonany_opIcurstackSVt_PVMGIpadix_flooruuids_this_tickPerl_push_scopesi_statusxpadl_arrh_addrtype_strerror_sizeIdelaymagic_euidbufendPerl_newSVpvlex_inwhatany_pvPL_valid_types_PVXatan2_amgxnv_nvPL_phase_namessin_zeroIopfreehook_protoent_ptrIunitcheckavsvu_uvPerlIOlsgt_amgto_hv_amgprotoentmg_lenImemory_debug_headerPL_no_modifyany_svSVt_IVItop_envwant_vtbl_sigelem__blksize_t_IO_buf_endshort unsigned int_spent_ptrbool__amgItmps_stackyy_lexsharedoffsPerl_newSVsvIseen_deprecated_macrowant_vtbl_substr_IO_codecvtIsv_undefIpsig_nameLEXSHAREDclone_paramsperl_drand48_tIgensymPL_fold__bsxIregmatch_slabop_redooprsfp_hostent_structstart_tmpxio_fmt_namesvt_lencop_hints__lenh_namepthread_mutex_init/home/.cpan/build/Data-UUID-1.227-0IerrorsPL_no_memxpvlenu_lenh_aliases_hostent_sizePL_Yesperl_uuid_timeop_pmreplstarthent_refcountsaved_copylex_sub_inwhatany_uvItmps_floorPL_do_undumpIstrxfrm_is_behavedindex64xpadl_iddec_amgint_amgIbasetimeIop_maskIsighandlerpunreferencedxpadnl_refcntIUpperLatin1xio_ofpNameSpace_OID_hostent_buffercop_seqmulti_startSVt_PVHVop_pmreplroot_shortbufSVt_NVIDBtracemaxlenpre_prefixop_targIbeginavje_retresume_statePL_dollarzero_mutexIsv_constsclockseqpw_dirlex_casestack__bswap_16op_lastopIsub_generationblku_evalfloatwant_vtbl_isaelemPL_versionPL_no_securityNameSpace_DNSIutf8_foldable__countunsigned charsi_cxmaxmulti_open_killsubtr_ass_amgst_rdevLOOPILB_invlistSVt_PVnodeIDwant_vtbl_dblineREENTRImess_svIglobalstashImin_intro_pending__suseconds_tPL_perlio_mutexexpectoldlocIcollxfrm_basewant_vtbl_envelemtime_lastcopy_amgIutf8_perl_idcontcx_blkIstatnameRETVAL__builtin_memsetmodulo_amgxnv_ugethostname__uid_tsin6_scope_idNameSpace_X500blku_gimmeptable_findPL_valid_types_IVXst_ctimrecheck_utf8_validityIutf8_tofoldxcv_rootISB_invlistblock_formatin_addr_top_sibparenttz_dsttime__dataXS_Data__UUID_newold_namesvlog_amgxpadn_type_uIAssigned_invlistpeep_tPL_my_ctx_mutexIsv_nominlen__off_tperl_phaseIin_clean_objssbxor_ass_amgd_reclenPL_mmap_page_sizePERL_PHASE_DESTRUCTin_podPerl_stack_growgp_ioImultideref_pcIors_svstring_amgxpadn_protocvIevalseqIunlockhookregexp_enginemg_flagssubtr_amgIcurstashgr_passwdPerl_markstack_growPerl_ppaddr_tgr_gidwant_vtbl_checkcallIstashpadmaxsi_overrun__clock_tSVt_NULLls_bufptrIbeginav_savenewsize__uint32_tIorigfilenamexmg_hash_indexlast_lop_opInumeric_localcop_warningsPL_op_private_bitdef_ixIcop_seqmaxop_pmtargetgvPL_veto_cleanupform_lex_stateIstatgvIdestroyhookcoplinest_blocks_sys_siglistsbu_msbu_ssave_curlyxIcomppadsub_no_recoverlex_dojoinxmg_u_uuid_context_tdirent64gp_cvgenPL_utf8skipxcv_fileSVt_PVNVitervar_ugp_flagsxiou_dirp_servent_bufferPL_op_mutexparen_namesIregistered_mrossi_uidpw_passwdsqrt_amglex_allbracketsopvalIcurcopdbblock_subpos_magic_old_offsetgp_file_heksv_refcntsockaddr_in6__nlink_t__buflentbl_aryXS_Data__UUID_createsband_ass_amgxav_allocsi_fdnparensPL_no_funcxpadn_refcntscmp_amgIeval_root_perl_uuid_told_eval_rootnamed_buff_iterst_gidIdowarnyycharIfirstgvrshift_amgmg_moremagicop_pmoffsetop_pmstashoffPERL_SIMGVTBLop_staticMAGICPerl_sv_newmortalItmps_maxoptargPL_latin1_lcwant_vtbl_packsockaddr_ipxtimevalIthreadhookPL_valid_types_IV_setblku_givwhengr_nameop_typeIutf8_perl_idstartsublenblku_oldmarkspxivu_ivIutf8_swash_ptrs_netent_ptrwant_vtbl_regexpIpadname_undefpreamblingproto_perlbyte_uppercx_uoutputIDBcvPL_sigfpe_savedtrieIlockhooktrue_random__ctype_toupperunsigned64_tPL_inf_xnvuPerl_keyword_plugin_txio_lines_leftcompflagssockaddr_isopthread_mutex_twant_vtbl_utf8Iin_load_modulePL_memory_wrapxio_pageget_system_timesigjmp_bufpow_amgwant_vtbl_hintsdiv_amgIlaststype__ctype_b__listh_addr_listIutf8_charname_continuein_my_stashwant_vtbl_regdataxpadn_len_IO_write_ptr_strerror_bufferadd_ass_amgdummyIunitcheckav_savePL_op_descsi_stimePL_no_aelemlastcloseparenshort intifmatchIdumpindentIoldnamepreambledop_code_listxhv_keysitersave_readdir64_struct_sys_nerrIAboveLatin1Iutf8_mark_servent_sizesi_signoIDBgvIlast_swash_tmps__namessv_anyblk_uxcv_startacceptedgvvalIWB_invlistolddepthIutf8cache_boundsprev_evalIpadixdefsv_savewant_vtbl_lvref_netent_bufferxcv_stashYYSTYPExcv_gvGNU C17 8.5.0 20210514 (Red Hat 8.5.0-22) -m64 -mtune=generic -march=x86-64 -g -g -O2 -fexceptions -fstack-protector-strong -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection=full -fwrapv -fno-strict-aliasing -fPIC -fplugin=gcc-annobin_markersPL_keyword_plugincop_hints_hash_filenoIcustom_op_nameslex_sub_replstdoutsle_amgxpadn_highre_scream_pos_datahek_hash_ttyname_bufferPL_hints_mutexIknown_layers_netent_errnoItaintingPL_op_private_bitdefsIcurcopIstack_sp__ssize_tany_boolregmatch_info_auxPERL_PHASE_ENDPL_interp_sizeIcollation_standard__glibc_reservedwant_vtbl_taintlex_deferxmg_stashPL_runops_stdIorigalensbu_maxiterssockaddrIdebugrefcounted_heIcurpadPL_op_private_valid__time_t__daylightst_mtimwant_vtbl_uvars_protosbu_targd_type__destlogicalIforkprocesslex_bracketsxio_top_gvIutf8_tolowerclock_seq_hi_and_reservedPL_op_sequenceblku_oldcopperl_mutexIcurstackinfoIstart_envlex_fakeeoflex_sub_opstashesIstashcachexnv_linesmult_amgPL_use_safe_putenv_IO_write_basep_aliases_netent_structin_mytime_lownext_offxivu_uvsin_portpadnlImodglobalin6addr_anyICmdsockaddr_atregmatch_info_aux_evalxcv_start_uPL_no_helem_svwant_vtbl_envbasespIgenerationIGCB_invlistIstrtabxpadl_outidoldsize_uuid_node_txpadn_lowblock_givwhenregexp_paren_pair__sizeptable_newcrypt_datapprivatecv_flags_tcur_top_envxpadn_typestashIin_utf8_COLLATE_localeIlast_swash_slenstate_uPERL_PHASE_RUN_sigfaultop_sparelex_opst_inopw_gecos__pid_ttime_hi_and_versionparsed_subop_lastPerl_free_tmpswant_vtbl_regdatumxio_typeyylvalPerl_sv_derived_fromsp_inactsockaddr_dlxav_fillhent_valIorigenvironunsigned8Idelaymagic_egidgp_avftest_amgscream_oldsmg_ptr_cur_columnmaxposXS_Data__UUID_from_stringsa_familyptr_tblInumeric_namelazyiv_sifieldsnodeidSVCOMPARE_tSVt_REGEXPIpsig_ptrgp_cvxgv_stashnetentsaved_curcoptv_secblku_u16Iprofiledatasbor_amg__sigset_tgp_lineImainstackIcurpmop_pmflagsst_blksizexpadn_ourstashprogram_invocation_short_namePL_sig_numptr_tbl_ent_hostent_errnoop_slabbedscompl_amgIsublineIargvoutgvIwatchaddrIdefgvhek_keyPerlExitListEntryxio_bottom_namegp_formIreentrant_bufferhent_nextcheck_ix__off64_tIunsafeIhintgvsockaddr_in__jmp_bufIDBsignalIutf8_charname_beginblku_formatPL_ppaddr__dirstreamsin_addrIXpvIregex_padavPL_perlio_debug_fdblku_loopcache_offsetwantedpw_uid_timerIstrxfrm_NUL_replacement__locksig_elemsPL_valid_types_NV_setgr_memIxsubfilenamegp_hvIpad_reset_pendingopterrdfoutgv_sigchldxcv_depthItaint_warnIArgvselfcallocpw_shelltime_nowsi_nextXS_Data__UUID_compare_syscallPL_no_symref_svIexitlistIsubname_IO_read_basePL_warn_uninitany_i32Ihv_fetch_ent_mhUNOP_AUX_itemsvt_dup__pthread_mutex_sPerl_sv_setiv_mgInumeric_radix_svPL_fold_latin1xcv_outside_seqPL_magic_vtable_namesPL_no_sock_funcIsplitstrxcv_heksvt_freesockaddr_nslong long unsigned intsi_addrdirentptable_fetchwant_vtbl_posIbody_arenascheckstr_grent_sizeinitedPL_csighandlerpSVt_INVLISTwant_vtbl_mglobIsortcopPL_warn_uninit_svsin_familyNameSpace_URLIsignalssbu_typesi_pidmg_privatedupeje_buflazysvItoptargetIstrxfrm_max_cpIerrgvPerl_sv_2pv_flagsinc_amgsvt_clearPERL_PHASE_CHECKMD5FinalnexttokePL_no_myglobItmps_ixIsig_pendingsubstrsany_svpintflagsdestroyable_proc_tIfdpidxpadlarr_allocivalany_dxptrn_netto_sv_amgtime_midPerl_croak_xs_usageclock_seqop_pmtargetoffIcollation_nameIefloatbufto_cv_amgmagic_vtable_max_pwent_sizeoldvalany_longxiou_anylshift_amgIexit_flagsc1_utf8ptable_entrepeat_amgIglobhooksin6_portPL_block_typed_offxio_top_namemodulo_ass_amgIptr_tableIcolorset__jmpbufIfilemode__dev_trcount__kindIexitlistlensockaddr_unnumer_amgop_foldedIdelaymagicPL_charclassImarkstack_ptrblockpw_gidprev_yes_states_name_protoent_structop_compgp_svsvu_arrayXS_Data__UUID_DESTROY__pthread_internal_listwhilemIInBitmapmother_re__valn_aliases_sigsysextflagsxio_fmt_gvxpadn_gencop_fileIcurstnamecx_subst__u6_addr16Isv_countsvt_setIdefstashItaintedtz_minuteswestIbodytargetoldoldbufptrxav_maxxiv_u_protoent_bufferst_modesavearrayPerl_sv_setref_pv_xivu_chainleave_opIutf8_xidstartre_eval_startperl_debug_padIstack_maxst_dev__u6_addr32je_prevwant_vtbl_svIclocktickPerl_sv_2iv_flags__syscall_slong_tIXPosix_ptrsIDBsubspwd__nextIutf8_idstartje_mustcatchnumbered_buff_LENGTHyy_parserblock_loopop_savefreeIscopestackIformtargetpad_offsetPL_perlio_fd_refcnt_sizes_aliaseslastcpIconstpadixmulti_closestatherelinesImy_cxt_listIPosix_ptrsunsigned16_freeres_listxivu_namehek__pad5__bswap_32_ttyname_sizesin6_addrIwatchok_IO_FILE__stack_chk_failPL_my_cxt_index__tznamep_protoPerl_sv_2mortalwant_vtbl_isasvt_copyxnv_bm_tailsival_ptrmark_locsi_utimexpvavIsrand_calledoptindstrlenregexp_amg__mode_tsp_flagperl_keyIreplgvsa_dataIbreakable_sub_genrsfp_filtersIin_evalsuboffset__sigval_t_servent_ptrlex_re_reparsingIutf8_toupperlinestartsig_optelemsPERL_PHASE_INITIcv_has_evalmg_typexpvcvnumbered_buff_FETCHIrandom_stateIscopestack_namesi_bandxpadn_pvIcomppad_name_floorUUID.cIdelaymagic_uidIwarnhookIlast_swash_klen_xmgu_sigpollslt_amgxio_dirpucur_text__elisionblku_oldpmImain_cv!!U!}&U!!T!K"TK"P"Pr"w"P""P""P""P##P5#:#P\#a#P##P##P##P$$P<$A$Pc$h$P$$P$$P" "P "\&]\&`&Ta&}&]P"["Pw""P""P""P""P##P:#E#Pa#l#P##P##P##P$%$PA$L$Ph$s$P$$P$$P%%P%Z&\a&}&\U%c%Pa&q&Pq&|&T/%;%P;%P%V ( U( nU , T, ] CTCR]RnT2 X VH M ^M k ~k \ 1 ~ \ ~5C\Cn~M Q ~ $ &3$p"Q U ~ $ &3$p"M Q v~ $ &3$p8 \ 5\Rn\v ] 0   \ 5\Rn\ ' PRbPbmT P)P)4T1 r \ \1 r ^ ^r | P 01 ^ 5^1 r \Q r P1 F |3%|:%'|D%'F M PM r |3%|:%'|D%' 07 H P@ ^ U^ !U@ b Tb ] p!Tp!!]!!Th V~ ^ ~ i!\p!!~!!\ ~ $ &3$p" ~ $ &3$p" v~ $ &3$p8 Pp!!P!!T@!M!P!!P!!TD!p!0m ~ P V P 4! 4!_ 4!V !!V!!]!!}! !Q !!!}PU6 UPT_5T5U_UT_ T 1 _1 6 TVSs]5^]]  ] s 1 ]s $ &3$p"s $ &3$p"P  Pvs $ &3$p8\5Z\\ 1 \  !,V5VS V 6 VS5PVP`S`gQgSQ So]o}}]0A_AHH_g w  w 511 6 145D@5D05D}pPUU"T"_T_T_(W^=BVBkvkK\\vBIv $ &3$p"ITv $ &3$p"TuPPBI~v $ &3$p8Mn]]BuVV1-=PUU#T#^>T>Q^QT^*S\^V{^@ESElslI]IS]"S"V]{SsELs $ &3$p"LPs $ &3$p"PsPPEL|s $ &3$p8^>^{^_"_{_Pbpvbfpw0 S S*S-:SPSV{S;\"\V\SV{S1/@P.U.U2T2_T_T_T8g^MRVRvx\\vRYv $ &3$p"Ydv $ &3$p"dPPRY~v $ &3$p8]]]R^^___Pk\w11UU@P=MP.U.LU2T2_=T=L_8dVNS]S{}{\V+}V}*8V=L}SZ} $ &3$p"Za} $ &3$p"SZv} $ &3$p8hT==DTDKq(KLS=KQ&3P3VdV*VwdP  |"ddP  |"+_]d~]]*]8=]&3P3VdV*V)d18=1+wmm*m]6=NPpUUpT']'T]T]V^X~X\~\~~ $ &3$p"~ $ &3$p"v~ $ &3$p811PVV-PPTJ_PPTuyPy]]6Wv11P;U;]U@ ]?T?^T@ ^PV2 @ V2KP$ - P\VV$ 2 VEVvxP\\V  V 2 \2 ; Pv\ \2 @ \<<@<<P<<]`wUw^U^`{T{}]}T]\VvbVVP\PVVPVP\P \P\O]\0V0PvxVvxV -V-2P2]VK\ J\JOP U m ]m n Un s ]  P i Vn s V   }@ ] U] S U S U U U ] T T T  S T Q Q Q + V+ Q Ģ P 0 ? P U U U ] U U U ] T P t3%t:%'tD%' P t3%t:%'tD%' p& ]/ ? UM P PP S/ ` V` | V7 w ^w Z ^ 0 Y P Y` r p3$r s | ~"3$` s 0` n sv"n r Ur s sv" X X R sv" R X x//2@a(orwz`{8Oa  ` ` h j n s 7 7 9 H e CRn   $ Rn$ * 1 r $ * 1 r 5  >RBGKPUXknPchmtuz{mt 38=DEJKPc=D--/=ekk`==?Mu=U ##(,116:==?Nu{{Ah8#&#+w*8 1 }8<?Dm m o ~ p!!4!D!!!K"K"M"P"r"r"t"w"""""""""""""####5#5#7#:#\#\#^#a#############$$$$<$<$>$A$c$c$e$h$$$$$$$$$$E&a&}& %%%<%L%P%<%E%P%]%a&}&8` H      p  `==$CCpHHL PL XL `L `N P @P P` !   ]=% 9 Q j       x1 G x^ =s { =  @   0  ( b8 W S!t  S! " `! " N%$ "^:P (JP T N%u & P% & * 'BA *  ,0 *H ,v / , / ,3 /LpP )dP ?hP O`P \ ,3 7 03A 7 8 7w& 8E ]=b0P p P ~P P   P @P PL  HL 2lH@ `=FXL S`L \$Co@P {`N   .?Tct@P {  . B Q ^ r  8        (  P < O _ t @P       "4 F  f .annobin_UUID.c.annobin_UUID.c_end.annobin_UUID.c.hot.annobin_UUID.c_end.hot.annobin_UUID.c.unlikely.annobin_UUID.c_end.unlikely.annobin_UUID.c.startup.annobin_UUID.c_end.startup.annobin_UUID.c.exit.annobin_UUID.c_end.exit.annobin_XS_Data__UUID_compare.start.annobin_XS_Data__UUID_compare.endXS_Data__UUID_compare.annobin_MD5Init.start.annobin_MD5Init.endMD5Init.annobin_MD5Update.start.annobin_MD5Update.endMD5Update.annobin_MD5Final.start.annobin_MD5Final.endMD5Final.annobin_get_system_time.start.annobin_get_system_time.endget_system_time.annobin_get_random_info.start.annobin_get_random_info.endget_random_info.annobin_ptable_store.isra.3.start.annobin_ptable_store.isra.3.endptable_store.isra.3.annobin_XS_Data__UUID_DESTROY.start.annobin_XS_Data__UUID_DESTROY.endXS_Data__UUID_DESTROYinstances_mutexinstances.annobin_XS_Data__UUID_new.start.annobin_XS_Data__UUID_new.endXS_Data__UUID_new.annobin_make_ret.start.annobin_make_ret.endmake_retbase64.annobin_XS_Data__UUID_to_string.start.annobin_XS_Data__UUID_to_string.endXS_Data__UUID_to_string.annobin_XS_Data__UUID_create_from_name.start.annobin_XS_Data__UUID_create_from_name.endXS_Data__UUID_create_from_name.annobin_XS_Data__UUID_create.start.annobin_XS_Data__UUID_create.endXS_Data__UUID_createinited.19609uuids_this_tick.19608time_last.19607inited.19615.annobin_XS_Data__UUID_from_string.start.annobin_XS_Data__UUID_from_string.endXS_Data__UUID_from_stringindex64.annobin_XS_Data__UUID_CLONE.start.annobin_XS_Data__UUID_CLONE.endXS_Data__UUID_CLONE.annobin_boot_Data__UUID.start.annobin_boot_Data__UUID.endNameSpace_DNSNameSpace_URLNameSpace_OIDNameSpace_X500crtstuff.cderegister_tm_clones__do_global_dtors_auxcompleted.7303__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entry__FRAME_END___fini__dso_handle_DYNAMIC__GNU_EH_FRAME_HDR__TMC_END___GLOBAL_OFFSET_TABLE__initPerl_sv_setref_pvPerl_sv_2iv_flagsfree@@GLIBC_2.2.5__errno_location@@GLIBC_2.2.5gethostid@@GLIBC_2.2.5Perl_stack_grow_ITM_deregisterTMCloneTablePerl_call_methodPerl_sv_derived_fromPerl_pop_scopePerl_newCONSTSUB_edatastrlen@@GLIBC_2.2.5__stack_chk_fail@@GLIBC_2.4Perl_sv_setiv_mgPL_thr_keygettimeofday@@GLIBC_2.2.5memset@@GLIBC_2.2.5Perl_sv_2pv_flagsPerl_xs_boot_epilogsrand@@GLIBC_2.2.5calloc@@GLIBC_2.2.5__gmon_start__Perl_newSVsvPerl_croak_xs_usageboot_Data__UUIDPerl_savetmpsPerl_gv_stashpvPL_memory_wrapPerl_newSVpvpthread_getspecific@@GLIBC_2.2.5pthread_mutex_unlock@@GLIBC_2.2.5malloc@@GLIBC_2.2.5Perl_croak_nocontextsscanf@@GLIBC_2.2.5Perl_newXS_deffilePerl_sv_2mortalrealloc@@GLIBC_2.2.5__bss_startPerl_xs_handshakePerl_free_tmpsPerl_markstack_growgethostname@@GLIBC_2.2.5Perl_push_scope_ITM_registerTMCloneTablepthread_mutex_init@@GLIBC_2.2.5__cxa_finalize@@GLIBC_2.2.5Perl_sv_newmortalpthread_mutex_lock@@GLIBC_2.2.5__sprintf_chk@@GLIBC_2.3.4.symtab.strtab.shstrtab.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.plt.sec.text.fini.rodata.eh_frame_hdr.eh_frame.note.gnu.property.init_array.fini_array.data.rel.ro.dynamic.got.data.bss.comment.gnu.build.attributes.debug_aranges.debug_info.debug_abbrev.debug_line.debug_str.debug_loc.debug_ranges88$.o``48 @GHo jUoH H `d nB xs~pp  ='`=`= == $C$CCCpHpH HL HLPL PLXL XL`L `L`N `NP P@@P @Pp 0@P- P`pPD#`02`> =L #X05SBcx)<nBXP#z  )|