lib/TWiki/Configure/Types/PERL.pm
changeset 0 414e01d06fd5
equal deleted inserted replaced
-1:000000000000 0:414e01d06fd5
       
     1 #
       
     2 # TWiki Enterprise Collaboration Platform, http://TWiki.org/
       
     3 #
       
     4 # Copyright (C) 2000-2006 TWiki Contributors.
       
     5 #
       
     6 # This program is free software; you can redistribute it and/or
       
     7 # modify it under the terms of the GNU General Public License
       
     8 # as published by the Free Software Foundation; either version 2
       
     9 # of the License, or (at your option) any later version. For
       
    10 # more details read LICENSE in the root of this distribution.
       
    11 #
       
    12 # This program is distributed in the hope that it will be useful,
       
    13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    15 #
       
    16 # As per the GPL, removal of this notice is prohibited.
       
    17 #
       
    18 # Data type for an perl constant rvalue. This is used for capturing values
       
    19 # of collection types.
       
    20 # The value must observe the following grammar:
       
    21 # value :: array | hash | string ;
       
    22 # array :: '[' value ( ',' value )* ']' ;
       
    23 # hash  :: '{' keydef ( ',' keydef )* ']';
       
    24 # keydef :: string '=>' value ;
       
    25 # string ::= single quoted string, use \' to escape a quote, or \w+
       
    26 
       
    27 package TWiki::Configure::Types::PERL;
       
    28 
       
    29 use strict;
       
    30 
       
    31 use TWiki::Configure::Type;
       
    32 use Data::Dumper;
       
    33 
       
    34 use base 'TWiki::Configure::Type';
       
    35 
       
    36 sub prompt {
       
    37     my( $this, $id, $opts, $value ) = @_;
       
    38     my $v = Data::Dumper->Dump([$value],['x']);
       
    39     $v =~ s/^\$x = (.*);\s*$/$1/s;
       
    40     $v =~ s/^     //gm;
       
    41     return CGI::textarea( -name => $id,
       
    42                           -value => $v,
       
    43                           -rows => 10,
       
    44                           -columns => 80);
       
    45 }
       
    46 
       
    47 # verify that the string is a legal rvalue according to the grammar
       
    48 sub _rvalue {
       
    49     my ($s, $term) = @_;
       
    50     while (length($s) > 0 && (!$term || $s !~ s/^\s*$term//)) {
       
    51         if ($s =~ s/^\s*'//s) {
       
    52             my $escaped = 0;
       
    53             while (length($s) > 0 && $s =~ s/^(.)//s) {
       
    54                 last if ($1 eq "'" && !$escaped);
       
    55                 $escaped = $1 eq '\\';
       
    56             }
       
    57         } elsif ($s =~ s/^\s*(\w+)//s) {
       
    58         } elsif ($s =~ s/^\s*\[//s) {
       
    59             $s = _rvalue($s, ']');
       
    60         } elsif ($s =~ s/^\s*{//s) {
       
    61             $s = _rvalue($s, '}');
       
    62         } elsif ($s =~ s/^\s*(,|=>)//s) {
       
    63         } else {
       
    64             last;
       
    65         }
       
    66     }
       
    67     return $s;
       
    68 }
       
    69 
       
    70 sub string2value {
       
    71     my ($this, $val) = @_;
       
    72     my $s;
       
    73     if ($s = _rvalue($val)) {
       
    74         # Parse failed, return as a string.
       
    75         die "Parse of structured value failed at: $s\nPlease go back and check it.";
       
    76     }
       
    77     return eval $val;
       
    78 }
       
    79 
       
    80 sub deep_equals {
       
    81     my ($a, $b) = @_;
       
    82 
       
    83     if (!defined($a) && !defined($b)) {
       
    84         return 1;
       
    85     }
       
    86     if (!defined($a) || !defined($b)) {
       
    87         return 0;
       
    88     }
       
    89     if (ref($a) eq 'ARRAY' && ref($b) eq 'ARRAY') {
       
    90         return 0 unless scalar(@$a) == scalar(@$b);
       
    91         for (0..$#$a) {
       
    92             return 0 unless deep_equals($a->[$_], $b->[$_]);
       
    93         }
       
    94         return 1;
       
    95     }
       
    96 
       
    97     if (ref($a) eq 'HASH' && ref($b) eq 'HASH') {
       
    98         return 0 unless scalar(keys %$a) == scalar(keys %$b);
       
    99         for ( keys %$a ) {
       
   100             return 0 unless deep_equals($a->{$_}, $b->{$_});
       
   101         }
       
   102         return 1;
       
   103     }
       
   104     return $a eq $b;
       
   105 }
       
   106 
       
   107 sub equals {
       
   108     my ($this, $val, $def) = @_;
       
   109 
       
   110     return deep_equals($val, $def);
       
   111 }
       
   112 
       
   113 1;