#!/usr/bin/perl -w use lib q<../lib>; use strict; BEGIN { require 'manakai/genlib.pl' } use Message::Util::QName::General [qw/ExpandedURI/], { ManakaiDOMLS2003 => q, }; use Message::DOM::ManakaiDOMLS2003; use Message::DOM::DOMLS qw/MODE_SYNCHRONOUS/; use Getopt::Long; require 'dommemlist.pl.tmp'; ## Generated by mkdommemlist.pl my $output_filename; my $output_file; GetOptions ( 'output-file=s' => \$output_filename, ); if (defined $output_filename) { open $output_file, '>', $output_filename or die "$0: $output_filename: $!"; } else { $output_file = \*STDOUT; } our $Method; our $Attr; our $MethodParam; my $Assert = { qw/assertDOMException 1 assertFalse 1 assertNotNull 1 assertNull 1 assertTrue 1/ }; my $Misc = { qw/if 1 implementationAttribute 1 var 1/ }; my $Condition = { qw/condition 1 contains 1 contentType 1 hasSize 1 implementationAttribute 1 not 1 notNull 1 or 1/ }; my $Status = {Number => 0, our => {Info => 1}}; ## Defined in genlib.pl but redefined. sub output_result ($) { print $output_file shift; } sub to_perl_value ($;%) { my ($s, %opt) = @_; if (defined $s) { if ($s =~ /^(?!\d)\w+$/) { return perl_var (type => '$', local_name => $s); } else { return $s; } } elsif (defined $opt{default}) { return $opt{default}; } else { return ''; } } sub body2code ($) { my $parent = shift; my $result = ''; my $children = $parent->childNodes; for (my $i = 0; $i < $children->length; $i++) { my $child = $children->item ($i); if ($child->nodeType == $child->ELEMENT_NODE) { my $ln = $child->localName; if ($Method->{$ln} or $Attr->{$ln} or $Assert->{$ln} or $Misc->{$ln}) { $result .= node2code ($child); } else { valid_err q.$child->localName, node => $child; } } elsif ($child->nodeType == $child->COMMENT_NODE) { $result .= perl_comment $child->data; } elsif ($child->nodeType == $child->TEXT_NODE) { if ($child->data =~ /\S/) { valid_err q.$child->data, node => $child; } } else { valid_err q.$child->nodeType, node => $child; } } $result; } sub condition2code ($;%) { my ($parent, %opt) = @_; my $result = ''; my @result; my $children = $parent->childNodes; for (my $i = 0; $i < $children->length; $i++) { my $child = $children->item ($i); if ($child->nodeType == $child->ELEMENT_NODE) { my $ln = $child->localName; if ($Condition->{$ln}) { push @result, node2code ($child); } else { valid_err q.$child->localName, node => $child; } } elsif ($child->nodeType == $child->COMMENT_NODE) { $result .= perl_comment $child->data; } elsif ($child->nodeType == $child->TEXT_NODE) { if ($child->data =~ /\S/) { valid_err q.$child->data, node => $child; } } else { valid_err q.$child->nodeType, node => $child; } } $result .= join (($opt{join}||='or' eq 'or' ? ' || ' : $opt{join} eq 'and' ? ' && ' : valid_err q, node => $parent), map {"($_)"} @result); $result; } #condition2code sub node2code ($); sub node2code ($) { my $node = shift; my $result = ''; if ($node->nodeType != $node->ELEMENT_NODE) { if ($node->nodeType == $node->COMMENT_NODE) { $result .= perl_comment $node->data; } elsif ($node->nodeType == $node->TEXT_NODE) { if ($node->data =~ /\S/) { valid_err q.$node->data, node => $node; } } else { valid_err q.$node->nodeType, node => $node; } return $result; } my $ln = $node->localName; if ($ln eq 'var') { my $name = $node->getAttributeNS (undef, 'name'); $result .= perl_statement perl_var local_name => $name, scope => 'my', type => '$'; if ($node->getAttributeNS (undef, 'value')) { valid_err q, node => $node; } $Status->{var}->{$name}->{type} = $node->getAttributeNS (undef, 'type'); } elsif ($ln eq 'load') { $result .= perl_statement perl_assign perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'var')) => 'load (' . perl_literal ($node->getAttributeNS (undef, 'href')). ')'; } elsif ($Method->{$ln}) { $result .= perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'var')). ' = ' if $node->hasAttributeNS (undef, 'var'); $result .= perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'obj')). '->'.$ln.' ('. join (', ', map { to_perl_value ($node->getAttributeNS (undef, $_), default => 'undef') } @{$Method->{$ln}}). ");\n"; } elsif ($Attr->{$ln}) { if ($node->hasAttributeNS (undef, 'var')) { $result .= perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'var')). ' = '; } elsif ($node->hasAttributeNS (undef, 'value')) { # } else { valid_err q, node => $node; } $result .= perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'obj')). '->'.$ln; if ($node->hasAttributeNS (undef, 'var')) { $result .= ";\n"; } elsif ($node->hasAttributeNS (undef, 'value')) { $result .= " (".to_perl_value ($node->getAttributeNS (undef, 'value')). ");\n"; } } elsif ($ln eq 'assertEquals') { my $expected = $node->getAttributeNS (undef, 'expected'); my $expectedType = $Status->{var}->{$expected}->{type} || ''; $result .= 'assertEquals'. ({Collection => 'Collection', List => 'List'}->{$expectedType}||''); my $ignoreCase = $node->getAttributeNS (undef, 'ignoreCase') || 'false'; if ($ignoreCase eq 'auto') { $result .= 'AutoCase ('. perl_literal ($node->getAttributeNS (undef, 'context') || 'element'). ', '; } else { $result .= ' ('; } $result .= perl_literal ($node->getAttributeNS (undef, 'id')).', '; $result .= join ", ", map { $ignoreCase eq 'true' ? ($expectedType eq 'Collection' or $expectedType eq 'List') ? "toLowerArray ($_)" : "lc ($_)" : $_ } map { to_perl_value ($_) } ( $expected, $node->getAttributeNS (undef, 'actual'), ); $result .= ");\n"; $Status->{Number}++; } elsif ($ln eq 'assertTrue' or $ln eq 'assertFalse') { my $condition; if ($node->hasAttributeNS (undef, 'actual')) { $condition = perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'actual')); if ($node->hasChildNodes) { valid_err q, node => $node; } } elsif ($node->hasChildNodes) { $condition = condition2code ($node); } else { valid_err $ln.q< w/o @actual not supported>, node => $node; } $result .= perl_statement $ln . ' ('. perl_literal ($node->getAttributeNS (undef, 'id')).', '. $condition. ')'; $Status->{Number}++; } elsif ($ln eq 'assertNotNull' or $ln eq 'assertNull') { $result .= perl_statement $ln . ' (' . perl_literal ($node->getAttributeNS (undef, 'id')).', '. perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'actual')). ')'; if ($node->hasChildNodes) { valid_err q, node => $node; } $Status->{Number}++; } elsif ($ln eq 'assertDOMException') { $Status->{use}->{'Message::Util::Error'} = 1; $result .= q[ { my $success = 0; try { ]; my $children = $node->childNodes; my $errname; for (my $i = 0; $i < $children->length; $i++) { my $child = $children->item ($i); $errname = $child->localName if $child->nodeType == $child->ELEMENT_NODE; $result .= body2code ($child); } $result .= q[ } catch Message::DOM::DOMException with { my $err = shift; $success = 1 if $err->{-type} eq ].perl_literal ($errname).q[; } assertTrue (].perl_literal ($node->getAttributeNS (undef, 'id')). q[, $success); } ]; $Status->{Number}++; } elsif ($ln eq 'contentType') { $result .= '$builder->{contentType} eq '. perl_literal ($node->getAttributeNS (undef, 'type')); $Status->{our}->{builder} = 1; } elsif ($ln eq 'if') { my $children = $node->childNodes; my $condition; my $true = ''; for (my $i = 0; $i < $children->length; $i++) { my $child = $children->item ($i); if ($child->nodeType == $child->ELEMENT_NODE) { if (not $condition) { $condition = node2code ($child); } elsif ($child->localName eq 'else') { valid_err q, node => $child if $true; $true = $result; $result = ''; } else { $result .= node2code ($child); } } else { $result .= node2code ($child); } } $result = perl_if $condition, $true || $result, $true ? $result : undef; } elsif ($ln eq 'or') { $result .= condition2code ($node, join => 'or'); } elsif ($ln eq 'not') { $result .= 'not '.condition2code ($node, join => 'nosupport'); } elsif ($ln eq 'notNull') { $result .= 'defined '. perl_var (type => '$', local_name => $node->getAttributeNS (undef, 'obj')); } else { valid_err q.$ln; } $result; } our $result = ''; my $input; { local $/ = undef; $input = <>; } { my $dom = Message::DOM::DOMImplementationRegistry ->getDOMImplementation ({Core => undef, XML => undef, ExpandedURI q => '1.0'}); my $parser = $dom->createLSParser (MODE_SYNCHRONOUS); my $in = $dom->createLSInput; $in->stringData ($input); my $src = $parser->parse ($in)->documentElement; { my $children = $src->ownerDocument->childNodes; for (my $i = 0; $i < $children->length; $i++) { my $node = $children->item ($i); if ($node->nodeType == $node->COMMENT_NODE) { if ($node->data =~ /Copyright/) { $result .= perl_comment qq. qq. qq. $node->data; } else { $result .= perl_comment $node->data; } } } } my $child = $src->childNodes; for (my $i = 0; $i < $child->length; $i++) { my $node = $child->item ($i); if ($node->nodeType == $node->ELEMENT_NODE) { my $ln = $node->localName; if ($ln eq 'metadata') { my $md = $node->childNodes; for (my $j = 0; $j < $md->length; $j++) { my $node = $md->item ($j); if ($node->nodeType == $node->ELEMENT_NODE) { my $ln = $node->localName; if ($ln eq 'title') { $result .= perl_statement perl_assign '$Info->{Name}' => perl_literal $node->textContent; } elsif ($ln eq 'description') { $result .= perl_statement perl_assign '$Info->{Description}' => perl_literal $node->textContent; } else { # valid_err q.$ln, # node => $node; } } elsif ($node->nodeType == $node->TEXT_NODE) { if ($node->data =~ /\S/) { valid_err q.$node->data, node => $node; } } elsif ($node->nodeType == $node->COMMENT_NODE) { $result .= perl_comment $node->data; } else { valid_err q.$node->nodeType, node => $node; } } } elsif ($ln eq 'implementationAttribute') { $result .= perl_comment sprintf 'Implementation attribute: @name=%s, @value=%s', $node->getAttributeNS (undef, 'name'), $node->getAttributeNS (undef, 'value'); } else { $result .= node2code ($node); } } elsif ($node->nodeType == $node->COMMENT_NODE) { $result .= perl_comment $node->data; } elsif ($node->nodeType == $node->TEXT_NODE) { if ($node->data =~ /\S/) { valid_err q.$node->data, node => $node; } } else { valid_err q.$node->nodeType, node => $node; } } } my $pre = "#!/usr/bin/perl -w\nuse strict;\n"; $pre .= perl_statement ('require '.perl_literal 'manakai/domtest.pl'); $pre .= perl_statement ('use Message::Util::Error') if $Status->{use}->{'Message::Util::Error'}; for (keys %{$Status->{our}}) { $pre .= perl_statement perl_var type => '$', local_name => $_, scope => 'our'; } $pre .= perl_statement q.(0+$Status->{Number}).q<)>; output_result $pre.$result;