sub packVars { my $varsref = $_[0]; my $seenref = $_[1]; return unless $varsref; return if $seenref->{0+$varsref}++; if (ref $varsref eq "HASH") { return join "&", "$PackVer:H", map { my $v = $varsref->{$_}; $v = ref $v ? packVars( $v, $seenref ) : defined($v) ? $v : ' '; join '=', map { s/([%&=])/ sprintf '%%%02x', ord($1) /ge; $_ +} $_, $v; } sort keys %$varsref; } elsif (ref $varsref eq "ARRAY") { return join "^", "$PackVer:A", map { my $v = ref $_ ? packVars( $_, $seenref ) : defined($_) ? $_ : ''; $v =~ s/([~^=])/sprintf '~%02x', ord($1)/ge; $v; } @$varsref; } else { die "Can't handle vars of type ".ref($varsref)."\n"; } } sub unpackVars { my $vars_str = $_[0]; return {} unless $vars_str; # version 00: original format # version 01: keys are escaped, not just values, handles nested re +fs. my $vars; #print "$vars_str\n"; $vars_str =~ s/^(==\d\d):([AH])(.)//; my ($format_version,$type,$split)=($1,$2,$3); #print "$format_version : $type : $split\n"; unless (defined $format_version) { # No format/format version "00" my %vars = map split(/=/, $_, 2), split /&/, $vars_str; unescape( values %vars ); $vars{$_} eq ' ' and $vars{$_} = '' for keys %vars; return \%vars; } elsif ($format_version le $PackVer) { if ($type eq 'H') { for (split /\Q$split\E/, $vars_str) { s/%(\w\w)/ chr(hex($1)) /ge for my ($k,$v) = split /=/, +$_, -1; # special data to unpack? if ($v=~/^==\d\d:[AH]/) { # nested value $v = unpackVars($v); } $vars->{$k} = $v; } } elsif ($type eq 'A') { for (split /\Q$split\E/, $vars_str) { s/~(\w\w)/ chr(hex($1)) /ge; # special data to unpack? if (/^==\d\d:[AH]/) { # nested value $_ = unpackVars($_); } push @{$vars), $_; } } else { return "Unknown type! $type"; } } else { return "Version number too high! ($format_version gt $PackVer)"; } return $vars; } sub cmpVars { my ($var1str, $var2str) = @_; return 0 if $var1str eq $var2str; # upgrade to new version /^$PackVer:[AH]/ or $_ = packVars( unpackVars( $_ ) ) for ($var1str, $var2str); return $var1str cmp $var2str; }
In reply to Re^3: patchable settings (big readmores)
by ysth
in thread patchable settings
by ysth
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |