1 |
wakaba |
1.1 |
#!/usr/bin/perl -w |
2 |
|
|
|
3 |
|
|
=head1 NAME |
4 |
|
|
|
5 |
|
|
dis2pm.pl - Manakai DOM Perl Module Generator |
6 |
|
|
|
7 |
|
|
=head1 SYNOPSIS |
8 |
|
|
|
9 |
|
|
perl dis2pm.pl Foo.dis > Foo.pm |
10 |
|
|
|
11 |
|
|
=head1 DESCRIPTION |
12 |
|
|
|
13 |
|
|
B<dis2pm> generates a Perl module file (*.pm) that implements |
14 |
|
|
DOM (Document Object Model) interfaces from a "dis" |
15 |
|
|
(DOM implementation source) file. |
16 |
|
|
|
17 |
|
|
This script is part of manakai. |
18 |
|
|
|
19 |
|
|
=cut |
20 |
|
|
|
21 |
|
|
use strict; |
22 |
|
|
use lib qw<lib ../lib>; |
23 |
|
|
use Message::Markup::SuikaWikiConfig20::Parser; |
24 |
|
|
use Message::Markup::XML::QName qw/DEFAULT_PFX/; |
25 |
|
|
use Message::Util::QName::General [qw/ExpandedURI/], { |
26 |
|
|
DOMCore => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core#>, |
27 |
|
|
DOMMain => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core#>, |
28 |
|
|
infoset => q<http://www.w3.org/2001/04/infoset#>, |
29 |
|
|
lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>, |
30 |
|
|
Perl => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#Perl-->, |
31 |
|
|
license => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/license#>, |
32 |
|
|
ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>, |
33 |
|
|
MDOM_EXCEPTION => q<http://suika.fam.cx/~wakaba/archive/2004/8/4/manakai-dom-exception#>, |
34 |
|
|
xml => q<http://www.w3.org/XML/1998/namespace>, |
35 |
|
|
xmlns => q<http://www.w3.org/2000/xmlns/>, |
36 |
|
|
}; |
37 |
|
|
my $ManakaiDOMModulePrefix = q<Message::DOM>; |
38 |
|
|
my $MAX_DOM_LEVEL = 3; |
39 |
|
|
|
40 |
wakaba |
1.4 |
use Getopt::Long; |
41 |
|
|
my %Opt; |
42 |
|
|
GetOptions ( |
43 |
|
|
'help' => \$Opt{help}, |
44 |
|
|
'output-pod=s' => \$Opt{output_pod}, |
45 |
|
|
'output-pod-file=s' => \$Opt{output_pod_file}, |
46 |
|
|
) or pod2usage (2); |
47 |
|
|
if ($Opt{help}) { |
48 |
|
|
pod2usage (0); |
49 |
|
|
exit; |
50 |
|
|
} elsif (($Opt{output_pod} ||= 'no') eq 'file' and |
51 |
|
|
not defined $Opt{output_pod_file}) { |
52 |
|
|
pod2usage (2); |
53 |
|
|
exit 2; |
54 |
|
|
} |
55 |
|
|
|
56 |
wakaba |
1.1 |
my $s; |
57 |
|
|
{ |
58 |
|
|
local $/ = undef; |
59 |
|
|
$s = <>; |
60 |
|
|
} |
61 |
|
|
my $source = Message::Markup::SuikaWikiConfig20::Parser->parse_text ($s); |
62 |
|
|
my $Info = {}; |
63 |
|
|
my $Status = {package => 'main', depth => 0, generated_fragment => 0}; |
64 |
|
|
our $result = ''; |
65 |
wakaba |
1.4 |
my $result_pod; |
66 |
wakaba |
1.1 |
|
67 |
|
|
BEGIN { |
68 |
|
|
require 'manakai/genlib.pl'; |
69 |
|
|
} |
70 |
|
|
|
71 |
wakaba |
1.4 |
if ($Opt{output_pod} eq 'no') { |
72 |
|
|
eval q{ |
73 |
|
|
sub pod_block (@) { |
74 |
|
|
return ''; |
75 |
|
|
} |
76 |
|
|
}; |
77 |
|
|
} elsif ($Opt{output_pod} eq 'only' or |
78 |
|
|
$Opt{output_pod} eq 'file') { |
79 |
|
|
eval q{ |
80 |
|
|
sub pod_block (@) { |
81 |
|
|
my @v = grep ((defined and length), @_); |
82 |
|
|
$result_pod .= join "\n\n", '', ($v[0] =~ /^=/ ? () : '=pod'), @v, |
83 |
|
|
'=cut', ''; |
84 |
|
|
return ''; |
85 |
|
|
} |
86 |
|
|
}; |
87 |
|
|
} |
88 |
|
|
|
89 |
wakaba |
1.1 |
sub perl_package_name (%) { |
90 |
|
|
my %opt = @_; |
91 |
|
|
my $r; |
92 |
|
|
if ($opt{if}) { |
93 |
|
|
$r = $ManakaiDOMModulePrefix . q<::IF::> . perl_name $opt{if}; |
94 |
|
|
} elsif ($opt{iif}) { |
95 |
|
|
$r = $ManakaiDOMModulePrefix . q<::IIF::> . perl_name $opt{iif}; |
96 |
|
|
} elsif ($opt{name} or $opt{name_with_condition}) { |
97 |
|
|
if ($opt{name_with_condition}) { |
98 |
|
|
if ($opt{name_with_condition} =~ /^([^:]+)::([^:]+)$/) { |
99 |
|
|
$opt{name} = $1; |
100 |
|
|
$opt{condition} = $2; |
101 |
|
|
} else { |
102 |
|
|
$opt{name} = $opt{name_with_condition}; |
103 |
|
|
} |
104 |
|
|
} |
105 |
|
|
$opt{name} = perl_name $opt{name}; |
106 |
|
|
$opt{name} = $opt{prefix} . '::' . $opt{name} if $opt{prefix}; |
107 |
|
|
$r = $ManakaiDOMModulePrefix . q<::> . $opt{name}; |
108 |
|
|
} elsif ($opt{qname} or $opt{qname_with_condition}) { |
109 |
|
|
if ($opt{qname_with_condition}) { |
110 |
|
|
if ($opt{qname_with_condition} =~ /^(.+)::([^:]*)$/) { |
111 |
|
|
$opt{qname} = $1; |
112 |
|
|
$opt{condition} = $2; |
113 |
|
|
} else { |
114 |
|
|
$opt{qname} = $opt{qname_with_condition}; |
115 |
|
|
} |
116 |
|
|
} |
117 |
|
|
if ($opt{qname} =~ /^([^:]*):(.*)$/) { |
118 |
|
|
$opt{ns_prefix} = $1; |
119 |
|
|
$opt{name} = $2; |
120 |
|
|
} else { |
121 |
|
|
$opt{ns_prefix} = DEFAULT_PFX; |
122 |
|
|
$opt{name} = $opt{qname}; |
123 |
|
|
} |
124 |
|
|
## ISSUE: Prefix to ... |
125 |
|
|
#$r = ns_uri_to_perl_package_name (ns_prefix_to_uri ($opt{ns_prefix})) . |
126 |
|
|
# '::' . $opt{name}; |
127 |
|
|
$r = $ManakaiDOMModulePrefix . '::' . $opt{name}; |
128 |
|
|
} elsif ($opt{if_qname} or $opt{if_qname_with_condition}) { |
129 |
|
|
if ($opt{if_qname_with_condition}) { |
130 |
|
|
if ($opt{if_qname_with_condition} =~ /^(.+)::([^:]*)$/) { |
131 |
|
|
$opt{if_qname} = $1; |
132 |
|
|
$opt{condition} = $2; |
133 |
|
|
} else { |
134 |
|
|
$opt{if_qname} = $opt{if_qname_with_condition}; |
135 |
|
|
} |
136 |
|
|
} |
137 |
|
|
if ($opt{if_qname} =~ /^([^:]*):(.*)$/) { |
138 |
|
|
$opt{ns_prefix} = $1; |
139 |
|
|
$opt{name} = $2; |
140 |
|
|
} else { |
141 |
|
|
$opt{ns_prefix} = DEFAULT_PFX; |
142 |
|
|
$opt{name} = $opt{if_qname}; |
143 |
|
|
} |
144 |
|
|
## ISSUE: Prefix to ... |
145 |
|
|
#$r = ns_uri_to_perl_package_name (ns_prefix_to_uri ($opt{ns_prefix})) . |
146 |
|
|
# '::' . $opt{name}; |
147 |
|
|
$r = $ManakaiDOMModulePrefix . '::IF::' . $opt{name}; |
148 |
|
|
} elsif ($opt{full_name}) { |
149 |
|
|
$r = $opt{full_name}; |
150 |
|
|
} else { |
151 |
|
|
valid_err q<$opt{name} is false>; |
152 |
|
|
} |
153 |
|
|
if ($opt{condition}) { |
154 |
|
|
$r = $r . '::' . perl_name $opt{condition}; |
155 |
|
|
} |
156 |
|
|
if ($opt{is_internal}) { |
157 |
|
|
$r .= '::_internal'; |
158 |
|
|
$r .= '_inherit' if $opt{is_for_inheriting}; |
159 |
|
|
} |
160 |
|
|
$r; |
161 |
|
|
} |
162 |
|
|
|
163 |
|
|
sub perl_package (%) { |
164 |
|
|
my $fn = perl_package_name @_; |
165 |
|
|
unless ($fn eq $Status->{package}) { |
166 |
|
|
$Status->{package} = $fn; |
167 |
|
|
return perl_statement qq<package $fn>; |
168 |
|
|
} else { |
169 |
|
|
return ''; |
170 |
|
|
} |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
sub perl_exception (@) { |
174 |
|
|
my %opt = @_; |
175 |
|
|
if ($opt{class} !~ /:/) { |
176 |
|
|
$opt{class} = perl_package_name name => $opt{class}; |
177 |
|
|
} else { |
178 |
|
|
$opt{class} = perl_package_name full_name => $opt{class}; |
179 |
|
|
} |
180 |
|
|
my @param = (-type => $opt{type}, |
181 |
|
|
-object => perl_code_literal ('$self')); |
182 |
|
|
if (ref $opt{param}) { |
183 |
|
|
push @param, %{$opt{param}}; |
184 |
|
|
} elsif ($opt{param}) { |
185 |
|
|
push @param, perl_code_literal ($opt{param}); |
186 |
|
|
} |
187 |
|
|
if ($opt{subtype} or $opt{subtype_uri}) { |
188 |
|
|
my $uri = $opt{subtype_uri} || expanded_uri ($opt{subtype}); |
189 |
|
|
push @param, ExpandedURI q<MDOM_EXCEPTION:subtype> => $uri; |
190 |
|
|
} |
191 |
|
|
q<report > . $opt{class} . q< > . perl_list @param; |
192 |
|
|
} |
193 |
|
|
|
194 |
|
|
|
195 |
|
|
{ |
196 |
|
|
use re 'eval'; |
197 |
|
|
my $RegBlockContent; |
198 |
|
|
$RegBlockContent = qr/(?>[^{}\\]*)(?>(?>[^{}\\]+|\\.|\{(??{$RegBlockContent})\})*)/s; |
199 |
|
|
## Defined by genlib.pl but overridden. |
200 |
|
|
sub perl_code ($;%) { |
201 |
|
|
my ($s, %opt) = @_; |
202 |
|
|
valid_err q<Uninitialized value in perl_code>, |
203 |
|
|
node => $opt{node} unless defined $s; |
204 |
|
|
$s =~ s[<Q:([^<>]+)>|\b(null|true|false)\b][ |
205 |
|
|
my ($q, $l) = ($1, $2); |
206 |
|
|
if (defined $q) { |
207 |
|
|
if ($q =~ /\}/) { |
208 |
|
|
valid_warn qq<Possible typo in the QName: "$q">; |
209 |
|
|
} |
210 |
|
|
perl_literal (expanded_uri ($q)); |
211 |
|
|
} else { |
212 |
|
|
{true => 1, false => 0, null => 'undef'}->{$l}; |
213 |
|
|
} |
214 |
|
|
]ge; |
215 |
|
|
## TODO: Ensure Message::Util::Error imported if try. |
216 |
|
|
## ISSUE: __FILE__ & __LINE__ will break if multiline substition happens. |
217 |
|
|
$s =~ s{ |
218 |
|
|
\b__([A-Z]+) |
219 |
|
|
(?:\{($RegBlockContent)\})? |
220 |
|
|
__\b |
221 |
|
|
}{ |
222 |
|
|
my ($name, $data) = ($1, $2); |
223 |
|
|
my $r; |
224 |
|
|
if ($name eq 'CLASS' or ## Manakai DOM Class |
225 |
|
|
$name eq 'SUPER' or ## Manakai DOM Class (internal) |
226 |
|
|
$name eq 'IIF' or ## DOM Interface + Internal interface & prop |
227 |
|
|
$name eq 'IF') { ## DOM Interface |
228 |
|
|
local $Status->{condition} = $Status->{condition}; |
229 |
|
|
if ($data =~ s/::([^:]*)$//) { |
230 |
|
|
$Status->{condition} = $1; |
231 |
|
|
} |
232 |
|
|
$r = perl_package_name {qw/CLASS name SUPER name IIF iif IF if/}->{$name} |
233 |
|
|
=> $data, |
234 |
|
|
is_internal => {qw/SUPER 1/}->{$name}, |
235 |
|
|
condition => $Status->{condition}; |
236 |
|
|
} elsif ($name eq 'INT') { ## Internal Method / Attr Name |
237 |
|
|
if (defined $data) { |
238 |
|
|
if ($data =~ /^{($RegBlockContent)}$/o) { |
239 |
|
|
$data = $1; |
240 |
|
|
my $name = $1 if $data =~ s/^\s*(\w+)\s*(?:$|:\s*)// or |
241 |
|
|
valid_err qq<Syntax of preprocessing macro "INT" is invalid>, |
242 |
|
|
node => $opt{node}; |
243 |
|
|
local $Status->{preprocess_variable} |
244 |
|
|
= {%{$Status->{preprocess_variable}||{}}}; |
245 |
|
|
while ($data =~ /\G(\S+)\s*(?:=>\s*(\S+)\s*)?(?:,\s*|$)/g) { |
246 |
|
|
my ($n, $v) = ($1, defined $2 ? $2 : 1); |
247 |
|
|
for ($n, $v) { |
248 |
|
|
s/^'([^']+)'$/$1/; ## ISSUE: Doesn't support quoted-' |
249 |
|
|
} |
250 |
|
|
$Status->{preprocess_variable}->{$n} = $v; |
251 |
|
|
} |
252 |
|
|
valid_err q<Preprocessing macro INT{} cannot be used here> |
253 |
|
|
unless $opt{internal}; |
254 |
|
|
$r = perl_comment ("INT: $name"). |
255 |
|
|
$opt{internal}->($name); |
256 |
|
|
} elsif ($data =~ s/^SP://) { |
257 |
|
|
$r = '___'.$data; |
258 |
|
|
} else { |
259 |
|
|
$r = perl_internal_name $data; |
260 |
|
|
} |
261 |
|
|
} else { |
262 |
|
|
valid_err q<Preprocessing macro INT cannot be used here> |
263 |
|
|
unless $opt{internal}; |
264 |
|
|
$r = $opt{internal}->(); |
265 |
|
|
} |
266 |
|
|
} elsif ($name eq 'DEEP') { ## Deep Method Call |
267 |
|
|
$r = 'do { local $Error::Depth = $Error::Depth + 1;' . perl_code ($data) . |
268 |
|
|
'}'; |
269 |
|
|
} elsif ($name eq 'EXCEPTION' or $name eq 'WARNING') { |
270 |
|
|
## Raising an Exception or Warning |
271 |
|
|
if ($data =~ s/^\s*(\w+)\s*\.\s*(\w+)\s*(?:\.\s*([\w:]+)\s*)?(?:::\s*|$)//) { |
272 |
|
|
$r = perl_exception (level => $name, |
273 |
|
|
class => $1, |
274 |
|
|
type => $2, |
275 |
|
|
subtype => $3, |
276 |
|
|
param => perl_code $data); |
277 |
|
|
} else { |
278 |
|
|
valid_err qq<Exception type and name required: "$data">, |
279 |
|
|
node => $opt{node}; |
280 |
|
|
} |
281 |
|
|
} elsif ($name eq 'CODE') { # Built-in code |
282 |
|
|
my ($nm, %param); |
283 |
|
|
if ($data =~ s/^(\w+)\s*(?::\s*|$)//) { |
284 |
|
|
$nm = $1; |
285 |
|
|
} elsif ($data =~ s/^<([^<>]+)>\s*(?::\s*|$)//) { |
286 |
|
|
$nm = $1; |
287 |
|
|
} else { |
288 |
|
|
valid_err q<Built-in code name required>; |
289 |
|
|
} |
290 |
|
|
while ($data =~ /\G(\S+)\s*=>\s*(\S+)\s*(?:,\s*|$)/g) { |
291 |
|
|
$param{$1} = $2; |
292 |
|
|
} |
293 |
|
|
$r = perl_builtin_code ($nm, condition => $opt{condition}, %param); |
294 |
|
|
} elsif ($name eq 'PACKAGE' and $data) { |
295 |
|
|
if ($data eq 'Global') { |
296 |
|
|
$r = $ManakaiDOMModulePrefix; |
297 |
|
|
} else { |
298 |
|
|
valid_err qq<PACKAGE "$data" not supported>; |
299 |
|
|
} |
300 |
|
|
} elsif ($name eq 'REQUIRE') { |
301 |
|
|
$r = perl_statement (q<require >. perl_package_name name => $data); |
302 |
|
|
} elsif ($name eq 'WHEN') { |
303 |
|
|
if ($data =~ s/^\s*IS\s*\{($RegBlockContent)\}::\s*//o) { |
304 |
|
|
my $v = $1; |
305 |
|
|
if ($v =~ /^\s*'([^']+)'\s*$/) { ## ISSUE: Doesn't support quoted-' |
306 |
|
|
if ($Status->{preprocess_variable}->{$1}) { |
307 |
|
|
$r = perl_code ($data, %opt); |
308 |
|
|
} else { |
309 |
|
|
$r = perl_comment ($data); |
310 |
|
|
} |
311 |
|
|
} else { |
312 |
|
|
valid_err qq<WHEN-IS condition "$v" is invalid>, |
313 |
|
|
node => $opt{node}; |
314 |
|
|
} |
315 |
|
|
} else { |
316 |
|
|
valid_err qq<Syntax for preprocessing macro "WHEN" is invalid>, |
317 |
|
|
node => $opt{node}; |
318 |
|
|
} |
319 |
|
|
} elsif ($name eq 'FILE' or $name eq 'LINE' or $name eq 'PACKAGE') { |
320 |
|
|
$r = qq<__${name}__>; |
321 |
|
|
} else { |
322 |
|
|
valid_err qq<Preprocessing macro "$name" not supported>; |
323 |
|
|
} |
324 |
|
|
$r; |
325 |
|
|
}goex; |
326 |
|
|
$s; |
327 |
|
|
} |
328 |
|
|
} |
329 |
|
|
|
330 |
|
|
## Defined in genlib.pl but overridden. |
331 |
|
|
sub perl_code_source ($%) { |
332 |
|
|
my ($s, %opt) = @_; |
333 |
|
|
sprintf qq<\n#line %d "File <%s> Node <%s>"\n%s\n> . |
334 |
|
|
qq<#line 1 "File <%s> Chunk #%d"\n>, |
335 |
|
|
$opt{line} || 1, $opt{file} || $Info->{source_filename}, |
336 |
|
|
$opt{path} || 'x:unknown ()', $s, |
337 |
|
|
$opt{file} || $Info->{source_filename}, ++$Status->{generated_fragment}; |
338 |
|
|
} |
339 |
|
|
|
340 |
|
|
sub perl_builtin_code ($;%); |
341 |
|
|
sub perl_builtin_code ($;%) { |
342 |
|
|
my ($name, %opt) = @_; |
343 |
|
|
$opt{condition} ||= $Status->{condition}; |
344 |
|
|
my $r; |
345 |
|
|
if ($name eq 'DOMString') { |
346 |
|
|
$name = $1 if $name =~ /(\w+)$/; |
347 |
|
|
$r = q{ |
348 |
|
|
if (defined $arg) { |
349 |
|
|
if (ref $arg) { |
350 |
|
|
if (ref $arg eq 'SCALAR') { |
351 |
|
|
$r = bless {value => $$arg}, $self; |
352 |
|
|
} elsif ($arg->isa ('IF')) { |
353 |
|
|
$r = $arg; |
354 |
|
|
} else { |
355 |
|
|
$r = bless {value => ''.$arg}, $self; |
356 |
|
|
} |
357 |
|
|
} else { |
358 |
|
|
$r = bless {value => $arg}, $self; |
359 |
|
|
} |
360 |
|
|
} else { |
361 |
|
|
$r = undef; # null |
362 |
|
|
} |
363 |
|
|
}; |
364 |
|
|
$r =~ s/'IF'/perl_literal (perl_package_name (if => $name))/ge; |
365 |
|
|
$r =~ s/\$self\b/perl_literal (perl_package_name (name => $name))/ge; |
366 |
|
|
$opt{s} or valid_err q<Built-in code parameter "s" required>; |
367 |
|
|
$r =~ s/\$arg\b/\$$opt{s}/g; |
368 |
|
|
$opt{r} or valid_err q<Built-in code parameter "r" required>; |
369 |
|
|
$r =~ s/\$r\b/\$$opt{r}/g; |
370 |
|
|
$r =~ s/\$$opt{r} = \$$opt{s};/#/g if $opt{r} eq $opt{s}; |
371 |
|
|
} elsif (type_isa ($name, ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>)) { |
372 |
|
|
$r = perl_statement perl_exception |
373 |
|
|
(level => 'WARNING', |
374 |
|
|
class => 'ManakaiDOMImplementationWarning', |
375 |
|
|
type => 'MDOM_NS_EMPTY_URI', |
376 |
|
|
param => { |
377 |
|
|
ExpandedURI q<MDOM_EXCEPTION:param-name> => $opt{s}, |
378 |
|
|
}); |
379 |
|
|
if ($opt{condition} and $opt{condition} ne 'DOM2') { |
380 |
|
|
$r .= perl_statement q<$out = undef>; |
381 |
|
|
} |
382 |
|
|
$r = perl_if (q<defined $in and $in eq ''>, $r); |
383 |
|
|
$opt{s} or valid_err q<Built-in code parameter "s" required>; |
384 |
|
|
$r =~ s/\$in\b/\$$opt{s}/g; |
385 |
|
|
$opt{r} or valid_err q<Built-in code parameter "r" required>; |
386 |
|
|
$r =~ s/\$out\b/\$$opt{r}/g; |
387 |
|
|
} elsif ($name eq 'UniqueID') { |
388 |
|
|
$r = q{( |
389 |
|
|
sprintf 'mid:%d.%d.%s.dom.manakai@suika.fam.cx', |
390 |
|
|
time, $$, |
391 |
|
|
['A'..'Z', 'a'..'z', '0'..'9']->[rand 62] . |
392 |
|
|
['A'..'Z', 'a'..'z', '0'..'9']->[rand 62] . |
393 |
|
|
['A'..'Z', 'a'..'z', '0'..'9']->[rand 62] . |
394 |
|
|
['A'..'Z', 'a'..'z', '0'..'9']->[rand 62] . |
395 |
|
|
['A'..'Z', 'a'..'z', '0'..'9']->[rand 62] |
396 |
|
|
)}; |
397 |
|
|
## TODO: Check as HTML Name if not XML. |
398 |
|
|
} elsif ($name eq 'CheckQName') { |
399 |
|
|
$opt{version} = '1.0' if $opt{condition} and $opt{condition} eq 'DOM2'; |
400 |
|
|
my $chk = perl_if |
401 |
|
|
(qq<##CHKNAME##>, undef, |
402 |
|
|
(perl_statement |
403 |
|
|
perl_exception |
404 |
|
|
(class => 'DOMException', |
405 |
|
|
type => 'INVALID_CHARACTER_ERR', |
406 |
|
|
subtype_uri => |
407 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_BAD_NAME>, |
408 |
|
|
param => { |
409 |
|
|
ExpandedURI q<DOMCore:name> |
410 |
|
|
=> perl_code_literal |
411 |
|
|
(perl_var type => '$', local_name => 'qname'), |
412 |
|
|
}))) . |
413 |
|
|
perl_if |
414 |
|
|
(qq<##CHKQNAME##>, undef, |
415 |
|
|
(perl_statement |
416 |
|
|
perl_exception |
417 |
|
|
(class => 'DOMException', |
418 |
|
|
type => 'NAMESPACE_ERR', |
419 |
|
|
subtype_uri => |
420 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_MALFORMED_QNAME>, |
421 |
|
|
param => { |
422 |
|
|
ExpandedURI q<DOMCore:qualifiedName> |
423 |
|
|
=> perl_code_literal |
424 |
|
|
(perl_var type => '$', local_name => 'qname'), |
425 |
|
|
}))); |
426 |
|
|
my $chk10 = $chk; |
427 |
|
|
$chk10 =~ s{##CHKNAME##} |
428 |
|
|
{q<$qname =~ /\A\p{InXML_NameStartChar10}>. |
429 |
|
|
q<\p{InXMLNameChar10}*\z/>}ge; |
430 |
|
|
$chk10 =~ s{##CHKQNAME##} |
431 |
|
|
{q<$qname =~ /\A\p{InXML_NCNameStartChar10}>. |
432 |
|
|
q<\p{InXMLNCNameChar10}*>. |
433 |
|
|
q<(?::\p{InXML_NCNameStartChar10}>. |
434 |
|
|
q<\p{InXMLNCNameChar10}*)?\z/>}ge; |
435 |
|
|
my $chk11 = $chk; |
436 |
|
|
$chk11 =~ s{##CHKNAME##} |
437 |
|
|
{q<$qname =~ /\A\p{InXMLNameStartChar11}>. |
438 |
|
|
q<\p{InXMLNameChar11}*\z/>}ge; |
439 |
|
|
$chk11 =~ s{##CHKQNAME##} |
440 |
|
|
{q<$qname =~ /\A\p{InXMLNCNameStartChar11}>. |
441 |
|
|
q<\p{InXMLNCNameChar11}*>. |
442 |
|
|
q<(?::\p{InXMLNCNameStartChar11}>. |
443 |
|
|
q<\p{InXMLNCNameChar11}*)?\z/>}ge; |
444 |
|
|
my %class; |
445 |
|
|
if ($opt{version} and $opt{version} eq '1.0') { |
446 |
|
|
$r = $chk10; |
447 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10 |
448 |
|
|
InXML_NCNameStartChar10 InXMLNCNameChar10/); |
449 |
|
|
} elsif ($opt{version} and $opt{version} eq '1.1') { |
450 |
|
|
$r = $chk11; |
451 |
|
|
%class = (qw/InXMLNameStartChar11 InXMLNameChar11 |
452 |
|
|
InXMLNCNameStartChar11 InXMLNCNameChar11/); |
453 |
|
|
} elsif ($opt{version}) { |
454 |
|
|
$r = perl_if (q<defined >. |
455 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
456 |
|
|
q< and >. |
457 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
458 |
|
|
q< eq '1.1'>, $chk11, $chk10); |
459 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10 |
460 |
|
|
InXML_NCNameStartChar10 InXMLNCNameChar10 |
461 |
|
|
InXMLNameStartChar11 InXMLNameChar11 |
462 |
|
|
InXMLNCNameStartChar11 InXMLNCNameChar11/); |
463 |
|
|
} else { |
464 |
|
|
valid_err q<Built-in code parameter "version" required>; |
465 |
|
|
} |
466 |
|
|
$opt{qname} or valid_err q<Built-in code parameter "qname" required>; |
467 |
|
|
$r =~ s/\$qname\b/\$$opt{qname}/g; |
468 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML'} or |
469 |
|
|
valid_err q<"Char::Class::XML" must be "Require"d in the interface >. |
470 |
|
|
qq{"$Status->{IF}", condition "$Status->{condition}"}; |
471 |
|
|
for (%class) { |
472 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML::::Import'}->{$_} or |
473 |
|
|
valid_err qq<"$_" must be exported from "Char::Class::XML" in the >. |
474 |
|
|
qq{interface "$Status->{IF}", condition }. |
475 |
|
|
qq{"$Status->{condition}"}; |
476 |
|
|
} |
477 |
|
|
} elsif ($name eq 'CheckNCName') { |
478 |
|
|
$opt{version} = '1.0' if $opt{condition} and $opt{condition} eq 'DOM2'; |
479 |
|
|
my $chk = perl_if |
480 |
|
|
(qq<##CHKNAME##>, undef, |
481 |
|
|
(perl_statement |
482 |
|
|
perl_exception |
483 |
|
|
(class => 'DOMException', |
484 |
|
|
type => 'INVALID_CHARACTER_ERR', |
485 |
|
|
subtype_uri => |
486 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_BAD_NAME>, |
487 |
|
|
param => { |
488 |
|
|
ExpandedURI q<DOMCore:name> |
489 |
|
|
=> perl_code_literal |
490 |
|
|
(perl_var type => '$', local_name => 'qname'), |
491 |
|
|
}))) . |
492 |
|
|
perl_if |
493 |
|
|
(qq<##CHKNCNAME##>, undef, |
494 |
|
|
(perl_statement |
495 |
|
|
perl_exception |
496 |
|
|
(class => 'DOMException', |
497 |
|
|
type => 'NAMESPACE_ERR', |
498 |
|
|
subtype_uri => |
499 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_BAD_NCNAME>, |
500 |
|
|
param => { |
501 |
|
|
ExpandedURI q<infoset:name> |
502 |
|
|
=> perl_code_literal |
503 |
|
|
(perl_var type => '$', local_name => 'qname'), |
504 |
|
|
}))); |
505 |
|
|
my $chk10 = $chk; |
506 |
|
|
$chk10 =~ s{##CHKNAME##} |
507 |
|
|
{q<$qname =~ /\A\p{InXML_NameStartChar10}>. |
508 |
|
|
q<\p{InXMLNameChar10}*\z/>}ge; |
509 |
|
|
$chk10 =~ s{##CHKNCNAME##} |
510 |
|
|
{q<$qname =~ /:/>}ge; |
511 |
|
|
my $chk11 = $chk; |
512 |
|
|
$chk11 =~ s{##CHKNAME##} |
513 |
|
|
{q<$qname =~ /\A\p{InXMLNameStartChar11}>. |
514 |
|
|
q<\p{InXMLNameChar11}*\z/>}ge; |
515 |
|
|
$chk11 =~ s{##CHKNCNAME##} |
516 |
|
|
{q<$qname =~ /:/>}ge; |
517 |
|
|
my $t = ($opt{empty} and $opt{empty} eq 'warn3' and |
518 |
|
|
(not $opt{condition} or $opt{condition} ne 'DOM2')) ? |
519 |
|
|
perl_if |
520 |
|
|
(q<defined $qname and $qname eq q<>>, |
521 |
|
|
perl_statement (perl_exception |
522 |
|
|
(level => 'WARNING', |
523 |
|
|
class => 'ManakaiDOMImplementationWarning', |
524 |
|
|
type => 'MDOM_NS_EMPTY_PREFIX', |
525 |
|
|
param => { |
526 |
|
|
ExpandedURI q<MDOM_EXCEPTION:param-name> => $opt{ncname}, |
527 |
|
|
})). |
528 |
|
|
perl_statement (q<$qname = undef>)) : ''; |
529 |
|
|
my %class; |
530 |
|
|
if ($opt{version} and $opt{version} eq '1.0') { |
531 |
|
|
$r = $chk10; |
532 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10/); |
533 |
|
|
} elsif ($opt{version} and $opt{version} eq '1.1') { |
534 |
|
|
$r = $chk11; |
535 |
|
|
%class = (qw/InXMLNameStartChar11 InXMLNameChar11/); |
536 |
|
|
} elsif ($opt{version}) { |
537 |
|
|
$r = perl_if (q<defined >. |
538 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
539 |
|
|
q< and >. |
540 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
541 |
|
|
q< eq '1.1'>, $chk11, $chk10); |
542 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10 |
543 |
|
|
InXMLNameStartChar11 InXMLNameChar11/); |
544 |
|
|
} else { |
545 |
|
|
valid_err q<Built-in code parameter "version" required>; |
546 |
|
|
} |
547 |
|
|
$r = $t . $r; |
548 |
|
|
$opt{ncname} or valid_err q<Built-in code parameter "ncname" required>; |
549 |
|
|
$r =~ s/\$qname\b/\$$opt{ncname}/g; |
550 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML'} or |
551 |
|
|
valid_err q<"Char::Class::XML" must be "Require"d in the interface >. |
552 |
|
|
qq{"$Status->{IF}", condition "$Status->{condition}"}; |
553 |
|
|
for (%class) { |
554 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML::::Import'}->{$_} or |
555 |
|
|
valid_err qq<"$_" must be exported from "Char::Class::XML" in the >. |
556 |
|
|
qq{interface "$Status->{IF}", condition }. |
557 |
|
|
qq{"$Status->{condition}"}; |
558 |
|
|
} |
559 |
|
|
} elsif ($name eq 'CheckName') { |
560 |
|
|
$opt{version} = '1.0' if $opt{condition} and |
561 |
|
|
($opt{condition} eq 'DOM2' or |
562 |
|
|
$opt{condition} eq 'DOM1'); |
563 |
|
|
my $chk = perl_if |
564 |
|
|
(qq<##CHKNAME##>, undef, |
565 |
|
|
(perl_statement |
566 |
|
|
perl_exception |
567 |
|
|
(class => 'DOMException', |
568 |
|
|
type => 'INVALID_CHARACTER_ERR', |
569 |
|
|
subtype_uri => |
570 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_BAD_NAME>, |
571 |
|
|
param => { |
572 |
|
|
ExpandedURI q<DOMCore:name> |
573 |
|
|
=> perl_code_literal |
574 |
|
|
(perl_var type => '$', local_name => 'qname'), |
575 |
|
|
}))); |
576 |
|
|
my $chk10 = $chk; |
577 |
|
|
$chk10 =~ s{##CHKNAME##} |
578 |
|
|
{q<$qname =~ /\A\p{InXML_NameStartChar10}>. |
579 |
|
|
q<\p{InXMLNameChar10}*\z/>}ge; |
580 |
|
|
my $chk11 = $chk; |
581 |
|
|
$chk11 =~ s{##CHKNAME##} |
582 |
|
|
{q<$qname =~ /\A\p{InXMLNameStartChar11}>. |
583 |
|
|
q<\p{InXMLNameChar11}*\z/>}ge; |
584 |
|
|
my %class; |
585 |
|
|
|
586 |
|
|
if ($opt{version} and $opt{version} eq '1.0') { |
587 |
|
|
$r = $chk10; |
588 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10/); |
589 |
|
|
} elsif ($opt{version} and $opt{version} eq '1.1') { |
590 |
|
|
$r = $chk11; |
591 |
|
|
%class = (qw/InXMLNameStartChar11 InXMLNameChar11/); |
592 |
|
|
} elsif ($opt{version}) { |
593 |
|
|
$r = perl_if (q<defined >. |
594 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
595 |
|
|
q< and >. |
596 |
|
|
perl_var (type => '$', local_name => $opt{version}) . |
597 |
|
|
q< eq '1.1'>, $chk11, $chk10); |
598 |
|
|
%class = (qw/InXML_NameStartChar10 InXMLNameChar10 |
599 |
|
|
InXMLNameStartChar11 InXMLNameChar11/); |
600 |
|
|
} else { |
601 |
|
|
valid_err q<Built-in code parameter "version" required>; |
602 |
|
|
} |
603 |
|
|
$opt{name} or valid_err q<Built-in code parameter "name" required>; |
604 |
|
|
$r =~ s/\$qname\b/\$$opt{name}/g; |
605 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML'} or |
606 |
|
|
valid_err q<"Char::Class::XML" must be "Require"d in the interface >. |
607 |
|
|
qq{"$Status->{IF}", condition "$Status->{condition}"}; |
608 |
|
|
for (%class) { |
609 |
|
|
$Info->{Require_perl_package_use}->{'Char::Class::XML::::Import'}->{$_} or |
610 |
|
|
valid_err qq<"$_" must be exported from "Char::Class::XML" in the >. |
611 |
|
|
qq{interface "$Status->{IF}", condition }. |
612 |
|
|
qq{"$Status->{condition}"}; |
613 |
|
|
} |
614 |
|
|
} elsif ($name eq 'CheckNull') { |
615 |
|
|
$r = perl_code q{ |
616 |
|
|
__EXCEPTION{ |
617 |
|
|
ManakaiDOMImplementationException.PARAM_NULL_POINTER:: |
618 |
|
|
<Q:MDOM_EXCEPTION:param-name> => 'arg', |
619 |
|
|
}__ unless defined $arg; |
620 |
|
|
}; |
621 |
|
|
$opt{s} or valid_err q<Built-in code parameter "s" required>; |
622 |
|
|
$r =~ s/\$arg\b/\$$opt{s}/g; |
623 |
|
|
$r =~ s/'arg'/perl_literal ($opt{s})/ge; |
624 |
|
|
} elsif ($name eq 'XMLVersion') { |
625 |
|
|
$r = perl_code q{ |
626 |
|
|
$r = defined $node->{<Q:DOMCore:hasFeature>}->{XML} ? |
627 |
|
|
defined $node->{<Q:infoset:version>} ? |
628 |
|
|
$node->{<Q:infoset:version>} : '1.0' : null; |
629 |
|
|
}; |
630 |
|
|
$opt{docNode} or valid_err q<Built-in code parameter "docNode" required>; |
631 |
|
|
$r =~ s/\$node\b/\$$opt{docNode}/g; |
632 |
|
|
$opt{out} or valid_err q<Built-in code parameter "out" required>; |
633 |
|
|
$r =~ s/\$r\b/\$$opt{out}/g; |
634 |
|
|
} elsif ($name eq 'XMLNS') { |
635 |
|
|
for (qw/docNode namespaceURI qualifiedName out-version |
636 |
|
|
out-prefix out-localName/) { |
637 |
|
|
$opt{$_} or valid_err qq<Built-in code parameter "$_" required>, |
638 |
|
|
node => $opt{node}; |
639 |
|
|
} |
640 |
|
|
|
641 |
|
|
## Check the Document XML version |
642 |
|
|
## - The Document must support the "XML" feature |
643 |
|
|
$r = perl_builtin_code ('XMLVersion', %opt, |
644 |
|
|
out => $opt{'out-version'}, |
645 |
|
|
docNode => $opt{docNode}); |
646 |
|
|
$r .= perl_if |
647 |
|
|
(q<defined >.perl_var (type => '$', |
648 |
|
|
local_name => $opt{'out-version'}), |
649 |
|
|
undef, |
650 |
|
|
perl_statement |
651 |
|
|
perl_exception |
652 |
|
|
(type => 'NOT_SUPPORTED_ERR', |
653 |
|
|
class => 'DOMException', |
654 |
|
|
subtype_uri => |
655 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_DOC_NOSUPPORT_XML>)); |
656 |
|
|
|
657 |
|
|
## Check the QName |
658 |
|
|
$r .= perl_builtin_code ('CheckQName', %opt, |
659 |
|
|
qname => $opt{qualifiedName}, |
660 |
|
|
version => $opt{'out-version'}); |
661 |
|
|
|
662 |
|
|
## Split QName into prefix and local name |
663 |
|
|
my $prefix = perl_var (type => '$', local_name => $opt{'out-prefix'}); |
664 |
|
|
my $lname = perl_var (type => '$', local_name => $opt{'out-localName'}); |
665 |
|
|
my $nsURI = perl_var (type => '$', local_name => $opt{namespaceURI}); |
666 |
|
|
$r .= qq{($prefix, $lname) = split /:/, \$$opt{qualifiedName}, 2; |
667 |
|
|
($prefix, $lname) = (undef, $prefix) unless defined $lname;}; |
668 |
|
|
|
669 |
|
|
## Check namespace binding |
670 |
|
|
$r .= perl_if |
671 |
|
|
(qq<defined $prefix>, |
672 |
|
|
perl_cases ( |
673 |
|
|
qq<not defined $nsURI>, |
674 |
|
|
=> perl_statement |
675 |
|
|
(perl_exception |
676 |
|
|
(type => 'NAMESPACE_ERR', |
677 |
|
|
class => 'DOMException', |
678 |
|
|
subtype_uri => |
679 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_PREFIX_WITH_NULL_URI>, |
680 |
|
|
param => { |
681 |
|
|
ExpandedURI q<infoset:prefix> => |
682 |
|
|
perl_code_literal ($prefix), |
683 |
|
|
})), |
684 |
|
|
qq<$prefix eq 'xml' and $nsURI ne >. |
685 |
|
|
perl_literal (ExpandedURI q<xml:>) |
686 |
|
|
=> perl_statement |
687 |
|
|
(perl_exception |
688 |
|
|
(type => 'NAMESPACE_ERR', |
689 |
|
|
class => 'DOMException', |
690 |
|
|
subtype_uri => |
691 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_XML_WITH_OTHER_URI>, |
692 |
|
|
param => { |
693 |
|
|
ExpandedURI q<infoset:namespaceName> => |
694 |
|
|
perl_code_literal ($nsURI), |
695 |
|
|
})), |
696 |
|
|
qq<$prefix eq 'xmlns' and $nsURI ne >. |
697 |
|
|
perl_literal (ExpandedURI q<xmlns:>) |
698 |
|
|
=> perl_statement |
699 |
|
|
(perl_exception |
700 |
|
|
(type => 'NAMESPACE_ERR', |
701 |
|
|
class => 'DOMException', |
702 |
|
|
subtype_uri => |
703 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_XMLNS_WITH_OTHER_URI>, |
704 |
|
|
param => { |
705 |
|
|
ExpandedURI q<infoset:namespaceName> => |
706 |
|
|
perl_code_literal ($nsURI), |
707 |
|
|
})), |
708 |
|
|
perl_literal (ExpandedURI q<xml:>). |
709 |
|
|
qq< eq $nsURI and $prefix ne 'xml'> |
710 |
|
|
=> perl_statement |
711 |
|
|
(perl_exception |
712 |
|
|
(type => 'NAMESPACE_ERR', |
713 |
|
|
class => 'DOMException', |
714 |
|
|
subtype_uri => |
715 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_OTHER_WITH_XML_URI>, |
716 |
|
|
param => { |
717 |
|
|
ExpandedURI q<infoset:prefix> => |
718 |
|
|
perl_code_literal ($prefix), |
719 |
|
|
ExpandedURI q<DOMCore:qualifiedName> |
720 |
|
|
=> perl_code_literal ('$qualifiedName'), |
721 |
|
|
})), |
722 |
|
|
perl_literal (ExpandedURI q<xmlns:>). |
723 |
|
|
qq< eq $nsURI and $prefix ne 'xmlns'> |
724 |
|
|
=> perl_statement |
725 |
|
|
(perl_exception |
726 |
|
|
(type => 'NAMESPACE_ERR', |
727 |
|
|
class => 'DOMException', |
728 |
|
|
subtype_uri => |
729 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_OTHER_WITH_XMLNS_URI>, |
730 |
|
|
param => { |
731 |
|
|
ExpandedURI q<infoset:prefix> => |
732 |
|
|
perl_code_literal ($prefix), |
733 |
|
|
ExpandedURI q<DOMCore:qualifiedName> |
734 |
|
|
=> perl_code_literal ('$qualifiedName'), |
735 |
|
|
})), |
736 |
|
|
perl_literal (ExpandedURI q<xmlns:>). |
737 |
|
|
qq< eq $nsURI and $prefix eq 'xmlns' and $lname eq 'xmlns'> |
738 |
|
|
=> perl_statement |
739 |
|
|
(perl_exception |
740 |
|
|
(type => 'NAMESPACE_ERR', |
741 |
|
|
class => 'DOMException', |
742 |
|
|
subtype_uri => |
743 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_XMLNS_XMLNS>, |
744 |
|
|
param => { |
745 |
|
|
})), |
746 |
|
|
), |
747 |
|
|
perl_cases ( # No prefix |
748 |
|
|
perl_literal (ExpandedURI q<xml:>).qq< eq $nsURI> |
749 |
|
|
=> perl_statement |
750 |
|
|
(perl_exception |
751 |
|
|
(type => 'NAMESPACE_ERR', |
752 |
|
|
class => 'DOMException', |
753 |
|
|
subtype_uri => |
754 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_OTHER_WITH_XML_URI>, |
755 |
|
|
param => { |
756 |
|
|
ExpandedURI q<DOMCore:qualifiedName> |
757 |
|
|
=> perl_code_literal ($lname), |
758 |
|
|
})), |
759 |
|
|
perl_literal (ExpandedURI q<xmlns:>). |
760 |
|
|
qq< eq $nsURI and $lname ne 'xmlns'> |
761 |
|
|
=> perl_statement |
762 |
|
|
(perl_exception |
763 |
|
|
(type => 'NAMESPACE_ERR', |
764 |
|
|
class => 'DOMException', |
765 |
|
|
subtype_uri => |
766 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_OTHER_WITH_XMLNS_URI>, |
767 |
|
|
param => { |
768 |
|
|
ExpandedURI q<DOMCore:qualifiedName> |
769 |
|
|
=> perl_code_literal ($lname), |
770 |
|
|
})), |
771 |
|
|
qq<$lname eq 'xmlns' and $nsURI ne >. |
772 |
|
|
perl_literal (ExpandedURI q<xmlns:>) |
773 |
|
|
=> perl_statement |
774 |
|
|
(perl_exception |
775 |
|
|
(type => 'NAMESPACE_ERR', |
776 |
|
|
class => 'DOMException', |
777 |
|
|
subtype_uri => |
778 |
|
|
ExpandedURI q<MDOM_EXCEPTION:MDOM_NS_XMLNSQ_WITH_OTHER_URI>, |
779 |
|
|
param => { |
780 |
|
|
ExpandedURI q<infoset:namespaceName> |
781 |
|
|
=> perl_code_literal ($nsURI), |
782 |
|
|
})), |
783 |
|
|
)); |
784 |
|
|
} elsif ($name eq 'isRelativeDOMURI') { |
785 |
|
|
$r = q<$in !~ /^[0-9A-Za-z+_.%-]:/>; |
786 |
|
|
## TODO: I18n consideration |
787 |
|
|
for (qw/in/) { |
788 |
|
|
$opt{$_} or valid_err qq<Built-in code parameter "$_" required>, |
789 |
|
|
node => $opt{node}; |
790 |
|
|
$r =~ s/\$$_/\$$opt{$_}/g; |
791 |
|
|
} |
792 |
|
|
} elsif ($name eq 'ParseFeatures') { |
793 |
|
|
$r = q{ |
794 |
|
|
{ |
795 |
|
|
if (ref $in eq 'HASH') { |
796 |
|
|
for (keys %$in) { |
797 |
|
|
if ($_ =~ /^\+(.+)/) { |
798 |
|
|
$out{lc $1} = {version => $in{$_}, plus => 1}; |
799 |
|
|
} else { |
800 |
|
|
$out{lc $_} = {version => $in{$_}, plus => 0}; |
801 |
|
|
} |
802 |
|
|
} |
803 |
|
|
} else { |
804 |
|
|
my @f = grep {length} split /\s+/, $in; |
805 |
|
|
for (my $i = 0; $i < @f; $i++) { |
806 |
|
|
my ($name, $plus) = (lc $f[$i]); |
807 |
|
|
$plus = 1 if $name =~ s/^\+//; |
808 |
|
|
if ($i + 1 < @f and $f[$i + 1] =~ /^\d/) { |
809 |
|
|
$out{$name} = {version => $f[$i + 1], plus => $plus}; $i++; |
810 |
|
|
} else { |
811 |
|
|
$out{$name} = {version => undef, plus => $plus}; |
812 |
|
|
} |
813 |
|
|
} |
814 |
|
|
} |
815 |
|
|
} |
816 |
|
|
}; ## NOTE: Feature name is case-insensitive. |
817 |
|
|
## NOTE: This code does not work if a feature appears more than |
818 |
|
|
## one versions. DOM specification does not specify how |
819 |
|
|
## implementations should cope with such case. |
820 |
|
|
for (qw/in out/) { |
821 |
|
|
$opt{$_} or valid_err qq<Built-in code parameter "$_" required>, |
822 |
|
|
node => $opt{node}; |
823 |
|
|
$r =~ s/\$$_/\$$opt{$_}/g; |
824 |
|
|
$r =~ s/%$_/%$opt{$_}/g; |
825 |
|
|
} |
826 |
|
|
} else { |
827 |
|
|
valid_err qq<Built-in code "$name" not defined>; |
828 |
|
|
} |
829 |
|
|
$r; |
830 |
|
|
} |
831 |
|
|
|
832 |
wakaba |
1.3 |
=head2 C<Operator> element |
833 |
|
|
|
834 |
|
|
An C<Operatpr> element associates an operator or special-purpose |
835 |
|
|
function name to the method or attribute. For the Perl binding, |
836 |
|
|
it can be used to declare the method or attribute to be |
837 |
|
|
called at the operation (by overloading of an operator; |
838 |
|
|
see also L<overload>). |
839 |
|
|
|
840 |
|
|
Element value: A C<Type> dependent operator name. |
841 |
|
|
For the Perl binding, it is either the operator name |
842 |
|
|
used with the C<overload> module (except C<=>), |
843 |
|
|
C<DESTROY> or C<new>. |
844 |
|
|
|
845 |
|
|
Child elements: |
846 |
|
|
|
847 |
|
|
=over 4 |
848 |
|
|
|
849 |
|
|
=item C<Type> = type (Required) |
850 |
|
|
|
851 |
|
|
The type of the element value. It also specifies the |
852 |
|
|
target binding of the C<Operatpr> element. |
853 |
|
|
|
854 |
|
|
=back |
855 |
|
|
|
856 |
|
|
=cut |
857 |
|
|
|
858 |
wakaba |
1.1 |
sub ops2perl () { |
859 |
|
|
my $result = ''; |
860 |
|
|
for (keys %{$Status->{Operator}}) { |
861 |
|
|
if ($_ eq 'DESTROY') { |
862 |
|
|
$result .= perl_statement q<sub DESTROY ($)>; |
863 |
|
|
$result .= perl_statement |
864 |
|
|
perl_assign |
865 |
|
|
perl_var (type => '*', local_name => 'DESTROY') |
866 |
|
|
=> $Status->{Operator}->{DESTROY}; |
867 |
|
|
delete $Status->{Operator}->{DESTROY}; |
868 |
|
|
} elsif ($_ eq 'new') { |
869 |
|
|
$result .= perl_statement q<sub new ($)>; |
870 |
|
|
$result .= perl_statement |
871 |
|
|
perl_assign |
872 |
|
|
perl_var (type => '*', local_name => 'new') |
873 |
|
|
=> $Status->{Operator}->{$_}; |
874 |
|
|
delete $Status->{Operator}->{$_}; |
875 |
|
|
} elsif ($_ eq 'object-error-handler') { |
876 |
|
|
$result .= perl_statement q<sub ___report_error ($$)>; |
877 |
|
|
$result .= perl_statement |
878 |
|
|
perl_assign |
879 |
|
|
perl_var (type => '*', local_name => '___report_error') |
880 |
|
|
=> $Status->{Operator}->{$_}; |
881 |
|
|
delete $Status->{Operator}->{$_}; |
882 |
|
|
} elsif ({qw[ |
883 |
|
|
+ 1 - 1 * 1 / 1 % 1 ** 1 << 1 >> 1 x 1 . 1 |
884 |
|
|
+= 1 -= 1 *= 1 /= 1 %= 1 **= 1 <<= 1 >>= 1 x= 1 .= 1 |
885 |
|
|
< 1 <= 1 > 1 >= 1 == 1 != 1 <=> 1 |
886 |
|
|
lt 1 le 1 gt 1 ge 1 eq 1 ne 1 cmp 1 |
887 |
|
|
& 1 | 1 ^ 1 |
888 |
|
|
neg 1 ! 1 ~ 1 |
889 |
|
|
++ 1 -- 1 |
890 |
|
|
atan2 1 cos 1 sin 1 exp 1 abs 1 log 1 sqrt 1 |
891 |
|
|
bool 1 "" 1 0+ 1 |
892 |
|
|
<> 1 |
893 |
|
|
${} 1 @{} 1 %{} 1 &{} 1 *{} 1 |
894 |
|
|
]}->{$_}) { |
895 |
|
|
# |
896 |
|
|
} else { |
897 |
|
|
valid_err qq[$Status->{if}: Operator "$_" not supported]; |
898 |
|
|
} |
899 |
|
|
} |
900 |
|
|
if (keys %{$Status->{Operator}}) { |
901 |
|
|
$result .= perl_statement 'use overload ' . |
902 |
|
|
perl_list map ({($_, |
903 |
|
|
perl_code_literal $Status->{Operator}->{$_})} |
904 |
|
|
keys %{$Status->{Operator}}), |
905 |
|
|
fallback => 1; |
906 |
|
|
} |
907 |
|
|
$result; |
908 |
|
|
} |
909 |
|
|
|
910 |
|
|
|
911 |
|
|
|
912 |
|
|
sub qname_label ($;%) { |
913 |
|
|
my ($node, %opt) = @_; |
914 |
|
|
my $q = defined $opt{qname} ? $opt{qname} |
915 |
|
|
: $node->get_attribute_value ('QName'); |
916 |
|
|
my $prefix = DEFAULT_PFX; |
917 |
|
|
if ($q =~ s/^([^:]*)://) { |
918 |
|
|
$prefix = $1; |
919 |
|
|
} |
920 |
|
|
|
921 |
|
|
if ($prefix ne DEFAULT_PFX or not $opt{no_default_ns}) { |
922 |
|
|
if (defined $Info->{Namespace}->{$prefix}) { |
923 |
|
|
my $uri = $Info->{Namespace}->{$prefix}; |
924 |
|
|
if (defined $Status->{ns_in_doc}->{$prefix}) { |
925 |
|
|
if ($Status->{ns_in_doc}->{$prefix} ne $uri) { |
926 |
|
|
my $i = 1; |
927 |
|
|
{ |
928 |
|
|
if (defined $Status->{ns_in_doc}->{$prefix.$i}) { |
929 |
|
|
if ($Status->{ns_in_doc}->{$prefix.$i} eq $uri) { |
930 |
|
|
$prefix .= $i; last; |
931 |
|
|
} else { |
932 |
|
|
$i++; redo; |
933 |
|
|
} |
934 |
|
|
} else { |
935 |
|
|
$Status->{ns_in_doc}->{$prefix.$i} = $uri; |
936 |
|
|
$prefix .= $i; last; |
937 |
|
|
} |
938 |
|
|
} |
939 |
|
|
} |
940 |
|
|
} else { |
941 |
|
|
$Status->{ns_in_doc}->{$prefix} = $uri; |
942 |
|
|
} |
943 |
|
|
} else { |
944 |
wakaba |
1.4 |
valid_err qq<Namespace prefix "$prefix" not defined>, |
945 |
|
|
node => defined $opt{qname} ? undef : $node->get_attribute ('QName'); |
946 |
wakaba |
1.1 |
} |
947 |
|
|
} |
948 |
|
|
|
949 |
|
|
$opt{out_type} ||= ExpandedURI q<DOMMain:any>; |
950 |
|
|
if ($opt{out_type} eq ExpandedURI q<lang:pod>) { |
951 |
|
|
pod_code ($prefix eq DEFAULT_PFX ? $q : qq<$prefix:$q>); |
952 |
|
|
} else { |
953 |
|
|
$prefix eq DEFAULT_PFX ? qq<"$q"> : qq<"$prefix:$q">; |
954 |
|
|
} |
955 |
|
|
} |
956 |
|
|
|
957 |
wakaba |
1.3 |
=head1 TYPES |
958 |
|
|
|
959 |
|
|
In the DIS format, types (such as datatypes of something defined |
960 |
|
|
by the DIS document or media types of the element values) are |
961 |
|
|
identified by pair of a namespace URI and a local name. In general, |
962 |
|
|
the pair is specified by a QName in the DIS document. The pair is |
963 |
|
|
sometiems interpreted as a URI reference for the purpose of |
964 |
|
|
comparise. |
965 |
|
|
|
966 |
|
|
NOTE: In DIS documents, the QName is less strictly defined than |
967 |
|
|
the XML standards; its namespace prefix can be empty; and |
968 |
|
|
its namespace prefix and local name can contain any character |
969 |
|
|
other than C<COLON>. In addition, the interpretation of the |
970 |
|
|
null-prefixed QName might differ by the context in which the |
971 |
|
|
QName is used. In general, its namespace is the default |
972 |
|
|
namespace, as is QName in the XML document representing an element |
973 |
|
|
type name. But some local names, such as C<long> and C<DOMString> |
974 |
|
|
might be interpreted as belonging to the C<DOMMain> namespace. |
975 |
|
|
|
976 |
|
|
=cut |
977 |
|
|
|
978 |
wakaba |
1.1 |
{ |
979 |
|
|
my $nest = 0; |
980 |
|
|
sub type_normalize ($); |
981 |
|
|
sub type_normalize ($) { |
982 |
|
|
my ($uri) = @_; |
983 |
|
|
$nest++ == 100 and valid_err q<Possible loop for DataTypeAlias of <$uri>>; |
984 |
|
|
if ($Info->{DataTypeAlias}->{$uri}->{canon_uri}) { |
985 |
|
|
$uri = type_normalize ($Info->{DataTypeAlias}->{$uri}->{canon_uri}); |
986 |
|
|
} |
987 |
|
|
$nest--; |
988 |
|
|
$uri; |
989 |
|
|
} |
990 |
|
|
} |
991 |
|
|
|
992 |
|
|
{ |
993 |
|
|
my $nest = 0; |
994 |
|
|
sub type_isa ($$); |
995 |
|
|
sub type_isa ($$) { |
996 |
|
|
my ($uri, $uri2) = @_; |
997 |
|
|
$nest++ == 100 and valid_err qq<Possible loop for <DataType/ISA> of <$uri>>; |
998 |
|
|
my $r = 0; |
999 |
|
|
if ($uri eq $uri2) { |
1000 |
|
|
$r = 1; |
1001 |
|
|
} else { |
1002 |
|
|
for (@{$Info->{DataTypeAlias}->{$uri}->{isa_uri}||[]}) { |
1003 |
|
|
if (type_isa $_, $uri2) { |
1004 |
|
|
$r = 1; |
1005 |
|
|
last; |
1006 |
|
|
} |
1007 |
|
|
} |
1008 |
|
|
} |
1009 |
|
|
$nest--; |
1010 |
|
|
$r; |
1011 |
|
|
} |
1012 |
|
|
} |
1013 |
|
|
|
1014 |
|
|
sub type_label ($;%) { |
1015 |
|
|
my $uri = type_normalize shift; |
1016 |
|
|
my %opt = @_; |
1017 |
|
|
my $pod_code = sub { $opt{is_pod} ? pod_code $_[0] : $_[0] }; |
1018 |
|
|
my $r = { |
1019 |
wakaba |
1.3 |
ExpandedURI q<DOMMain:boolean> => q<Boolean Value>, |
1020 |
|
|
ExpandedURI q<DOMMain:long> => q<Signed Long Integer>, |
1021 |
wakaba |
1.1 |
ExpandedURI q<DOMMain:unsigned-long> => q<Unsigned Long Integer>, |
1022 |
wakaba |
1.3 |
ExpandedURI q<DOMMain:unsigned-short> => q<Unsigned Short Floating Number>, |
1023 |
wakaba |
1.1 |
ExpandedURI q<ManakaiDOM:ManakaiDOMURI> |
1024 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM URI)>, |
1025 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI> |
1026 |
wakaba |
1.3 |
=> $pod_code->(q<DOMString>).q< (DOM Namespace URI)>, |
1027 |
wakaba |
1.1 |
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatureName> |
1028 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM Feature name)>, |
1029 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatureVersion> |
1030 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM Feature version)>, |
1031 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatures> |
1032 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM features)>, |
1033 |
wakaba |
1.3 |
ExpandedURI q<ManakaiDOM:ManakaiDOMKeyIdentifier> |
1034 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM Key Identifier)>, |
1035 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMKeyIdentifiers> |
1036 |
|
|
=> $pod_code->(q<DOMString>).q< (DOM Key Identifiers)>, |
1037 |
wakaba |
1.1 |
}->{$uri}; |
1038 |
|
|
unless ($r) { |
1039 |
|
|
if ($uri =~ /([\w_-]+)$/) { |
1040 |
|
|
my $label = $1; |
1041 |
|
|
$label =~ s/--+/ /g; |
1042 |
|
|
$label =~ s/__+/ /g; |
1043 |
|
|
$r = $pod_code->($label); |
1044 |
|
|
} else { |
1045 |
|
|
$r = $pod_code->("<$uri>"); |
1046 |
|
|
} |
1047 |
|
|
} |
1048 |
|
|
$r; |
1049 |
|
|
} |
1050 |
|
|
|
1051 |
|
|
sub type_package_name ($) { |
1052 |
|
|
my $qname = shift; |
1053 |
|
|
if ($qname =~ /^([^:]*):([^:]*)$/) { |
1054 |
|
|
perl_package_name name => perl_name $2, ucfirst => 1; |
1055 |
|
|
} else { |
1056 |
|
|
perl_package_name name => perl_name $qname, ucfirst => 1; |
1057 |
|
|
} |
1058 |
|
|
} |
1059 |
|
|
|
1060 |
|
|
sub ns_uri_to_perl_package_name ($) { |
1061 |
|
|
my $uri = shift; |
1062 |
|
|
if ($Info->{uri_to_perl_package}->{$uri}) { |
1063 |
|
|
return $Info->{uri_to_perl_package}->{$uri}; |
1064 |
|
|
} else { |
1065 |
|
|
return qq<Perl package name for namespace <$uri> not defined>; |
1066 |
|
|
} |
1067 |
|
|
} |
1068 |
|
|
|
1069 |
|
|
sub ns_prefix_to_uri ($) { |
1070 |
|
|
my $pfx = shift; |
1071 |
|
|
if (exists $Info->{Namespace}->{$pfx}) { |
1072 |
|
|
if (not defined $Info->{Namespace}->{$pfx}) { |
1073 |
|
|
valid_err qq<Namespace name for "$pfx" not defined>; |
1074 |
|
|
} else { |
1075 |
|
|
return $Info->{Namespace}->{$pfx}; |
1076 |
|
|
} |
1077 |
|
|
} else { |
1078 |
|
|
valid_err qq<Namespace prefix "$pfx" not declared>; |
1079 |
|
|
} |
1080 |
|
|
} |
1081 |
|
|
|
1082 |
|
|
sub type_expanded_uri ($) { |
1083 |
|
|
my $qname = shift || ''; |
1084 |
|
|
if ($qname =~ /^[a-z-]+$/ or $qname eq 'Object') { |
1085 |
|
|
expanded_uri ("DOMMain:$qname"); |
1086 |
|
|
} else { |
1087 |
|
|
expanded_uri ($qname); |
1088 |
|
|
} |
1089 |
|
|
} |
1090 |
|
|
|
1091 |
|
|
sub expanded_uri ($) { |
1092 |
|
|
my $lname = shift || ''; |
1093 |
|
|
my $pfx = DEFAULT_PFX; |
1094 |
|
|
if ($lname =~ s/^([^:]*)://) { |
1095 |
|
|
$pfx = $1; |
1096 |
|
|
} |
1097 |
|
|
ns_prefix_to_uri ($pfx) . $lname; |
1098 |
|
|
} |
1099 |
|
|
|
1100 |
|
|
sub array_contains ($$) { |
1101 |
|
|
my ($array, $val) = @_; |
1102 |
|
|
if (ref $array eq 'ARRAY') { |
1103 |
|
|
for (@$array) { |
1104 |
|
|
return 1 if $_ eq $val; |
1105 |
|
|
} |
1106 |
|
|
} else { |
1107 |
|
|
return $array eq $val; |
1108 |
|
|
} |
1109 |
|
|
return 0; |
1110 |
|
|
} |
1111 |
|
|
|
1112 |
|
|
|
1113 |
|
|
sub get_warning_perl_code ($) { |
1114 |
|
|
my $pnode = shift; |
1115 |
|
|
my $r = ''; |
1116 |
|
|
for my $node (@{$pnode->child_nodes}) { |
1117 |
|
|
next unless $node->node_type eq '#element' and |
1118 |
|
|
$node->local_name eq 'Warning'; |
1119 |
|
|
my %param; |
1120 |
|
|
for (@{$node->child_nodes}) { |
1121 |
|
|
next unless $_->node_type eq '#element' and |
1122 |
|
|
$_->local_name eq 'Param'; |
1123 |
|
|
$param{expanded_uri $_->get_attribute_value ('QName')} |
1124 |
|
|
= perl_code_literal get_value_literal ($_, name => 'Value', |
1125 |
|
|
type_name => 'Type'); |
1126 |
|
|
} |
1127 |
|
|
$r .= perl_statement |
1128 |
|
|
perl_exception |
1129 |
|
|
class => type_package_name $node->get_attribute_value |
1130 |
|
|
('Type', |
1131 |
|
|
default => 'DOMMain:any'), |
1132 |
|
|
type => $node->get_attribute_value ('Name'), |
1133 |
|
|
param => \%param; |
1134 |
|
|
} |
1135 |
|
|
$r; |
1136 |
|
|
} # get_warning_perl_code |
1137 |
|
|
|
1138 |
|
|
sub get_perl_definition_node ($%) { |
1139 |
|
|
my ($node, %opt) = @_; |
1140 |
|
|
my $ln = $opt{name} || 'Def'; |
1141 |
|
|
my $def = $node->get_element_by (sub { |
1142 |
|
|
my ($me, $you) = @_; |
1143 |
|
|
$you->local_name eq $ln and |
1144 |
|
|
type_expanded_uri $you->get_attribute_value ('Type', default => '') |
1145 |
|
|
eq ExpandedURI q<lang:Perl> and |
1146 |
|
|
condition_match ($you, %opt); |
1147 |
|
|
}) || ($opt{use_dis} and $node->get_element_by (sub { |
1148 |
|
|
my ($me, $you) = @_; |
1149 |
|
|
$you->local_name eq $ln and |
1150 |
|
|
$you->get_attribute_value ('Type', default => '') |
1151 |
|
|
eq ExpandedURI q<lang:dis> and |
1152 |
|
|
condition_match ($you, %opt); |
1153 |
|
|
})) || $node->get_element_by (sub { |
1154 |
|
|
my ($me, $you) = @_; |
1155 |
|
|
$you->local_name eq $ln and |
1156 |
|
|
not $you->get_attribute_value ('Type', default => '') and |
1157 |
|
|
condition_match ($you, %opt); |
1158 |
|
|
}) || $node->get_element_by (sub { |
1159 |
|
|
my ($me, $you) = @_; |
1160 |
|
|
$you->local_name eq $ln and |
1161 |
|
|
type_expanded_uri $you->get_attribute_value ('Type', default => '') |
1162 |
|
|
eq ExpandedURI q<lang:Perl> and |
1163 |
|
|
condition_match ($you); # no condition specified |
1164 |
|
|
}) || ($opt{use_dis} and $node->get_element_by (sub { |
1165 |
|
|
my ($me, $you) = @_; |
1166 |
|
|
$you->local_name eq $ln and |
1167 |
|
|
type_expanded_uri $you->get_attribute_value ('Type', default => '') |
1168 |
|
|
eq ExpandedURI q<lang:dis> and |
1169 |
|
|
condition_match ($you); # no condition specified |
1170 |
|
|
})) || $node->get_element_by (sub { |
1171 |
|
|
my ($me, $you) = @_; |
1172 |
|
|
$you->local_name eq $ln and |
1173 |
|
|
not $you->get_attribute_value ('Type', default => '') and |
1174 |
|
|
condition_match ($you); # no condition specified |
1175 |
|
|
}); |
1176 |
|
|
$def; |
1177 |
|
|
} |
1178 |
|
|
|
1179 |
|
|
sub get_perl_definition ($%) { |
1180 |
|
|
my ($node, %opt) = @_; |
1181 |
|
|
my $def = get_perl_definition_node $node, %opt; |
1182 |
|
|
$def ? $def->value : $opt{default}; |
1183 |
|
|
} |
1184 |
|
|
|
1185 |
wakaba |
1.3 |
=head1 DISDOC DOCUMENTATION FORMAT |
1186 |
|
|
|
1187 |
|
|
The DISDOC format is a documentation format for DIS documents. |
1188 |
|
|
|
1189 |
|
|
=cut |
1190 |
|
|
|
1191 |
wakaba |
1.1 |
sub dis2perl ($) { |
1192 |
|
|
my $node = shift; |
1193 |
|
|
my $r = ''; |
1194 |
|
|
for (@{$node->child_nodes}) { |
1195 |
|
|
next unless $_->node_type eq '#element'; |
1196 |
|
|
if ($_->local_name eq 'GetProp') { |
1197 |
|
|
$r .= perl_statement perl_assign |
1198 |
|
|
perl_var (type => '$', local_name => 'r') |
1199 |
|
|
=> '$self->{node}->{' . |
1200 |
|
|
perl_literal (expanded_uri ($_->value)) . '}'; |
1201 |
|
|
} elsif ($_->local_name eq 'GetPropNode') { |
1202 |
|
|
$r .= perl_statement perl_assign |
1203 |
|
|
perl_var (type => '$', local_name => 'r') |
1204 |
|
|
=> '$self->{node}->{' . |
1205 |
|
|
perl_literal (expanded_uri ($_->value)) . '}'; |
1206 |
|
|
## Conditional |
1207 |
|
|
$r .= perl_statement |
1208 |
|
|
perl_code q{$r = __CLASS{Node}__->__INT{getNodeReference}__ ($r) |
1209 |
|
|
if defined $r}; |
1210 |
|
|
} elsif ($_->local_name eq 'SetProp') { |
1211 |
|
|
my $t = perl_statement perl_assign |
1212 |
|
|
'$self->{node}->{' . |
1213 |
|
|
perl_literal (expanded_uri ($_->value)) . '}' |
1214 |
|
|
=> perl_var (type => '$', local_name => 'given'); |
1215 |
|
|
if ($_->get_attribute_value ('CheckReadOnly', default => 1)) { |
1216 |
|
|
$r .= perl_if |
1217 |
|
|
q[$self->{'node'}->{]. |
1218 |
|
|
perl_literal (ExpandedURI (q<DOMCore:read-only>)).q[}], |
1219 |
|
|
perl_statement |
1220 |
|
|
(perl_exception |
1221 |
|
|
class => 'DOMException', |
1222 |
|
|
type => 'NO_MODIFICATION_ALLOWED_ERR', |
1223 |
|
|
param => {}), |
1224 |
|
|
$t; |
1225 |
|
|
} else { |
1226 |
|
|
$r .= $t; |
1227 |
|
|
} |
1228 |
|
|
} elsif ($_->local_name eq 'Overridden') { |
1229 |
|
|
$r = perl_statement perl_exception |
1230 |
|
|
class => 'ManakaiDOMImplementationException', |
1231 |
|
|
type => 'MDOM_DEBUG_BUG', |
1232 |
|
|
param => { |
1233 |
|
|
ExpandedURI q<MDOM_EXCEPTION:values> => { |
1234 |
|
|
msg => q<This class defines only the interface; >. |
1235 |
|
|
q<some other class must inherit this class >. |
1236 |
|
|
q<and implement this subroutine.>, |
1237 |
|
|
}, |
1238 |
|
|
}; |
1239 |
|
|
} elsif ($_->local_name eq 'Type') { |
1240 |
|
|
# |
1241 |
|
|
} else { |
1242 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
1243 |
|
|
node => $_; |
1244 |
|
|
} |
1245 |
|
|
} |
1246 |
|
|
if (defined $node->value and length $node->value) { |
1247 |
|
|
valid_err q{DIS has value}, node => $node; |
1248 |
|
|
} |
1249 |
|
|
$r; |
1250 |
|
|
} # dis2perl |
1251 |
|
|
|
1252 |
|
|
{ |
1253 |
|
|
use re 'eval'; |
1254 |
|
|
our $Element; |
1255 |
|
|
$Element = qr/[A-Za-z0-9]+(?>:(?>[^<>]*)(?>(?>[^<>]+|<(??{$Element})>)*))?/; |
1256 |
|
|
my $MElement = qr/([A-Za-z0-9]+)(?>:((?>[^<>]*)(?>(?>[^<>]+|<(??{$Element})>)*)))?/; |
1257 |
|
|
|
1258 |
|
|
sub disdoc2text ($;%); |
1259 |
|
|
sub disdoc2text ($;%) { |
1260 |
|
|
my ($s, %opt) = @_; |
1261 |
|
|
$s =~ s/\x0D\x0A/\x0A/g; |
1262 |
|
|
$s =~ tr/\x0D/\x0A/; |
1263 |
|
|
my @s = split /\x0A\x0A+/, $s; |
1264 |
|
|
my @r; |
1265 |
|
|
for my $s (@s) { |
1266 |
|
|
if ($s =~ s/^\{([0-9A-Za-z-]+)::\s*//) { ## Start tag'ed element |
1267 |
|
|
my $et = $1; |
1268 |
|
|
if ($et eq 'P') { ## Paragraph |
1269 |
|
|
push @r, (disdoc_inline2text ($s, %opt)); |
1270 |
|
|
} elsif ($et eq 'LI' or $et eq 'OLI') { ## List |
1271 |
|
|
my $marker = '* '; |
1272 |
|
|
if ($et eq 'OLI') { |
1273 |
|
|
$marker = '# '; |
1274 |
|
|
} |
1275 |
|
|
if ($s =~ s/^(.+?)::\s*//) { |
1276 |
|
|
$marker = disdoc_inline2text ($1, %opt) . ': '; |
1277 |
|
|
} |
1278 |
|
|
push @r, $marker . (disdoc_inline2text ($s, %opt)); |
1279 |
wakaba |
1.3 |
} elsif ($et eq 'NOTE') { |
1280 |
|
|
push @r, "NOTE: ". disdoc_inline2text ($s, %opt); |
1281 |
|
|
} elsif ($et eq 'eg') { |
1282 |
|
|
push @r, "Example. "; |
1283 |
|
|
$s =~ s/^\s+//; |
1284 |
|
|
valid_err qq<Invalid content for DISDOC "eg" element: "$s">, |
1285 |
|
|
node => $opt{node} if length $s; |
1286 |
wakaba |
1.1 |
} else { |
1287 |
|
|
valid_err qq<Unknown DISDOC element type "$et">, node => $opt{node}; |
1288 |
|
|
} |
1289 |
|
|
} elsif ($s =~ /^\}\s*$/) { ## End tag |
1290 |
|
|
# |
1291 |
|
|
} elsif ($s =~ s/^([-=])\s*//) { ## List |
1292 |
|
|
my $marker = $1; |
1293 |
|
|
if ($marker eq '=') { |
1294 |
|
|
$marker = '# '; |
1295 |
|
|
} elsif ($marker eq '-') { |
1296 |
|
|
$marker = '* '; |
1297 |
|
|
} |
1298 |
|
|
if ($s =~ s/^(.+?)::\s*//) { |
1299 |
|
|
$marker = disdoc_inline2text ($1, %opt) . ': '; |
1300 |
|
|
} |
1301 |
|
|
push @r, $marker . (disdoc_inline2pod ($s, %opt)); |
1302 |
|
|
} elsif ($s =~ /^[^\w\s<]/) { ## Reserved for future extension |
1303 |
|
|
valid_err qq<Broken DISDOC: "$s">, node => $opt{node}; |
1304 |
|
|
} else { |
1305 |
|
|
$s =~ s/^\s+//; |
1306 |
|
|
push @r, disdoc_inline2text ($s, %opt); |
1307 |
|
|
} |
1308 |
|
|
} |
1309 |
|
|
join "\n\n", @r; |
1310 |
|
|
} # disdoc2text |
1311 |
|
|
|
1312 |
|
|
sub disdoc_inline2text ($;%); |
1313 |
|
|
sub disdoc_inline2text ($;%) { |
1314 |
|
|
my ($s, %opt) = @_; |
1315 |
|
|
$s =~ s{\G(?:([^<>]+)|<$MElement>|(.))}{ |
1316 |
|
|
my ($cdata, $type, $data, $err) = ($1, $2, defined $3 ? $3 : '', $4); |
1317 |
|
|
my $r = ''; |
1318 |
|
|
if (defined $err) { |
1319 |
|
|
valid_err qq<Invalid character "$err" in DISDOC>, |
1320 |
|
|
node => $opt{node}; |
1321 |
|
|
} elsif (defined $cdata) { |
1322 |
|
|
$r = $cdata; |
1323 |
wakaba |
1.3 |
} elsif ({DFN => 1, CITE => 1, KEY => 1}->{$type}) { |
1324 |
wakaba |
1.1 |
$r = disdoc_inline2text $data; |
1325 |
|
|
} elsif ({SRC => 1}->{$type}) { |
1326 |
|
|
$r = q<[>. disdoc_inline2text ($data) . q<]>; |
1327 |
wakaba |
1.3 |
} elsif ({EM => 1}->{$type}) { |
1328 |
|
|
$r = q<*>. disdoc_inline2text ($data) . q<*>; |
1329 |
wakaba |
1.1 |
} elsif ({URI => 1}->{$type}) { |
1330 |
|
|
$r = q{<} . $data . q{>}; |
1331 |
|
|
} elsif ({CODE => 1, Perl => 1}->{$type}) { |
1332 |
|
|
$r = q<"> . disdoc_inline2text ($data) . q<">; |
1333 |
|
|
} elsif ({IF => 1, TYPE => 1, P => 1, XML => 1, SGML => 1, DOM => 1, |
1334 |
|
|
FeatureVer => 1, CHAR => 1, HTML => 1, Prefix => 1, |
1335 |
|
|
Module => 1, QUOTE => 1, PerlModule => 1, |
1336 |
|
|
FILE => 1}->{$type}) { |
1337 |
|
|
$r = q<"> . $data . q<">; |
1338 |
|
|
} elsif ({Feature => 1, CP => 1, ERR => 1, |
1339 |
|
|
HA => 1, HE => 1, XA => 1, SA => 1, SE => 1}->{$type}) { |
1340 |
|
|
$r = qname_label (undef, qname => $data, |
1341 |
|
|
no_default_ns => 1); |
1342 |
|
|
} elsif ({Q => 1, EV => 1, |
1343 |
|
|
XE => 1}->{$type}) { |
1344 |
|
|
$r = qname_label (undef, qname => $data); |
1345 |
|
|
} elsif ({M => 1, A => 1, X => 1, WARN => 1}->{$type}) { |
1346 |
|
|
if ($data =~ /^([^.]+)\.([^.]+)$/) { |
1347 |
|
|
$r = q<"> . $1 . '->' . $2 . q<">; |
1348 |
|
|
} else { |
1349 |
|
|
$r = q<"> . $data . q<">; |
1350 |
|
|
} |
1351 |
|
|
} elsif ({InfosetP => 1}->{$type}) { |
1352 |
|
|
$r = q<[> . $data . q<]>; |
1353 |
|
|
} elsif ($type eq 'lt') { |
1354 |
|
|
$r = '<'; |
1355 |
|
|
} elsif ($type eq 'gt') { |
1356 |
|
|
$r = '>'; |
1357 |
|
|
} else { |
1358 |
|
|
valid_err qq<DISDOC element type "$type" not supported>, |
1359 |
|
|
node => $opt{node}; |
1360 |
|
|
} |
1361 |
|
|
$r; |
1362 |
|
|
}ges; |
1363 |
|
|
$s; |
1364 |
|
|
} # disdoc_inline2text |
1365 |
|
|
|
1366 |
|
|
sub disdoc2pod ($;%); |
1367 |
|
|
sub disdoc2pod ($;%) { |
1368 |
|
|
my ($s, %opt) = @_; |
1369 |
|
|
$s =~ s/\x0D\x0A/\x0A/g; |
1370 |
|
|
$s =~ tr/\x0D/\x0A/; |
1371 |
|
|
my @s = split /\x0A\x0A+/, $s; |
1372 |
|
|
my @el = ({type => '#document'}); |
1373 |
|
|
my @r; |
1374 |
|
|
for my $s (@s) { |
1375 |
|
|
if ($s =~ s/^\{([0-9A-Za-z-]+)::\s*//) { ## Start tag'ed element |
1376 |
|
|
my $et = $1; |
1377 |
|
|
if ($el[-1]->{type} eq '#list' and |
1378 |
|
|
not {qw/LI 1 OLI 1/}->{$et}) { |
1379 |
|
|
push @r, '=back'; |
1380 |
|
|
pop @el; |
1381 |
|
|
} |
1382 |
|
|
push @el, {type => $et}; |
1383 |
|
|
if ($et eq 'P') { ## Paragraph |
1384 |
|
|
push @r, pod_para (disdoc_inline2pod ($s, %opt)); |
1385 |
wakaba |
1.3 |
} elsif ($et eq 'NOTE') { |
1386 |
|
|
push @r, pod_para (pod_em ('NOTE').": ".disdoc_inline2pod ($s, %opt)); |
1387 |
|
|
} elsif ($et eq 'eg') { |
1388 |
|
|
push @r, pod_para (pod_em ('Example').". "); |
1389 |
|
|
$s =~ s/^\s+//; |
1390 |
|
|
valid_err qq<Invalid content for DISDOC "eg" element: "$s">, |
1391 |
|
|
node => $opt{node} if length $s; |
1392 |
wakaba |
1.1 |
} elsif ($et eq 'LI' or $et eq 'OLI') { ## List |
1393 |
|
|
my $marker = '*'; |
1394 |
|
|
unless ($el[-1]->{type} eq '#list') { |
1395 |
|
|
push @el, {type => '#list', n => 0}; |
1396 |
|
|
push @r, '=over 4'; |
1397 |
|
|
} |
1398 |
|
|
if ($et eq 'OLI') { |
1399 |
|
|
$marker = ++($el[-1]->{n}) . '. '; |
1400 |
|
|
} |
1401 |
|
|
if ($s =~ s/^(.+?)::\s*//) { |
1402 |
|
|
$marker = disdoc_inline2pod ($1, %opt); |
1403 |
|
|
} |
1404 |
|
|
push @r, pod_item ($marker), pod_para (disdoc_inline2pod ($s, %opt)); |
1405 |
|
|
} else { |
1406 |
|
|
valid_err qq<Unknown DISDOC element type "$et">, node => $opt{node}; |
1407 |
|
|
} |
1408 |
|
|
} elsif ($s =~ /^\}\s*$/) { ## End tag |
1409 |
|
|
while (@el > 1 and $el[-1]->{type} =~ /^\#/) { |
1410 |
|
|
if ($el[-1]->{type} eq '#list') { |
1411 |
|
|
push @r, '=back'; |
1412 |
|
|
} |
1413 |
|
|
pop @el; |
1414 |
|
|
} |
1415 |
|
|
if ($el[-1]->{type} eq '#document') { |
1416 |
|
|
valid_err qq<Unmatched DISDOC end tag>, node => $opt{node}; |
1417 |
|
|
} else { |
1418 |
|
|
pop @el; |
1419 |
|
|
} |
1420 |
|
|
} elsif ($s =~ s/^([-=])\s*//) { ## List |
1421 |
|
|
my $marker = $1; |
1422 |
|
|
unless ($el[-1]->{type} eq '#list') { |
1423 |
|
|
push @el, {type => '#list', n => 0}; |
1424 |
|
|
push @r, '=over 4'; |
1425 |
|
|
} |
1426 |
|
|
if ($marker eq '=') { |
1427 |
|
|
$marker = ++($el[-1]->{n}) . '. '; |
1428 |
|
|
} elsif ($marker eq '-') { |
1429 |
|
|
$marker = '*'; |
1430 |
|
|
} |
1431 |
|
|
if ($s =~ s/^(.+?)::\s*//) { |
1432 |
|
|
$marker = disdoc_inline2pod ($1, %opt); |
1433 |
|
|
} |
1434 |
|
|
push @r, pod_item ($marker), pod_para (disdoc_inline2pod ($s, %opt)); |
1435 |
|
|
} elsif ($s =~ /^[^\w\s<]/) { ## Reserved for future extension |
1436 |
|
|
valid_err qq<Broken DISDOC: "$s">, node => $opt{node}; |
1437 |
|
|
} else { |
1438 |
|
|
if ($el[-1]->{type} eq '#list') { |
1439 |
|
|
push @r, '=back'; |
1440 |
|
|
pop @el; |
1441 |
|
|
} |
1442 |
|
|
$s =~ s/^\s+//; |
1443 |
|
|
push @r, pod_para disdoc_inline2pod ($s, %opt); |
1444 |
|
|
} |
1445 |
|
|
} |
1446 |
|
|
while (@el and $el[-1]->{type} =~ /^\#/) { |
1447 |
|
|
if ($el[-1]->{type} eq '#list') { |
1448 |
|
|
push @r, '=back'; |
1449 |
|
|
} |
1450 |
|
|
pop @el; |
1451 |
|
|
} |
1452 |
|
|
if (@el) { |
1453 |
|
|
valid_err qq[DISDOC end tag required for "$el[-1]->{type}"], |
1454 |
|
|
node => $opt{node}; |
1455 |
|
|
} |
1456 |
|
|
wantarray ? @r : join "\n\n", @r; |
1457 |
|
|
} # disdoc2pod |
1458 |
|
|
|
1459 |
|
|
sub disdoc_inline2pod ($;%); |
1460 |
|
|
sub disdoc_inline2pod ($;%) { |
1461 |
|
|
my ($s, %opt) = @_; |
1462 |
|
|
$s =~ s{\G(?:([^<>]+)|<$MElement>|(.))}{ |
1463 |
|
|
my ($cdata, $type, $data, $err) = ($1, $2, defined $3 ? $3 : '', $4); |
1464 |
|
|
my $r = ''; |
1465 |
|
|
if (defined $err) { |
1466 |
|
|
valid_err qq<Invalid character "$err" in DISDOC>, |
1467 |
|
|
node => $opt{node}; |
1468 |
|
|
} elsif (defined $cdata) { |
1469 |
|
|
$r = pod_cdata $cdata; |
1470 |
wakaba |
1.3 |
} elsif ({CODE => 1, KEY => 1}->{$type}) { |
1471 |
wakaba |
1.1 |
$r = pod_code disdoc_inline2pod $data; |
1472 |
wakaba |
1.3 |
} elsif ({EM => 1}->{$type}) { |
1473 |
|
|
$r = pod_em disdoc_inline2pod $data; |
1474 |
wakaba |
1.1 |
} elsif ({DFN => 1}->{$type}) { |
1475 |
|
|
$r = pod_dfn disdoc_inline2pod $data; |
1476 |
|
|
} elsif ({CITE => 1}->{$type}) { |
1477 |
|
|
$r = q[I<] . disdoc_inline2pod ($data) . q[>]; |
1478 |
|
|
} elsif ({SRC => 1}->{$type}) { |
1479 |
|
|
$r = q<[>. disdoc_inline2pod ($data) . q<]>; |
1480 |
|
|
} elsif ({URI => 1}->{$type}) { |
1481 |
|
|
$r = pod_uri $data; |
1482 |
|
|
} elsif ({ |
1483 |
|
|
IF => 1, TYPE => 1, P => 1, DOM => 1, XML => 1, HTML => 1, |
1484 |
|
|
SGML => 1, FeatureVer => 1, CHAR => 1, Prefix => 1, |
1485 |
|
|
Perl => 1, FILE => 1, |
1486 |
|
|
}->{$type}) { |
1487 |
|
|
$r = pod_code $data; |
1488 |
|
|
} elsif ({Feature => 1, CP => 1, ERR => 1, |
1489 |
|
|
HA => 1, HE => 1, XA => 1, SA => 1, SE => 1}->{$type}) { |
1490 |
|
|
$r = qname_label (undef, qname => $data, |
1491 |
|
|
out_type => ExpandedURI q<lang:pod>, |
1492 |
|
|
no_default_ns => 1); |
1493 |
|
|
} elsif ({Q => 1, EV => 1, |
1494 |
|
|
XE => 1}->{$type}) { |
1495 |
|
|
$r = qname_label (undef, qname => $data, |
1496 |
|
|
out_type => ExpandedURI q<lang:pod>); |
1497 |
|
|
} elsif ({ |
1498 |
|
|
M => 1, A => 1, |
1499 |
|
|
}->{$type}) { |
1500 |
|
|
if ($data =~ /^([^.]+)\.([^.]+)$/) { |
1501 |
|
|
$r = pod_code ($1 . '->' . $2); |
1502 |
|
|
} else { |
1503 |
|
|
$r = pod_code $data; |
1504 |
|
|
} |
1505 |
|
|
} elsif ({X => 1, WARN => 1}->{$type}) { |
1506 |
|
|
if ($data =~ /^([^.]+)\.([^.]+)$/) { |
1507 |
|
|
$r = pod_code ($1) . '.' . pod_code ($2); |
1508 |
|
|
} else { |
1509 |
|
|
$r = pod_code $data; |
1510 |
|
|
} |
1511 |
|
|
} elsif ({InfosetP => 1}->{$type}) { |
1512 |
|
|
$r = q<[> . $data . q<]>; |
1513 |
|
|
} elsif ({QUOTE => 1}->{$type}) { |
1514 |
|
|
$r = q<"> . $data . q<">; |
1515 |
|
|
} elsif ({PerlModule => 1}->{$type}) { |
1516 |
|
|
$r = pod_link label => pod_code ($data), module => $data; |
1517 |
|
|
} elsif ({Module => 1}->{$type}) { |
1518 |
|
|
$r = pod_link label => pod_code ($data), |
1519 |
|
|
module => perl_package_name (name => $data); |
1520 |
|
|
} elsif ($type eq 'lt' or $type eq 'gt') { |
1521 |
|
|
$r = qq<E<$type>>; |
1522 |
|
|
} else { |
1523 |
|
|
valid_err qq<DISDOC element type "$type" not supported>, |
1524 |
|
|
node => $opt{node}; |
1525 |
|
|
} |
1526 |
|
|
$r; |
1527 |
|
|
}ges; |
1528 |
|
|
$s; |
1529 |
|
|
} |
1530 |
|
|
} |
1531 |
|
|
|
1532 |
|
|
sub get_description ($;%) { |
1533 |
|
|
my ($node, %opt) = @_; |
1534 |
|
|
my $ln = $opt{name} || 'Description'; |
1535 |
|
|
my $lang = $opt{lang} || q<en> || q<i-default>; |
1536 |
|
|
my $textplain = ExpandedURI q<DOMMain:any>; |
1537 |
|
|
my $default = q<lang:disdoc>; |
1538 |
|
|
$opt{type} ||= ExpandedURI q<lang:pod>; |
1539 |
|
|
my $script = $opt{script} || q<>; |
1540 |
|
|
my $def; |
1541 |
|
|
for my $type (($opt{type} ne $textplain ? $opt{type} : ()), |
1542 |
|
|
ExpandedURI q<lang:disdoc>, |
1543 |
|
|
$textplain) { |
1544 |
|
|
$def = $node->get_element_by (sub { |
1545 |
|
|
my ($me, $you) = @_; |
1546 |
|
|
$you->local_name eq $ln and |
1547 |
|
|
$you->get_attribute_value ('lang', default => 'i-default') eq $lang and |
1548 |
|
|
type_expanded_uri ($you->get_attribute_value ('Type', default => $default)) |
1549 |
|
|
eq $type; |
1550 |
|
|
}) || $node->get_element_by (sub { |
1551 |
|
|
my ($me, $you) = @_; |
1552 |
|
|
$you->local_name eq $ln and |
1553 |
|
|
$you->get_attribute_value ('lang', default => 'i-default') |
1554 |
|
|
eq 'i-default' and |
1555 |
|
|
type_expanded_uri ($you->get_attribute_value ('Type', default => $default)) |
1556 |
|
|
eq $type; |
1557 |
|
|
}); |
1558 |
|
|
last if $def; |
1559 |
|
|
} |
1560 |
|
|
unless ($def) { |
1561 |
|
|
$opt{default}; |
1562 |
|
|
} else { |
1563 |
|
|
my $srctype = type_expanded_uri |
1564 |
|
|
$def->get_attribute_value ('Type', default => $default); |
1565 |
|
|
my $value = $def->value; |
1566 |
|
|
valid_err q<Description undefined>, node => $def |
1567 |
|
|
unless defined $value; |
1568 |
|
|
if ($srctype eq ExpandedURI q<lang:disdoc>) { |
1569 |
|
|
if ($opt{type} eq ExpandedURI q<lang:pod>) { |
1570 |
|
|
$value = $opt{is_inline} ? |
1571 |
|
|
disdoc_inline2pod ($value, node => $def): |
1572 |
|
|
disdoc2pod ($value, node => $def); |
1573 |
|
|
} else { |
1574 |
|
|
$value = $opt{is_inline} ? |
1575 |
|
|
disdoc_inline2text ($value, node => $def): |
1576 |
|
|
disdoc2text ($value, node => $def); |
1577 |
|
|
if ($opt{type} eq ExpandedURI q<lang:muf>) { |
1578 |
|
|
$value =~ s/\s+/ /g; |
1579 |
|
|
} |
1580 |
|
|
} |
1581 |
|
|
} elsif ($srctype eq ExpandedURI q<lang:muf>) { |
1582 |
|
|
if ($opt{type} eq ExpandedURI q<lang:muf>) { |
1583 |
|
|
$value = muf_template $value; |
1584 |
|
|
$value =~ s/\s+/ /g; |
1585 |
|
|
} else { |
1586 |
|
|
impl_err q<Can't convert MUF tempalte to >.$opt{type}; |
1587 |
|
|
} |
1588 |
|
|
} elsif ($srctype eq $opt{type}) { |
1589 |
|
|
# |
1590 |
|
|
} else { |
1591 |
|
|
if ($opt{type} eq ExpandedURI q<lang:pod>) { |
1592 |
|
|
$value = pod_paras $def->value; |
1593 |
|
|
} elsif ($opt{type} eq ExpandedURI q<lang:muf>) { |
1594 |
|
|
$value =~ s/%/%percent;/g; |
1595 |
|
|
$value =~ s/\s+/ /g; |
1596 |
|
|
} |
1597 |
|
|
} |
1598 |
|
|
$value; |
1599 |
|
|
} |
1600 |
|
|
} |
1601 |
|
|
|
1602 |
|
|
sub get_level_description ($%) { |
1603 |
|
|
my ($node, %opt) = @_; |
1604 |
|
|
my @l = @{$node->get_attribute_value ('SpecLevel', default => [], |
1605 |
|
|
as_array => 1)}; |
1606 |
|
|
unless (@l) { |
1607 |
|
|
my $min = $opt{level}->[0] || 1; |
1608 |
|
|
for ($min..$MAX_DOM_LEVEL) { |
1609 |
|
|
if ($Info->{Condition}->{'DOM' . $_}) { |
1610 |
|
|
unshift @l, $_; |
1611 |
|
|
last; |
1612 |
|
|
} |
1613 |
|
|
} |
1614 |
|
|
} |
1615 |
|
|
return q<> unless @l; |
1616 |
|
|
@l = sort {$a <=> $b} @l; |
1617 |
|
|
@{$opt{level}} = @l; |
1618 |
|
|
my $r = q<introduced in DOM Level > . (0 + shift @l); |
1619 |
|
|
if (@l > 1) { |
1620 |
|
|
my $s = 0 + pop @l; |
1621 |
|
|
$r .= q< and modified in DOM Levels > . join ', ', @l; |
1622 |
|
|
$r .= qq< and $s>; |
1623 |
|
|
} elsif (@l == 1) { |
1624 |
|
|
$r .= q< and modified in DOM Level > . (0 + $l[0]); |
1625 |
|
|
} |
1626 |
|
|
$r; |
1627 |
|
|
} # get_level_description |
1628 |
|
|
|
1629 |
|
|
sub get_alternate_description ($;%) { |
1630 |
|
|
my ($node, %opt) = @_; |
1631 |
|
|
my @desc; |
1632 |
|
|
$opt{if} ||= 'interface'; |
1633 |
|
|
$opt{method} ||= $node->local_name =~ /Attr/ ? 'attribute' : 'method'; |
1634 |
|
|
|
1635 |
|
|
## XML Namespace unaware alternate |
1636 |
|
|
## (This method is namespace aware.) |
1637 |
|
|
my $ns = $node->get_attribute_value ('NoNSVersion', as_array => 1, |
1638 |
|
|
default => undef); |
1639 |
|
|
if (defined $ns) { |
1640 |
|
|
my $a = ''; |
1641 |
|
|
if (@$ns) { |
1642 |
|
|
$a = english_list |
1643 |
|
|
[map { |
1644 |
|
|
if (/^(?:[AM]:)?([^.]+)\.([^.]+)$/) { |
1645 |
|
|
pod_code ($2) . ' on the interface '. |
1646 |
|
|
type_label (type_expanded_uri ($1), is_pod => 1) |
1647 |
|
|
} else { |
1648 |
|
|
pod_code ($_) |
1649 |
|
|
} |
1650 |
|
|
} @$ns], connector => 'and/or'; |
1651 |
|
|
$a = qq<DOM applications dealing with documents that do >. |
1652 |
|
|
qq<not use XML Namespaces should use $a instead.>; |
1653 |
|
|
} |
1654 |
|
|
push @desc, pod_para |
1655 |
|
|
qq<This $opt{method} is namespace-aware. Mixing >. |
1656 |
|
|
qq<namespace-aware and -unaware methods can lead >. |
1657 |
|
|
qq<to unpredictable result. $a>; |
1658 |
|
|
} |
1659 |
|
|
|
1660 |
|
|
## XML Namespace aware alternate |
1661 |
|
|
## (This method is namespace unaware.) |
1662 |
|
|
$ns = $node->get_attribute_value ('NSVersion', as_array => 1, |
1663 |
|
|
default => undef); |
1664 |
|
|
if (defined $ns) { |
1665 |
|
|
my $a = ''; |
1666 |
|
|
if (@$ns) { |
1667 |
|
|
$a = english_list |
1668 |
|
|
[map { |
1669 |
|
|
if (/^(?:[AM]:)?([^.]+)\.([^.]+)$/) { |
1670 |
|
|
pod_code ($2) . ' on the interface '. |
1671 |
|
|
type_label (type_expanded_uri ($1), is_pod => 1) |
1672 |
|
|
} else { |
1673 |
|
|
pod_code ($_) |
1674 |
|
|
} |
1675 |
|
|
} @$ns]; |
1676 |
|
|
$a = qq<DOM applications dealing with documents that do >. |
1677 |
|
|
qq<use XML Namespaces should use $a instead.>; |
1678 |
|
|
} |
1679 |
|
|
push @desc, pod_para |
1680 |
|
|
qq<This $opt{method} is namespace ignorant. Mixing >. |
1681 |
|
|
qq<namespace-aware and -unaware methods can lead >. |
1682 |
|
|
qq<to unpredictable result. $a>; |
1683 |
|
|
} |
1684 |
|
|
|
1685 |
|
|
@desc; |
1686 |
|
|
} # get_alternate_description |
1687 |
|
|
|
1688 |
|
|
sub get_redef_description ($;%) { |
1689 |
|
|
my ($node, %opt) = @_; |
1690 |
|
|
my @desc; |
1691 |
|
|
$opt{if} ||= 'interface'; |
1692 |
|
|
$opt{method} ||= 'method'; |
1693 |
|
|
if ($node->local_name eq 'ReMethod' or |
1694 |
|
|
$node->local_name eq 'ReAttr') { |
1695 |
|
|
my $redef = $node->get_attribute_value ('Redefine'); |
1696 |
|
|
push @desc, pod_para qq<This $opt{method} is defined by the >. |
1697 |
|
|
($redef ? qq<$opt{if} > . type_label |
1698 |
|
|
(type_expanded_uri ($redef), |
1699 |
|
|
is_pod => 1) |
1700 |
|
|
: qq<super-$opt{if} of this $opt{if}>). |
1701 |
|
|
q< but that definition has been overridden here.>; |
1702 |
|
|
} |
1703 |
|
|
if ($node->get_attribute_value ('IsAbstract', default => 0)) { |
1704 |
|
|
push @desc, pod_para (qq<This $opt{method} is defined abstractly; >. |
1705 |
wakaba |
1.3 |
qq<it must be overridden by the concrete >. |
1706 |
|
|
qq<implementation. >); |
1707 |
wakaba |
1.1 |
} |
1708 |
|
|
my @redefBy; |
1709 |
|
|
for (@{$node->child_nodes}) { |
1710 |
|
|
next unless $_->node_type eq '#element' and |
1711 |
|
|
$_->local_name eq 'RedefinedBy'; |
1712 |
|
|
push @redefBy, type_label (type_expanded_uri ($_->value), is_pod => 1); |
1713 |
|
|
} |
1714 |
|
|
if (@redefBy) { |
1715 |
|
|
push @desc, pod_para qq<This $opt{method} is redefined by the >. |
1716 |
|
|
qq<implementation of the sub-$opt{if}>. |
1717 |
|
|
(@redefBy > 1 ? 's ' : ' '). |
1718 |
|
|
english_list (\@redefBy, connector => 'and').'.'; |
1719 |
|
|
} |
1720 |
|
|
@desc; |
1721 |
|
|
} # get_redef_description; |
1722 |
|
|
|
1723 |
|
|
sub get_isa_description ($;%) { |
1724 |
|
|
my ($node, %opt) = @_; |
1725 |
|
|
$opt{if} ||= $node->get_attribute_value ('IsAbstract', default => 0) |
1726 |
|
|
? 'interface' : 'class'; |
1727 |
|
|
my @desc; |
1728 |
|
|
my @isa; |
1729 |
|
|
my @impl; |
1730 |
|
|
for (@{$node->child_nodes}) { |
1731 |
|
|
next unless $_->node_type eq '#element'; |
1732 |
|
|
if ($_->local_name eq 'ISA') { |
1733 |
|
|
my $v = $_->value; |
1734 |
|
|
if (type_expanded_uri $_->get_attribute_value ('Type', |
1735 |
|
|
default => 'DOMMain:any') eq |
1736 |
|
|
ExpandedURI q<lang:Perl>) { |
1737 |
|
|
push @isa, pod_link (module => $v); |
1738 |
|
|
} else { |
1739 |
|
|
$v =~ s/::[^:]*$//g; |
1740 |
|
|
push @isa, type_label (type_expanded_uri ($v), is_pod => 1); |
1741 |
|
|
} |
1742 |
|
|
} elsif ($_->local_name eq 'Implement') { |
1743 |
|
|
my $v = $_->value; |
1744 |
|
|
$v =~ s/::[^:]*$//g; |
1745 |
|
|
push @impl, type_label (type_expanded_uri ($v), is_pod => 1); |
1746 |
|
|
} |
1747 |
|
|
} |
1748 |
|
|
if (@isa and @impl) { |
1749 |
|
|
push @desc, pod_para (qq<This $opt{if} inherits >. |
1750 |
|
|
english_list (\@isa, connector => 'and'). |
1751 |
|
|
qq< and implements >. |
1752 |
|
|
(@impl>1?q<interfaces >:q<the interface >). |
1753 |
|
|
english_list (\@impl, connector => 'and').q<.>); |
1754 |
|
|
} elsif (@isa) { |
1755 |
|
|
push @desc, pod_para (qq<This $opt{if} inherits >. |
1756 |
|
|
english_list (\@isa, connector => 'and').q<.>); |
1757 |
|
|
} elsif (@impl) { |
1758 |
|
|
push @desc, pod_para (qq<This $opt{if} implements >. |
1759 |
|
|
(@impl>1?q<interfaces >:q<the interface >). |
1760 |
|
|
english_list (\@impl, connector => 'and').q<.>); |
1761 |
|
|
} |
1762 |
|
|
@desc; |
1763 |
|
|
} # get_isa_description |
1764 |
|
|
|
1765 |
|
|
sub get_incase_label ($;%) { |
1766 |
|
|
my ($node, %opt) = @_; |
1767 |
|
|
my $label = $node->get_attribute_value ('Label', default => ''); |
1768 |
|
|
unless (length $label) { |
1769 |
|
|
$label = $node->get_attribute ('Value'); |
1770 |
|
|
my $type = type_normalize |
1771 |
|
|
type_expanded_uri |
1772 |
|
|
($node->get_attribute_value ('Type') || |
1773 |
|
|
$node->parent_node->get_attribute_value |
1774 |
|
|
('Type', |
1775 |
|
|
default => q<DOMMain:any>)); |
1776 |
|
|
if ($label) { |
1777 |
|
|
if ($label->get_attribute_value ('is-null', default => 0)) { |
1778 |
|
|
$label = 'null'; |
1779 |
|
|
} else { |
1780 |
|
|
if (not defined $label->value) { |
1781 |
|
|
valid_err q<Value is null>, node => $node; |
1782 |
|
|
} |
1783 |
|
|
if (type_isa $type, ExpandedURI q<DOMMain:DOMString>) { |
1784 |
|
|
$label = perl_literal $label->value; |
1785 |
|
|
} else { |
1786 |
|
|
$label = $label->value; |
1787 |
|
|
} |
1788 |
|
|
} |
1789 |
|
|
$label = $opt{is_pod} ? pod_code $label : $label; |
1790 |
|
|
} else { |
1791 |
|
|
$label = type_label $type, is_pod => $opt{is_pod}; |
1792 |
|
|
} |
1793 |
|
|
} else { |
1794 |
|
|
$label = get_description $node, name => 'Label', is_inline => 1; |
1795 |
|
|
} |
1796 |
|
|
$label; |
1797 |
|
|
} |
1798 |
|
|
|
1799 |
|
|
sub get_value_literal ($%) { |
1800 |
|
|
my ($node, %opt) = @_; |
1801 |
|
|
my $value = get_perl_definition_node $node, %opt; |
1802 |
|
|
my $type = type_normalize type_expanded_uri |
1803 |
|
|
$node->get_attribute_value ($opt{type_name} || 'Type', |
1804 |
|
|
default => q<DOMMain:any>); |
1805 |
|
|
my $r; |
1806 |
|
|
if ($type eq ExpandedURI q<DOMMain:boolean>) { |
1807 |
|
|
if ($value) { |
1808 |
|
|
$r = ($value->value and $value->value eq 'true') ? 1 : 0; |
1809 |
|
|
} else { |
1810 |
|
|
$r = $opt{default} ? 1 : 0; |
1811 |
|
|
} |
1812 |
|
|
} elsif ($type eq ExpandedURI q<DOMMain:unsigned-long> or |
1813 |
|
|
$type eq ExpandedURI q<DOMMain:unsigned-long-long> or |
1814 |
|
|
$type eq ExpandedURI q<DOMMain:long> or |
1815 |
|
|
$type eq ExpandedURI q<DOMMain:float> or |
1816 |
|
|
$type eq ExpandedURI q<DOMMain:unsigned-short>) { |
1817 |
|
|
if ($value) { |
1818 |
|
|
$r = $value->value; |
1819 |
|
|
} else { |
1820 |
|
|
$r = defined $opt{default} ? $opt{default} : 0; |
1821 |
|
|
} |
1822 |
|
|
} elsif (type_isa $type, ExpandedURI q<DOMMain:DOMString>) { |
1823 |
|
|
if ($value) { |
1824 |
|
|
if ($value->get_attribute_value ('is-null', default => 0)) { |
1825 |
|
|
$r = 'undef'; |
1826 |
|
|
} else { |
1827 |
|
|
$r = perl_literal $value->value; |
1828 |
|
|
} |
1829 |
|
|
} else { |
1830 |
|
|
if (exists $opt{default}) { |
1831 |
|
|
$r = defined $opt{default} ? perl_literal $opt{default} : 'undef'; |
1832 |
|
|
} else { |
1833 |
|
|
$r = perl_literal ''; |
1834 |
|
|
} |
1835 |
|
|
} |
1836 |
|
|
} elsif ($type eq ExpandedURI q<Perl:ARRAY>) { |
1837 |
|
|
if ($value) { |
1838 |
|
|
$r = perl_literal $value->value (as_array => 1); |
1839 |
|
|
} else { |
1840 |
|
|
$r = perl_literal (defined $opt{default} ? $opt{default} : []); |
1841 |
|
|
} |
1842 |
|
|
} elsif ($type eq ExpandedURI q<Perl:HASH>) { |
1843 |
|
|
if ($value) { |
1844 |
|
|
$r = perl_literal $value->value; |
1845 |
|
|
} else { |
1846 |
|
|
$r = perl_literal (defined $opt{default} ? $opt{default} : {}); |
1847 |
|
|
} |
1848 |
|
|
} else { |
1849 |
|
|
if ($value) { |
1850 |
|
|
if ($value->get_attribute_value ('is-null', default => 0)) { |
1851 |
|
|
$r = 'undef'; |
1852 |
|
|
} else { |
1853 |
|
|
$r = perl_literal $value->value; |
1854 |
|
|
} |
1855 |
|
|
} else { |
1856 |
|
|
if (exists $opt{default}) { |
1857 |
|
|
$r = defined $opt{default} ? perl_literal $opt{default} : 'undef'; |
1858 |
|
|
} else { |
1859 |
|
|
$r = 'undef'; |
1860 |
|
|
} |
1861 |
|
|
} |
1862 |
|
|
} |
1863 |
|
|
$r; |
1864 |
|
|
} |
1865 |
|
|
|
1866 |
|
|
sub get_internal_code ($$;%) { |
1867 |
|
|
my ($node, $name, %opt) = @_; |
1868 |
|
|
$node = $node->parent_node; |
1869 |
|
|
my $m; |
1870 |
|
|
my $def; |
1871 |
|
|
if ($m = $node->get_element_by (sub { |
1872 |
|
|
my ($me, $you) = @_; |
1873 |
|
|
$you->node_type eq '#element' and |
1874 |
|
|
($you->local_name eq 'Method' or |
1875 |
|
|
$you->local_name eq 'ReMethod') and |
1876 |
|
|
$you->get_attribute_value ('Name') eq $name |
1877 |
|
|
})) { |
1878 |
|
|
$def = $m->get_attribute ('Return'); |
1879 |
|
|
$def = (get_perl_definition_node $def, name => 'IntDef', use_dis => 1 or |
1880 |
|
|
get_perl_definition_node $def, name => 'Def', use_dis => 1) if $def; |
1881 |
|
|
} elsif ($m = $node->get_element_by (sub { |
1882 |
|
|
my ($me, $you) = @_; |
1883 |
|
|
$you->node_type eq '#element' and |
1884 |
|
|
($you->local_name eq 'Attr' or |
1885 |
|
|
$you->local_name eq 'ReAttr') and |
1886 |
|
|
$you->get_attribute_value ('Name') eq $name |
1887 |
|
|
})) { |
1888 |
|
|
$def = $m->get_attribute ('Get'); |
1889 |
|
|
$def = (get_perl_definition_node $def, name => 'IntDef', use_dis => 1 or |
1890 |
|
|
get_perl_definition_node $def, name => 'Def', use_dis => 1) if $def; |
1891 |
|
|
} elsif ($m = $node->get_element_by (sub { |
1892 |
|
|
my ($me, $you) = @_; |
1893 |
|
|
$you->node_type eq '#element' and |
1894 |
|
|
$you->local_name eq 'IntMethod' and |
1895 |
|
|
$you->get_attribute_value ('Name') eq $name |
1896 |
|
|
})) { |
1897 |
|
|
$def = $m->get_attribute ('Return'); |
1898 |
|
|
$def = get_perl_definition_node $def, name => 'Def', use_dis => 1 if $def; |
1899 |
|
|
} elsif ($m = $node->get_element_by (sub { |
1900 |
|
|
my ($me, $you) = @_; |
1901 |
|
|
$you->node_type eq '#element' and |
1902 |
|
|
$you->local_name eq 'IntAttr' and |
1903 |
|
|
$you->get_attribute_value ('Name') eq $name |
1904 |
|
|
})) { |
1905 |
|
|
$def = $m->get_attribute ('Get'); |
1906 |
|
|
$def = get_perl_definition_node $def, name => 'Def', use_dis => 1 if $def; |
1907 |
|
|
} |
1908 |
|
|
if ($def) { |
1909 |
|
|
if (type_expanded_uri ($def->get_attribute_value ('Type', default => '')) |
1910 |
|
|
eq ExpandedURI q<lang:dis>) { |
1911 |
|
|
return dis2perl $def; |
1912 |
|
|
} else { |
1913 |
|
|
return perl_code $def->value; |
1914 |
|
|
} |
1915 |
|
|
} else { |
1916 |
|
|
valid_warn qq<Internal method "$name" not defined>; |
1917 |
|
|
is_implemented (if => $Status->{IF}, method => $name, set => 0); |
1918 |
|
|
$Status->{is_implemented} = 0; |
1919 |
|
|
return perl_statement perl_exception |
1920 |
|
|
level => 'EXCEPTION', |
1921 |
|
|
class => 'DOMException', |
1922 |
wakaba |
1.2 |
type => 'NOT_SUPPORTED_ERR', |
1923 |
|
|
subtype_uri |
1924 |
|
|
=> ExpandedURI q<MDOM_EXCEPTION:MDOM_IMPL_METHOD_NOT_IMPLEMENTED>, |
1925 |
wakaba |
1.1 |
param => { |
1926 |
|
|
ExpandedURI q<MDOM_EXCEPTION:if> => $Status->{IF}, |
1927 |
|
|
ExpandedURI q<MDOM_EXCEPTION:method> => $name, |
1928 |
|
|
}; |
1929 |
|
|
} |
1930 |
|
|
} # get_internal_code |
1931 |
|
|
|
1932 |
|
|
sub register_namespace_declaration ($) { |
1933 |
|
|
my $node = shift; |
1934 |
|
|
for (@{$node->child_nodes}) { |
1935 |
|
|
if ($_->node_type eq '#element' and |
1936 |
|
|
$_->local_name eq 'Namespace') { |
1937 |
|
|
for (@{$_->child_nodes}) { |
1938 |
|
|
$Info->{Namespace}->{$_->local_name} = $_->value; |
1939 |
|
|
} |
1940 |
|
|
} |
1941 |
|
|
} |
1942 |
|
|
} |
1943 |
|
|
|
1944 |
|
|
{ |
1945 |
|
|
my $nest = 0; |
1946 |
|
|
sub is_implemented (%); |
1947 |
|
|
sub is_implemented (%) { |
1948 |
|
|
my (%opt) = @_; |
1949 |
|
|
my $r = 0; |
1950 |
|
|
$nest++ == 100 and valid_err q<Condition loop detected>; |
1951 |
|
|
my $member = ($Info->{is_implemented}->{$opt{if}}->{$opt{method} || |
1952 |
|
|
$opt{attr} . '.' . $opt{on}} |
1953 |
|
|
||= {}); |
1954 |
|
|
if (exists $opt{set}) { |
1955 |
|
|
$r = ($member->{$opt{condition} || ''} = $opt{set}); |
1956 |
|
|
} else { |
1957 |
|
|
if (defined $member->{$opt{condition} || ''}) { |
1958 |
|
|
$r = $member->{$opt{condition} || ''}; |
1959 |
|
|
} else { |
1960 |
|
|
for (@{$Info->{Condition}->{$opt{condition} || ''}->{ISA} || []}) { |
1961 |
|
|
if (is_implemented (%opt, condition => $_)) { |
1962 |
|
|
$r = 1; |
1963 |
|
|
last; |
1964 |
|
|
} |
1965 |
|
|
} |
1966 |
|
|
} |
1967 |
|
|
} |
1968 |
|
|
$nest--; |
1969 |
|
|
$r; |
1970 |
|
|
} |
1971 |
|
|
sub is_all_implemented (%); |
1972 |
|
|
sub is_all_implemented (%) { |
1973 |
|
|
my (%opt) = @_; |
1974 |
|
|
$nest++ == 100 and valid_err q<Condition loop detected>; |
1975 |
|
|
$opt{not_implemented} ||= []; |
1976 |
|
|
IF: for my $if (keys %{$Info->{is_implemented}}) { |
1977 |
|
|
for my $mem (keys %{$Info->{is_implemented}->{$if}}) { |
1978 |
|
|
## Note: In fact, this checks whether the method is NOT implemented |
1979 |
|
|
## rather than the method IS implemented. |
1980 |
|
|
if (exists $Info->{is_implemented}->{$if}->{$mem}->{$opt{condition}} and |
1981 |
|
|
not $Info->{is_implemented}->{$if}->{$mem}->{$opt{condition}}) { |
1982 |
|
|
@{$opt{not_implemented}} = ($if, $mem, $opt{condition} || ''); |
1983 |
|
|
last IF; |
1984 |
|
|
} |
1985 |
|
|
} |
1986 |
|
|
} |
1987 |
|
|
if (not @{$opt{not_implemented}}) { |
1988 |
|
|
for (@{$Info->{Condition}->{$opt{condition} || ''}->{ISA} || []}) { |
1989 |
|
|
if (not is_all_implemented (%opt, condition => $_)) { |
1990 |
|
|
last; |
1991 |
|
|
} |
1992 |
|
|
} |
1993 |
|
|
} |
1994 |
|
|
@{$opt{not_implemented}} ? 0 : 1; |
1995 |
|
|
}} |
1996 |
|
|
|
1997 |
|
|
sub condition_match ($%) { |
1998 |
|
|
my ($node, %opt) = @_; |
1999 |
|
|
my $conds = $node->get_attribute_value ('Condition', default => [], |
2000 |
|
|
as_array => 1); |
2001 |
|
|
my $level = $node->get_attribute_value |
2002 |
|
|
('Level', |
2003 |
|
|
default_list => @$conds ? [] |
2004 |
|
|
: ($opt{level_default} || []), |
2005 |
|
|
as_array => 1); |
2006 |
|
|
for (@$conds) { |
2007 |
|
|
unless ($Info->{Condition}->{$_}) { |
2008 |
|
|
valid_err qq<Condition "$_" not defined>; |
2009 |
|
|
} |
2010 |
|
|
} |
2011 |
|
|
for (@$level) { |
2012 |
|
|
unless ($Info->{Condition}->{"DOM".$_}) { |
2013 |
|
|
valid_err qq<Condition "DOM$_" not defined>; |
2014 |
|
|
} |
2015 |
|
|
} |
2016 |
|
|
if (not $opt{condition}) { |
2017 |
|
|
if (@$conds == 0 and @$level == 0) { |
2018 |
|
|
return 1; |
2019 |
|
|
} elsif (array_contains $conds, '$normal') { |
2020 |
|
|
return 1; |
2021 |
|
|
} elsif ($opt{ge} and not @$conds) { |
2022 |
|
|
return 1; |
2023 |
|
|
} elsif ($opt{any_unless_condition}) { |
2024 |
|
|
return 1; |
2025 |
|
|
} else { |
2026 |
|
|
return 0; |
2027 |
|
|
} |
2028 |
|
|
} else { |
2029 |
|
|
if (array_contains $conds, $opt{condition}) { |
2030 |
|
|
return 1; |
2031 |
|
|
} elsif ($opt{condition} =~ /^DOM(\d+)$/) { |
2032 |
|
|
if ($opt{ge}) { |
2033 |
|
|
for (my $i = $1; $i; $i--) { |
2034 |
|
|
if (array_contains $level, $i) { |
2035 |
|
|
return 1; |
2036 |
|
|
} |
2037 |
|
|
} |
2038 |
|
|
} else { |
2039 |
|
|
if ($1 and array_contains $level, $1) { |
2040 |
|
|
return 1; |
2041 |
|
|
} |
2042 |
|
|
} |
2043 |
|
|
} |
2044 |
|
|
## 'default_any': Match to 'any' condition (no condition specified) |
2045 |
|
|
if ($opt{default_any} and @$conds == 0 and @$level == 0) { |
2046 |
|
|
return 1; |
2047 |
|
|
} |
2048 |
|
|
return 0; |
2049 |
|
|
} |
2050 |
|
|
} |
2051 |
|
|
|
2052 |
|
|
=head1 SOURCE FORMAT |
2053 |
|
|
|
2054 |
|
|
"Dis" (DOM implementation source) file is written in |
2055 |
|
|
SuikaWikiConfig/2.0 text format. |
2056 |
|
|
|
2057 |
|
|
=head2 IF element |
2058 |
|
|
|
2059 |
|
|
C<IF> element defines a DOM interface with its descriptions |
2060 |
|
|
and implementations. |
2061 |
|
|
|
2062 |
|
|
Children elements: |
2063 |
|
|
|
2064 |
|
|
=over 4 |
2065 |
|
|
|
2066 |
|
|
=item IF/Name = name (1 - 1) |
2067 |
|
|
|
2068 |
|
|
Interface name. It should be taken from DOM specification. |
2069 |
|
|
|
2070 |
|
|
=item IF/Description = text (0 - infinite) |
2071 |
|
|
|
2072 |
|
|
Description for the interface. |
2073 |
|
|
|
2074 |
|
|
=item IF/ISA[list] = list of names (0 - 1) |
2075 |
|
|
|
2076 |
|
|
Names of interfaces that this interface inherits. |
2077 |
|
|
|
2078 |
|
|
=item IF/Method, IF/IntMethod, IF/ReMethod |
2079 |
|
|
|
2080 |
|
|
Method definition. |
2081 |
|
|
|
2082 |
|
|
=item IF/Attr, IF/IntAttr, IF/ReAttr |
2083 |
|
|
|
2084 |
|
|
Attribute definition. |
2085 |
|
|
|
2086 |
|
|
=item IF/ConstGroup |
2087 |
|
|
|
2088 |
|
|
Constant value group definition. |
2089 |
|
|
|
2090 |
|
|
=item IF/Const |
2091 |
|
|
|
2092 |
|
|
Constant value definition. |
2093 |
|
|
|
2094 |
|
|
=back |
2095 |
|
|
|
2096 |
|
|
=cut |
2097 |
|
|
|
2098 |
|
|
sub if2perl ($) { |
2099 |
|
|
my $node = shift; |
2100 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
2101 |
|
|
my $pack_name = perl_package_name |
2102 |
|
|
name => my $if_name |
2103 |
|
|
= perl_name $node->get_attribute_value ('Name'), |
2104 |
|
|
ucfirst => 1; |
2105 |
|
|
my $if_pack_name = perl_package_name if => $if_name; |
2106 |
|
|
my $iif_pack_name = perl_package_name iif => $if_name; |
2107 |
|
|
local $Status->{IF} = $if_name; |
2108 |
|
|
local $Status->{if} = {}; ## Temporary data |
2109 |
|
|
local $Info->{Namespace} = {%{$Info->{Namespace}}}; |
2110 |
|
|
local $Info->{Require_perl_package} = {%{$Info->{Require_perl_package}}}; |
2111 |
|
|
local $Info->{Require_perl_package_use} = {}; |
2112 |
|
|
local $Status->{is_implemented} = 1; |
2113 |
|
|
my $is_abs = $node->get_attribute ('IsAbstract', default => 0); |
2114 |
|
|
my $is_fin = $node->get_attribute ('IsFinal', default => 0); |
2115 |
|
|
$is_fin = -1 if $is_abs; # 1=no subclass, 0=free, -1=must be subclass |
2116 |
|
|
my $impl_by_app = $node->get_attribute ('ImplByApp', default => 0); |
2117 |
|
|
|
2118 |
|
|
my @level; |
2119 |
|
|
my $mod = get_level_description $node, level => \@level; |
2120 |
|
|
|
2121 |
|
|
push my @desc, |
2122 |
|
|
pod_head ($Status->{depth}, 'Interface ' . pod_code ($if_name). |
2123 |
|
|
($is_abs?'':', Class '.pod_code ($pack_name))); |
2124 |
|
|
|
2125 |
|
|
push @desc, pod_paras (get_description ($node)); |
2126 |
|
|
push @desc, pod_para ('This interface is ' . $mod . q<.>) if $mod; |
2127 |
|
|
|
2128 |
|
|
if ($impl_by_app) { |
2129 |
|
|
push @desc, pod_para ('This interface is intended to be implemented '. |
2130 |
|
|
'by DOM applications. To implement this '. |
2131 |
|
|
'interface, put the statement '), |
2132 |
wakaba |
1.3 |
pod_pre ('push our @ISA, q<'.($is_abs?$if_pack_name:$pack_name). |
2133 |
|
|
'>;'), |
2134 |
wakaba |
1.1 |
pod_para ('on your package and define methods and '. |
2135 |
|
|
'attributes.'); |
2136 |
|
|
} |
2137 |
|
|
|
2138 |
|
|
push @desc, get_isa_description ($node); |
2139 |
|
|
|
2140 |
|
|
my $result = pod_block @desc; |
2141 |
|
|
|
2142 |
|
|
my $has_role = $node->get_attribute ('Role'); |
2143 |
|
|
|
2144 |
|
|
for my $condition ((sort keys %{$Info->{Condition}}), '') { |
2145 |
|
|
if ($condition =~ /^DOM(\d+)$/) { |
2146 |
|
|
next if @level and $level[0] > $1; |
2147 |
|
|
} |
2148 |
|
|
local $Status->{Operator} = {}; |
2149 |
|
|
local $Status->{condition} = $condition; |
2150 |
|
|
my $cond_if_pack_name = perl_package_name if => $if_name, |
2151 |
|
|
condition => $condition; |
2152 |
|
|
my $cond_iif_pack_name = perl_package_name iif => $if_name, |
2153 |
|
|
condition => $condition; |
2154 |
|
|
my $cond_pack_name = perl_package_name name => $if_name, |
2155 |
|
|
condition => $condition; |
2156 |
|
|
my $cond_int_pack_name = perl_package_name name => $if_name, |
2157 |
|
|
condition => $condition, |
2158 |
|
|
is_internal => 1; |
2159 |
|
|
my $cond_iint_pack_name = perl_package_name name => $if_name, |
2160 |
|
|
condition => $condition, |
2161 |
|
|
is_internal => 1, |
2162 |
|
|
is_for_inheriting => 1; |
2163 |
|
|
$result .= perl_package full_name => $cond_int_pack_name; |
2164 |
|
|
my @isa; |
2165 |
|
|
for (@{$node->child_nodes}) { |
2166 |
|
|
next unless $_->node_type eq '#element' and |
2167 |
|
|
condition_match $_, condition => $condition, |
2168 |
|
|
default_any => 1, ge => 1; |
2169 |
|
|
if ($_->local_name eq 'ISA') { |
2170 |
|
|
if (type_expanded_uri ($_->get_attribute_value ('Type', |
2171 |
|
|
default => ExpandedURI q<DOMMain:any>)) |
2172 |
|
|
eq ExpandedURI q<lang:Perl>) { |
2173 |
|
|
my $v = $_->value; |
2174 |
|
|
if ($v =~ /[^\w:]|(?<!:):(?!:)/) { |
2175 |
|
|
valid_err q<Invalid package name "$v">, node => $_; |
2176 |
|
|
} |
2177 |
|
|
push @isa, $v; |
2178 |
|
|
} else { |
2179 |
|
|
push @isa, perl_package_name qname_with_condition => $_->value, |
2180 |
|
|
condition => $condition, |
2181 |
|
|
is_internal => 1, |
2182 |
|
|
is_for_inheriting => 1; |
2183 |
|
|
} |
2184 |
|
|
} elsif ($_->local_name eq 'Implement') { |
2185 |
|
|
push @isa, perl_package_name if_qname_with_condition => $_->value, |
2186 |
|
|
condition => $condition; |
2187 |
|
|
} |
2188 |
|
|
} |
2189 |
|
|
push my @isag, perl_package_name (name => 'ManakaiDOMObject') |
2190 |
|
|
unless $if_name eq 'ManakaiDOMObject'; |
2191 |
|
|
my @isaa; |
2192 |
|
|
if ($condition) { |
2193 |
|
|
for (@{$Info->{Condition}->{$condition}->{ISA}}) { |
2194 |
|
|
push @isaa, perl_package_name name => $if_name, |
2195 |
|
|
condition => $_, |
2196 |
|
|
is_internal => 1; |
2197 |
|
|
} |
2198 |
|
|
$result .= perl_inherit [$cond_int_pack_name, @isaa, @isa, @isag] |
2199 |
|
|
=> $cond_pack_name; |
2200 |
|
|
$result .= perl_inherit [@isaa, $cond_iif_pack_name] |
2201 |
|
|
=> $cond_int_pack_name; |
2202 |
|
|
$result .= perl_inherit [$cond_int_pack_name, @isa] |
2203 |
|
|
=> $cond_iint_pack_name; |
2204 |
|
|
$result .= perl_inherit [$cond_if_pack_name, $iif_pack_name] |
2205 |
|
|
=> $cond_iif_pack_name; |
2206 |
|
|
$result .= perl_inherit [$if_pack_name] => $cond_if_pack_name; |
2207 |
|
|
} else { ## No condition specified |
2208 |
|
|
$result .= perl_inherit [$cond_int_pack_name, @isa, @isag] |
2209 |
|
|
=> $cond_pack_name; |
2210 |
|
|
if ($Info->{NormalCondition}) { |
2211 |
|
|
push @isaa, perl_package_name name => $if_name, |
2212 |
|
|
condition => $Info->{NormalCondition}, |
2213 |
|
|
is_internal => 1; |
2214 |
|
|
$result .= perl_inherit [@isaa] |
2215 |
|
|
=> $cond_int_pack_name; |
2216 |
|
|
} else { ## Condition not used |
2217 |
|
|
$result .= perl_inherit [$iif_pack_name] => $cond_int_pack_name; |
2218 |
|
|
} |
2219 |
|
|
$result .= perl_inherit [$cond_int_pack_name, @isa] |
2220 |
|
|
=> $cond_iint_pack_name; |
2221 |
|
|
$result .= perl_inherit [$if_pack_name] => $iif_pack_name; |
2222 |
|
|
} |
2223 |
|
|
for my $pack ($cond_pack_name, $cond_int_pack_name, |
2224 |
|
|
$cond_iif_pack_name, $cond_if_pack_name, |
2225 |
|
|
$cond_iint_pack_name) { |
2226 |
wakaba |
1.4 |
$Status->{def_pack}->{$pack} = 1; |
2227 |
wakaba |
1.1 |
} |
2228 |
|
|
|
2229 |
|
|
my @feature; |
2230 |
|
|
for (@{$node->child_nodes}) { |
2231 |
|
|
my $gt = 0; |
2232 |
|
|
unless (condition_match $_, level_default => \@level, |
2233 |
|
|
condition => $condition) { |
2234 |
|
|
if (condition_match $_, level_default => \@level, |
2235 |
|
|
condition => $condition, ge => 1) { |
2236 |
|
|
$gt = 1; |
2237 |
|
|
} else { |
2238 |
|
|
next; |
2239 |
|
|
} |
2240 |
|
|
} |
2241 |
|
|
|
2242 |
|
|
if ($_->local_name eq 'Method' or |
2243 |
|
|
$_->local_name eq 'IntMethod' or |
2244 |
|
|
$_->local_name eq 'ReMethod') { |
2245 |
|
|
$result .= method2perl ($_, level => \@level, condition => $condition) |
2246 |
|
|
unless $gt; |
2247 |
|
|
} elsif ($_->local_name eq 'Attr' or |
2248 |
|
|
$_->local_name eq 'IntAttr' or |
2249 |
|
|
$_->local_name eq 'ReAttr') { |
2250 |
|
|
$result .= attr2perl ($_, level => \@level, condition => $condition) |
2251 |
|
|
unless $gt; |
2252 |
|
|
} elsif ($_->local_name eq 'ConstGroup') { |
2253 |
|
|
$result .= constgroup2perl ($_, level => \@level, |
2254 |
|
|
condition => $condition, |
2255 |
|
|
without_document => $gt, |
2256 |
|
|
package => $cond_int_pack_name); |
2257 |
|
|
} elsif ($_->local_name eq 'Const') { |
2258 |
|
|
$result .= const2perl ($_, level => \@level, condition => $condition, |
2259 |
|
|
package => $cond_int_pack_name) |
2260 |
|
|
unless $gt; |
2261 |
|
|
} elsif ($_->local_name eq 'Require') { |
2262 |
|
|
$result .= req2perl ($_, level => \@level, condition => $condition); |
2263 |
|
|
} elsif ($_->local_name eq 'Feature') { |
2264 |
|
|
push @feature, $_; |
2265 |
|
|
} elsif ({qw/Name 1 Spec 1 ISA 1 Description 1 Implement 1 |
2266 |
|
|
Level 1 SpecLevel 1 ImplNote 1 Role 1 |
2267 |
|
|
IsAbstract 1 IsFinal 1 ImplByApp 1/}->{$_->local_name}) { |
2268 |
|
|
# |
2269 |
|
|
} else { |
2270 |
|
|
valid_warn qq{Element @{[$_->local_name]} not supported}; |
2271 |
|
|
} |
2272 |
|
|
} |
2273 |
|
|
|
2274 |
|
|
if ($has_role) { |
2275 |
|
|
my $role = type_expanded_uri $has_role->value; |
2276 |
|
|
if ($role eq ExpandedURI q<DOMCore:DOMImplementationSource>) { |
2277 |
|
|
$result .= perl_statement |
2278 |
|
|
q<push @org::w3c::dom::DOMImplementationSourceList, >. |
2279 |
|
|
perl_literal $cond_pack_name; |
2280 |
|
|
} else { |
2281 |
|
|
my $var = q<@{>.perl_var (type => '$', |
2282 |
|
|
local_name => $ManakaiDOMModulePrefix.'::Role'). |
2283 |
|
|
q<{>.perl_literal ($role).q<}}>; |
2284 |
|
|
my %prop; |
2285 |
|
|
if ($has_role->get_attribute ('compat')) { |
2286 |
|
|
$prop{compat} = type_expanded_uri |
2287 |
|
|
$has_role->get_attribute_value ('compat'); |
2288 |
|
|
} else { |
2289 |
|
|
$prop{compat} = ''; |
2290 |
|
|
} |
2291 |
|
|
$result .= perl_statement |
2292 |
|
|
'push '.$var.q<, >. |
2293 |
|
|
perl_list { |
2294 |
|
|
class => $cond_pack_name, |
2295 |
|
|
constructor => 'new', |
2296 |
|
|
%prop, |
2297 |
|
|
}; |
2298 |
|
|
} |
2299 |
|
|
} |
2300 |
|
|
|
2301 |
|
|
if (@feature or $has_role) { |
2302 |
|
|
$result .= '{' . perl_statement 'our $Feature'; |
2303 |
|
|
for (@feature) { |
2304 |
|
|
my $name = $_->get_attribute ('QName'); |
2305 |
|
|
if ($name) { |
2306 |
|
|
$name = type_expanded_uri ($name->value); |
2307 |
|
|
} else { |
2308 |
|
|
$name = $_->get_attribute_value ('Name'); |
2309 |
|
|
} |
2310 |
|
|
$result .= perl_statement '$Feature->{'.perl_literal ($name).'}->{'. |
2311 |
|
|
perl_literal ($_->get_attribute_value ('Version')). |
2312 |
|
|
'} = 1'; |
2313 |
|
|
} |
2314 |
|
|
|
2315 |
|
|
$result .= perl_sub |
2316 |
|
|
name => '___classHasFeature', |
2317 |
|
|
prototype => '$%', |
2318 |
|
|
code => |
2319 |
|
|
perl_statement ('my ($self, %f) = @_'). |
2320 |
|
|
q[ |
2321 |
|
|
for (keys %f) { |
2322 |
|
|
if ($Feature->{$_}) { |
2323 |
|
|
if (defined $f{$_}->{version}) { |
2324 |
|
|
delete $f{$_} |
2325 |
|
|
if $Feature->{$_}->{$f{$_}->{version}}; |
2326 |
|
|
} else { |
2327 |
|
|
delete $f{$_} if keys %{$Feature->{$_}}; |
2328 |
|
|
} |
2329 |
|
|
return 1 if keys (%f) == 0; |
2330 |
|
|
} |
2331 |
|
|
} |
2332 |
|
|
]. |
2333 |
|
|
(@isa + @isaa ? |
2334 |
|
|
q[for (].perl_list (@isa, @isaa).q[) { |
2335 |
|
|
if (my $c = $_->can ('___classHasFeature')) { |
2336 |
|
|
if ($c->($self, %f)) { |
2337 |
|
|
return 1; |
2338 |
|
|
} |
2339 |
|
|
} |
2340 |
|
|
}] : ''). |
2341 |
|
|
(($has_role and $has_role->get_attribute ('compat'))? |
2342 |
|
|
q[ |
2343 |
|
|
my %g; |
2344 |
|
|
for (keys %f) { |
2345 |
|
|
unless ($f{$_}->{plus}) { |
2346 |
|
|
return 0; |
2347 |
|
|
} else { |
2348 |
|
|
$g{$_} = {version => $f{$_}->{version}}; |
2349 |
|
|
} |
2350 |
|
|
} |
2351 |
|
|
for (reverse @{$].$ManakaiDOMModulePrefix.'::Role{'. |
2352 |
|
|
perl_literal (type_expanded_uri |
2353 |
|
|
$has_role->value).'}'.q[||[]}) { |
2354 |
|
|
if ($_->{compat} eq ]. |
2355 |
|
|
perl_literal ($has_role->get_attribute_value |
2356 |
|
|
('compat')).q[) { |
2357 |
|
|
if ($_->{class}->___classHasFeature (%g)) { |
2358 |
|
|
return 1; |
2359 |
|
|
} |
2360 |
|
|
} |
2361 |
|
|
} |
2362 |
|
|
]:''). |
2363 |
|
|
perl_statement (q<return 0>); |
2364 |
|
|
$result .= '}'; |
2365 |
|
|
} |
2366 |
|
|
|
2367 |
|
|
$result .= ops2perl; |
2368 |
|
|
} |
2369 |
|
|
|
2370 |
|
|
$result; |
2371 |
|
|
} # if2perl |
2372 |
|
|
|
2373 |
|
|
=head2 Method, IntMethod and ReMethod elements |
2374 |
|
|
|
2375 |
|
|
C<Method>, C<IntMethod> and C<ReMethod> element defines a method. |
2376 |
|
|
Methods defined by C<Method> are ones as defined in the DOM |
2377 |
|
|
specification. Methods defined by C<IntMethod> are only for |
2378 |
|
|
internal use and usually not defined by the specifications. |
2379 |
|
|
Methods defined by C<ReMethod> do actually not belong |
2380 |
|
|
to this interface but to ancestor interface in the specification |
2381 |
|
|
but overriddenly re-defined for this type of descendant interfaces |
2382 |
|
|
(for example, some methods defined in Node interface of the DOM |
2383 |
|
|
Core Module are re-defined in Element, Attr or other node-type |
2384 |
|
|
interfaces, since those methods work differently by type of |
2385 |
|
|
the node). |
2386 |
|
|
|
2387 |
|
|
Children elements: |
2388 |
|
|
|
2389 |
|
|
=over 4 |
2390 |
|
|
|
2391 |
|
|
=item Name = name (1 - 1) |
2392 |
|
|
|
2393 |
|
|
Method name. It should be taken from DOM specification |
2394 |
|
|
if element type is C<Method> or C<ReMethod>. Method name |
2395 |
|
|
for C<ReMethod> must be used as the name of the C<Method> |
2396 |
|
|
defined in ancestor interface. Method name for C<IntMethod> |
2397 |
|
|
must be different with any other C<Method>, C<IntMethod> |
2398 |
|
|
or C<ReMethod> (including those defined by ancestor interfaces). |
2399 |
|
|
|
2400 |
|
|
=item Description = text (0 - infinite) |
2401 |
|
|
|
2402 |
|
|
Description for the method. |
2403 |
|
|
|
2404 |
|
|
=back |
2405 |
|
|
|
2406 |
|
|
=cut |
2407 |
|
|
|
2408 |
|
|
sub method2perl ($;%) { |
2409 |
|
|
my ($node, %opt) = @_; |
2410 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
2411 |
|
|
my $m_name = perl_name $node->get_attribute_value ('Name'); |
2412 |
|
|
my $level; |
2413 |
|
|
my @level = @{$opt{level} || []}; |
2414 |
|
|
local $Status->{Method} = $m_name; |
2415 |
|
|
local $Status->{is_implemented} = 1; |
2416 |
|
|
my $result = ''; |
2417 |
|
|
if ($node->local_name eq 'IntMethod') { |
2418 |
|
|
$m_name = perl_internal_name $m_name; |
2419 |
|
|
$level = ''; |
2420 |
|
|
} else { |
2421 |
|
|
$level = get_level_description $node, level => \@level; |
2422 |
|
|
} |
2423 |
|
|
|
2424 |
|
|
my @param_list; |
2425 |
|
|
my $param_prototype = '$'; |
2426 |
|
|
my @param_desc; |
2427 |
|
|
my @param_domstring; |
2428 |
|
|
if ($node->get_attribute ('Param')) { |
2429 |
|
|
for (@{$node->child_nodes}) { |
2430 |
|
|
if ($_->local_name eq 'Param') { |
2431 |
|
|
my $name = perl_name $_->get_attribute_value ('Name'); |
2432 |
|
|
my $type = type_expanded_uri $_->get_attribute_value |
2433 |
|
|
('Type', |
2434 |
|
|
default => 'DOMMain:any'); |
2435 |
|
|
push @param_list, '$' . $name; |
2436 |
|
|
push @param_desc, pod_item (pod_code '$' . $name); |
2437 |
|
|
if (type_isa $type, ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>) { |
2438 |
|
|
push @param_domstring, [$name, $type]; |
2439 |
|
|
} |
2440 |
|
|
push my @param_desc_val, |
2441 |
|
|
pod_item (type_label $type, is_pod => 1), |
2442 |
wakaba |
1.3 |
pod_paras get_description $_; |
2443 |
wakaba |
1.1 |
$param_prototype .= '$'; |
2444 |
|
|
for (@{$_->child_nodes}) { |
2445 |
|
|
next unless $_->local_name eq 'InCase'; |
2446 |
|
|
push @param_desc_val, pod_item (get_incase_label $_, is_pod => 1), |
2447 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2448 |
wakaba |
1.1 |
} |
2449 |
|
|
push @param_desc, pod_list 4, @param_desc_val; |
2450 |
|
|
} |
2451 |
|
|
} |
2452 |
|
|
} |
2453 |
|
|
|
2454 |
|
|
my $return = $node->get_attribute ('Return'); |
2455 |
|
|
unless ($return) { |
2456 |
|
|
## NOTE: A method without return value does not have 'Return' |
2457 |
|
|
## before its code is implemented. |
2458 |
|
|
valid_warn q<Required "Return" element not found>, node => $node; |
2459 |
|
|
$return = $node->get_attribute ('Return', make_new_node => 1); |
2460 |
|
|
} |
2461 |
|
|
my $has_return = $return->get_attribute_value ('Type', default => 0) ? 1 : 0; |
2462 |
|
|
push my @desc, |
2463 |
|
|
pod_head ($Status->{depth}, 'Method ' . |
2464 |
|
|
pod_code (($has_return ? '$return = ' : '') . |
2465 |
|
|
'$obj->' . $m_name . |
2466 |
|
|
' (' . join (', ', @param_list) . ')')), |
2467 |
|
|
pod_paras (get_description ($node)), |
2468 |
|
|
$level ? pod_para ('The method ' . pod_code ($m_name) . |
2469 |
|
|
q< has been > . $level . '.') : (); |
2470 |
|
|
|
2471 |
|
|
if (@param_list) { |
2472 |
wakaba |
1.3 |
push @desc, pod_para ('This method has ' . |
2473 |
wakaba |
1.1 |
english_number (@param_list + 0, |
2474 |
|
|
singular => q<parameter>, |
2475 |
|
|
plural => q<parameters>) . ':'), |
2476 |
|
|
pod_list (4, @param_desc); |
2477 |
|
|
} else { |
2478 |
|
|
push @desc, pod_para (q<This method has no parameter.>); |
2479 |
|
|
} |
2480 |
|
|
|
2481 |
|
|
my $is_abs = $node->get_attribute_value ('IsAbstract', default => 0); |
2482 |
|
|
if ($is_abs) { |
2483 |
|
|
unless (get_perl_definition_node $return, |
2484 |
|
|
condition => $opt{condition}, |
2485 |
|
|
level_default => $opt{level_default}, |
2486 |
|
|
use_dis => 1) { |
2487 |
|
|
for ($return->append_new_node (type => '#element', |
2488 |
|
|
local_name => 'Def')) { |
2489 |
|
|
$_->set_attribute ('Type' => ExpandedURI q<lang:dis>); |
2490 |
|
|
$_->set_attribute ('Overridden' => 1); |
2491 |
|
|
} |
2492 |
|
|
} |
2493 |
|
|
} |
2494 |
|
|
|
2495 |
|
|
my @return; |
2496 |
|
|
my @exception; |
2497 |
|
|
my $has_exception = 0; |
2498 |
|
|
my $code_node = get_perl_definition_node $return, |
2499 |
|
|
condition => $opt{condition}, |
2500 |
|
|
level_default => $opt{level_default}, |
2501 |
|
|
use_dis => 1; |
2502 |
|
|
my $int_code_node = get_perl_definition_node $return, name => 'IntDef', |
2503 |
|
|
condition => $opt{condition}, |
2504 |
|
|
level_default => $opt{level_default}, |
2505 |
|
|
use_dis => 1; |
2506 |
|
|
my $code; |
2507 |
|
|
my $int_code; |
2508 |
|
|
for ({code => \$code, code_node => $code_node, |
2509 |
|
|
internal => sub { |
2510 |
|
|
return get_internal_code $node, $_[0] if $_[0]; |
2511 |
|
|
if ($int_code_node) { |
2512 |
|
|
perl_code $int_code_node->value, |
2513 |
|
|
internal => sub { |
2514 |
|
|
$_[0] ? get_internal_code $node, $_[0] : |
2515 |
|
|
valid_err q<Preprocessing macro INT cannot be used here>; |
2516 |
|
|
}; |
2517 |
|
|
} else { |
2518 |
|
|
valid_err "<IF[Name = $Status->{IF}]/Method[Name = $m_name]/" . |
2519 |
|
|
"Return/IntDef> required"; |
2520 |
|
|
} |
2521 |
|
|
}}, |
2522 |
|
|
{code => \$int_code, code_node => $int_code_node, |
2523 |
|
|
internal => sub {$_[0]?get_internal_code $node,$_[0]: |
2524 |
|
|
valid_err q<Preprocessing macro INT cannot be> . |
2525 |
|
|
q<used here>}}) { |
2526 |
|
|
if ($_->{code_node}) { |
2527 |
|
|
my $mcode; |
2528 |
|
|
if (type_expanded_uri ($_->{code_node}->get_attribute_value |
2529 |
|
|
('Type', default => q<DOMMain:any>)) |
2530 |
|
|
eq ExpandedURI q<lang:dis>) { |
2531 |
|
|
$mcode = dis2perl $_->{code_node}; |
2532 |
|
|
} else { |
2533 |
|
|
$mcode = perl_code $_->{code_node}->value, |
2534 |
|
|
internal => $_->{internal}; |
2535 |
|
|
} |
2536 |
|
|
if ($mcode =~ /^\s*$/) { |
2537 |
|
|
${$_->{code}} = ''; |
2538 |
|
|
} else { |
2539 |
|
|
${$_->{code}} = perl_code_source ($mcode, |
2540 |
|
|
path => $_->{code_node}->node_path |
2541 |
|
|
(key => 'Name')); |
2542 |
|
|
} |
2543 |
|
|
} |
2544 |
|
|
} |
2545 |
|
|
if ($code_node) { |
2546 |
|
|
if ($has_return) { |
2547 |
|
|
$code = perl_statement (perl_assign 'my $r' => get_value_literal $return, |
2548 |
|
|
name => 'DefaultValue', |
2549 |
|
|
type_name => 'Type') . |
2550 |
|
|
$code; |
2551 |
|
|
if ($code_node->get_attribute_value ('cast-output', default => 1)) { |
2552 |
|
|
my $type = type_normalize |
2553 |
|
|
type_expanded_uri $return->get_attribute_value |
2554 |
|
|
('Type', |
2555 |
|
|
default => q<DOMMain:any>); |
2556 |
|
|
if (type_isa $type, ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>) { |
2557 |
|
|
$code .= perl_builtin_code $type, |
2558 |
|
|
s => 'r', r => 'r', |
2559 |
|
|
condition => $opt{condition}; |
2560 |
|
|
} |
2561 |
|
|
} |
2562 |
|
|
$code .= perl_statement ('$r'); |
2563 |
|
|
} else { |
2564 |
|
|
$code .= perl_statement ('undef'); |
2565 |
|
|
} |
2566 |
|
|
if ($code_node->get_attribute_value ('auto-argument', default => 1)) { |
2567 |
|
|
if ($code_node->get_attribute_value ('cast-input', default => 1)) { |
2568 |
|
|
for (@param_domstring) { |
2569 |
|
|
$code = perl_builtin_code ($_->[1], |
2570 |
|
|
s => $_->[0], r => $_->[0], |
2571 |
|
|
condition => $opt{condition}) . $code; |
2572 |
|
|
} |
2573 |
|
|
} |
2574 |
|
|
$code = perl_statement (perl_assign 'my (' . |
2575 |
|
|
join (', ', '$self', @param_list) . |
2576 |
|
|
')' => '@_') . |
2577 |
|
|
$code; |
2578 |
|
|
} |
2579 |
|
|
if ($int_code_node) { |
2580 |
|
|
if ($has_return) { |
2581 |
|
|
$int_code = perl_statement (perl_assign 'my $r' => perl_literal '') . |
2582 |
|
|
$int_code . |
2583 |
|
|
perl_statement ('$r'); |
2584 |
|
|
} else { |
2585 |
|
|
$int_code .= perl_statement ('undef'); |
2586 |
|
|
} |
2587 |
|
|
$int_code = perl_statement (perl_assign 'my (' . |
2588 |
|
|
join (', ', '$self', @param_list) . |
2589 |
|
|
')' => '@_') . |
2590 |
|
|
$int_code |
2591 |
|
|
if $int_code_node->get_attribute_value ('auto-argument', default => 1); |
2592 |
|
|
} |
2593 |
|
|
|
2594 |
|
|
if ($has_return) { |
2595 |
|
|
push @return, pod_item (type_label (type_expanded_uri |
2596 |
|
|
($return->get_attribute_value |
2597 |
|
|
('Type', |
2598 |
|
|
default => 'DOMMain:any')), |
2599 |
|
|
is_pod => 1)), |
2600 |
wakaba |
1.3 |
pod_paras (get_description $return); |
2601 |
wakaba |
1.1 |
} |
2602 |
|
|
for (@{$return->child_nodes}) { |
2603 |
|
|
if ($_->local_name eq 'InCase') { |
2604 |
|
|
push @return, pod_item ( get_incase_label $_, is_pod => 1), |
2605 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2606 |
wakaba |
1.1 |
$has_return++; |
2607 |
|
|
} elsif ($_->local_name eq 'Exception') { |
2608 |
|
|
push @exception, pod_item ('Exception: ' . |
2609 |
|
|
(type_label ($_->get_attribute_value |
2610 |
|
|
('Type', |
2611 |
|
|
default => 'DOMMain:any'), |
2612 |
|
|
is_pod => 1)). |
2613 |
|
|
'.' . pod_code $_->get_attribute_value |
2614 |
|
|
('Name', |
2615 |
|
|
default => '<unknown>')), |
2616 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2617 |
wakaba |
1.1 |
my @st; |
2618 |
|
|
for (@{$_->child_nodes}) { |
2619 |
|
|
next unless $_->node_type eq '#element'; |
2620 |
|
|
if ($_->local_name eq 'SubType') { |
2621 |
|
|
push @st, subtype2poditem ($_); |
2622 |
|
|
} elsif ({qw/Name 1 Type 1 |
2623 |
|
|
Description 1 ImplNote 1 |
2624 |
|
|
Condition 1 Level 1 SpecLevel 1/}->{$_->local_name}) { |
2625 |
|
|
# |
2626 |
|
|
} else { |
2627 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
2628 |
|
|
node => $_; |
2629 |
|
|
} |
2630 |
|
|
} |
2631 |
|
|
push @exception, pod_list 4, @st if @st; |
2632 |
|
|
$has_exception++; |
2633 |
|
|
} |
2634 |
|
|
} |
2635 |
|
|
} else { |
2636 |
|
|
$Status->{is_implemented} = 0; |
2637 |
|
|
$int_code = $code |
2638 |
|
|
= perl_statement ('my $self = shift'). |
2639 |
|
|
perl_statement perl_exception |
2640 |
|
|
level => 'EXCEPTION', |
2641 |
|
|
class => 'DOMException', |
2642 |
|
|
type => 'NOT_SUPPORTED_ERR', |
2643 |
wakaba |
1.2 |
subtype_uri |
2644 |
|
|
=> ExpandedURI q<MDOM_EXCEPTION:MDOM_IMPL_METHOD_NOT_IMPLEMENTED>, |
2645 |
wakaba |
1.1 |
param => { |
2646 |
|
|
ExpandedURI q<MDOM_EXCEPTION:if> => $Status->{IF}, |
2647 |
|
|
ExpandedURI q<MDOM_EXCEPTION:method> => $Status->{Method}, |
2648 |
|
|
}; |
2649 |
|
|
@return = (); |
2650 |
|
|
push @exception, pod_item ('Exception: ' . pod_code ('DOMException') . '.' . |
2651 |
|
|
pod_code ('NOT_SUPPORTED_ERR')), |
2652 |
|
|
pod_para ('Call of this method allways result in |
2653 |
|
|
this exception raisen, since this |
2654 |
|
|
method is not implemented yet.'); |
2655 |
|
|
$has_return = 0; |
2656 |
|
|
$has_exception = 1; |
2657 |
|
|
} |
2658 |
|
|
is_implemented if => $Status->{IF}, method => $Status->{Method}, |
2659 |
|
|
condition => $opt{condition}, set => $Status->{is_implemented}; |
2660 |
|
|
if ($has_return or $has_exception) { |
2661 |
|
|
if ($has_return) { |
2662 |
|
|
push @desc, pod_para (q<This method results in > . |
2663 |
|
|
($has_return == 1 ? q<the value:> |
2664 |
|
|
: q<either:>)), |
2665 |
|
|
pod_list 4, pod_item (pod_code q<$return>), |
2666 |
|
|
pod_list (4, @return), |
2667 |
|
|
@exception; |
2668 |
|
|
} elsif ($has_exception) { |
2669 |
|
|
push @desc, pod_para (q<This method does not return any value, |
2670 |
|
|
but it might raise > . |
2671 |
|
|
($has_exception == 1 ? q<an exception:> |
2672 |
|
|
: q<one of exceptions from:>)), |
2673 |
|
|
pod_list 4, @exception; |
2674 |
|
|
} |
2675 |
|
|
} else { |
2676 |
|
|
push @desc, pod_para q<This method does not return any value |
2677 |
|
|
nor does raise any exceptions.>; |
2678 |
|
|
} |
2679 |
|
|
|
2680 |
|
|
push @desc, get_alternate_description $node; |
2681 |
|
|
push @desc, get_redef_description $node; |
2682 |
|
|
|
2683 |
|
|
if ($node->local_name eq 'IntMethod' or |
2684 |
|
|
$Status->{if}->{method_documented}->{$m_name}++) { |
2685 |
|
|
$result .= pod_block pod_comment @desc; |
2686 |
|
|
} else { |
2687 |
|
|
$result .= pod_block @desc; |
2688 |
|
|
} |
2689 |
|
|
|
2690 |
|
|
$result .= perl_sub name => $m_name, |
2691 |
|
|
prototype => $param_prototype, |
2692 |
|
|
code => $code; |
2693 |
|
|
$result .= perl_sub name => perl_internal_name $m_name, |
2694 |
|
|
prototype => $param_prototype, |
2695 |
|
|
code => $int_code |
2696 |
|
|
if $int_code_node; |
2697 |
|
|
|
2698 |
|
|
if (my $op = get_perl_definition_node $node, name => 'Operator') { |
2699 |
|
|
my $value = $op->value; |
2700 |
|
|
valid_err qq{Overloaded operator name not specified}, |
2701 |
|
|
node => $op |
2702 |
|
|
unless defined $value; |
2703 |
|
|
$Status->{Operator}->{$value} = '\\' . perl_var type => '&', |
2704 |
|
|
local_name => $m_name; |
2705 |
|
|
} |
2706 |
|
|
|
2707 |
|
|
$result; |
2708 |
|
|
} # method2perl |
2709 |
|
|
|
2710 |
|
|
sub attr2perl ($;%) { |
2711 |
|
|
my ($node, %opt) = @_; |
2712 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
2713 |
|
|
my $m_name = perl_name $node->get_attribute_value ('Name'); |
2714 |
|
|
my $level; |
2715 |
|
|
my @level = @{$opt{level} || []}; |
2716 |
|
|
local $Status->{Method} = $m_name; |
2717 |
|
|
local $Status->{is_implemented} = 1; |
2718 |
|
|
my $result = ''; |
2719 |
|
|
if ($node->local_name eq 'IntAttr') { |
2720 |
|
|
$m_name = perl_internal_name $m_name; |
2721 |
|
|
$level = ''; |
2722 |
|
|
} else { |
2723 |
|
|
$level = get_level_description $node, level => \@level; |
2724 |
|
|
} |
2725 |
|
|
|
2726 |
|
|
my $return = $node->get_attribute ('Get'); |
2727 |
|
|
unless ($return) { |
2728 |
|
|
valid_err q<Required "Get" element not found>, node => $node; |
2729 |
|
|
} |
2730 |
|
|
my $set = $node->get_attribute ('Set'); |
2731 |
|
|
my $has_set = defined $set ? 1 : 0; |
2732 |
|
|
push my @desc, |
2733 |
|
|
pod_head ($Status->{depth}, 'Attribute ' . |
2734 |
|
|
pod_code ('$obj->' . $m_name)), |
2735 |
|
|
pod_paras (get_description ($node)), |
2736 |
|
|
$level ? pod_para ('The method ' . pod_code ($m_name) . |
2737 |
|
|
q< has been > . $level . '.') : (); |
2738 |
|
|
|
2739 |
|
|
my $is_abs = $node->get_attribute_value ('IsAbstract', default => 0); |
2740 |
|
|
if ($is_abs) { |
2741 |
|
|
unless (get_perl_definition_node $return, |
2742 |
|
|
condition => $opt{condition}, |
2743 |
|
|
level_default => $opt{level_default}, |
2744 |
|
|
use_dis => 1) { |
2745 |
|
|
for ($return->append_new_node (type => '#element', |
2746 |
|
|
local_name => 'Def')) { |
2747 |
|
|
$_->set_attribute ('Type' => ExpandedURI q<lang:dis>); |
2748 |
|
|
$_->set_attribute ('Overridden' => 1); |
2749 |
|
|
} |
2750 |
|
|
} |
2751 |
|
|
} |
2752 |
|
|
|
2753 |
|
|
my $code_node = get_perl_definition_node $return, |
2754 |
|
|
condition => $opt{condition}, |
2755 |
|
|
level_default => $opt{level_default}, |
2756 |
|
|
use_dis => 1; |
2757 |
|
|
my $int_code_node = get_perl_definition_node $return, name => 'IntDef', |
2758 |
|
|
condition => $opt{condition}, |
2759 |
|
|
level_default => $opt{level_default}, |
2760 |
|
|
use_dis => 1; |
2761 |
|
|
my ($set_code_node, $int_set_code_node); |
2762 |
|
|
if ($has_set) { |
2763 |
|
|
if ($is_abs) { |
2764 |
|
|
unless (get_perl_definition_node $set, |
2765 |
|
|
condition => $opt{condition}, |
2766 |
|
|
level_default => $opt{level_default}, |
2767 |
|
|
use_dis => 1) { |
2768 |
|
|
for ($return->append_new_node (type => '#element', |
2769 |
|
|
local_name => 'Def')) { |
2770 |
|
|
$_->set_attribute ('Type' => ExpandedURI q<lang:dis>); |
2771 |
|
|
$_->set_attribute ('Overridden' => 1); |
2772 |
|
|
} |
2773 |
|
|
} |
2774 |
|
|
} |
2775 |
|
|
$set_code_node = get_perl_definition_node $set, |
2776 |
|
|
condition => $opt{condition}, |
2777 |
|
|
level_default => $opt{level_default}, |
2778 |
|
|
use_dis => 1; |
2779 |
|
|
$int_set_code_node = get_perl_definition_node $set, name => 'IntDef', |
2780 |
|
|
condition => $opt{condition}, |
2781 |
|
|
level_default => $opt{level_default}, |
2782 |
|
|
use_dis => 1; |
2783 |
|
|
} |
2784 |
|
|
my $code = ''; |
2785 |
|
|
my $int_code = ''; |
2786 |
|
|
my $set_code = ''; |
2787 |
|
|
my $int_set_code = ''; |
2788 |
|
|
for ({code => \$code, code_node => $code_node, |
2789 |
|
|
internal => sub { |
2790 |
|
|
return get_internal_code $node, $_[0] if $_[0]; |
2791 |
|
|
if ($int_code_node) { |
2792 |
|
|
perl_code $int_code_node->value, |
2793 |
|
|
internal => sub { |
2794 |
|
|
$_[0] ? get_internal_code $node, $_[0] : |
2795 |
|
|
valid_err q<Preprocessing macro INT cannot be used here>; |
2796 |
|
|
}; |
2797 |
|
|
} else { |
2798 |
|
|
valid_err "<IF[Name = $Status->{IF}]/Attr[Name = $m_name]/" . |
2799 |
|
|
"Get/IntDef> required"; |
2800 |
|
|
} |
2801 |
|
|
}}, |
2802 |
|
|
{code => \$int_code, code_node => $int_code_node, |
2803 |
|
|
internal => sub {$_[0]?get_internal_code $node,$_[0]: |
2804 |
|
|
valid_err q<Preprocessing macro INT cannot be> . |
2805 |
|
|
q<used here>}}, |
2806 |
|
|
{code => \$set_code, code_node => $set_code_node, |
2807 |
|
|
internal => sub { |
2808 |
|
|
return get_internal_code $node, $_[0] if $_[0]; |
2809 |
|
|
if ($int_set_code_node) { |
2810 |
|
|
perl_code $int_set_code_node->value, |
2811 |
|
|
internal => sub { |
2812 |
|
|
$_[0] ? get_internal_code $node, $_[0] : |
2813 |
|
|
valid_err q<Preprocessing macro INT cannot be used here>; |
2814 |
|
|
}; |
2815 |
|
|
} else { |
2816 |
|
|
valid_err "<IF[Name = $Status->{IF}]/Attr[Name = $m_name]/" . |
2817 |
|
|
"Set/IntDef> required"; |
2818 |
|
|
} |
2819 |
|
|
}}, |
2820 |
|
|
{code => \$int_set_code, code_node => $int_set_code_node, |
2821 |
|
|
internal => sub {$_[0]?get_internal_code $node,$_[0]: |
2822 |
|
|
valid_err q<Preprocessing macro INT cannot be> . |
2823 |
|
|
q<used here>}}) { |
2824 |
|
|
if ($_->{code_node}) { |
2825 |
|
|
my $mcode; |
2826 |
|
|
if (type_expanded_uri ($_->{code_node}->get_attribute_value |
2827 |
|
|
('Type', default => q<DOMMain:any>)) |
2828 |
|
|
eq ExpandedURI q<lang:dis>) { |
2829 |
|
|
$mcode = dis2perl $_->{code_node}; |
2830 |
|
|
} else { |
2831 |
|
|
$mcode = perl_code $_->{code_node}->value, |
2832 |
|
|
internal => $_->{internal}, |
2833 |
|
|
node => $_->{code_node}; |
2834 |
|
|
} |
2835 |
|
|
if ($mcode =~ /^\s*$/) { |
2836 |
|
|
${$_->{code}} = ''; |
2837 |
|
|
} else { |
2838 |
|
|
${$_->{code}} = perl_code_source ($mcode, |
2839 |
|
|
path => $_->{code_node}->node_path |
2840 |
|
|
(key => 'Name')); |
2841 |
|
|
} |
2842 |
|
|
} |
2843 |
|
|
} |
2844 |
|
|
|
2845 |
|
|
my @return; |
2846 |
|
|
my @return_xcept; |
2847 |
|
|
if ($code_node) { |
2848 |
|
|
is_implemented if => $Status->{IF}, attr => $Status->{Method}, |
2849 |
|
|
condition => $opt{condition}, set => 1, on => 'get'; |
2850 |
|
|
my $co = $code_node->get_attribute_value ('cast-output', |
2851 |
|
|
default => $code eq '' ? 0 : 1); |
2852 |
|
|
if ($code eq '' and not $co) { |
2853 |
|
|
$code = perl_statement get_value_literal $return, |
2854 |
|
|
name => 'DefaultValue', |
2855 |
|
|
type_name => 'Type'; |
2856 |
|
|
} else { |
2857 |
|
|
$code = perl_statement (perl_assign 'my $r' => get_value_literal $return, |
2858 |
|
|
name => 'DefaultValue', |
2859 |
|
|
type_name => 'Type') . |
2860 |
|
|
$code; |
2861 |
|
|
if ($co) { |
2862 |
|
|
my $type = type_normalize |
2863 |
|
|
type_expanded_uri $return->get_attribute_value |
2864 |
|
|
('Type', |
2865 |
|
|
default => q<DOMMain:any>); |
2866 |
|
|
if (type_isa $type, ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>) { |
2867 |
|
|
$code .= perl_builtin_code $type, |
2868 |
|
|
s => 'r', r => 'r', |
2869 |
|
|
condition => $opt{condition}; |
2870 |
|
|
} |
2871 |
|
|
} |
2872 |
|
|
$code .= perl_statement ('$r'); |
2873 |
|
|
} |
2874 |
|
|
$code = get_warning_perl_code ($return) . $code; |
2875 |
|
|
if ($int_code_node) { |
2876 |
|
|
$int_code = perl_statement (perl_assign 'my $r' => perl_literal '') . |
2877 |
|
|
$int_code . |
2878 |
|
|
perl_statement ('$r'); |
2879 |
|
|
$int_code = perl_statement (perl_assign 'my ($self)' => '@_') . $int_code |
2880 |
|
|
if $int_code_node->get_attribute_value ('auto-argument', default => 1); |
2881 |
|
|
} |
2882 |
|
|
|
2883 |
|
|
push @return, pod_item (type_label (type_expanded_uri |
2884 |
|
|
$return->get_attribute_value |
2885 |
|
|
('Type', |
2886 |
|
|
default => 'DOMMain:any'), |
2887 |
|
|
is_pod => 1)), |
2888 |
wakaba |
1.3 |
pod_paras (get_description $return); |
2889 |
wakaba |
1.1 |
for (@{$return->child_nodes}) { |
2890 |
|
|
if ($_->local_name eq 'InCase') { |
2891 |
|
|
push @return, pod_item (get_incase_label $_, is_pod => 1), |
2892 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2893 |
wakaba |
1.1 |
} elsif ($_->local_name eq 'Exception') { |
2894 |
|
|
push @return_xcept, pod_item ('Exception: ' . |
2895 |
|
|
(type_label ($_->get_attribute_value |
2896 |
|
|
('Type', |
2897 |
|
|
default => 'DOMMain:any'), |
2898 |
|
|
is_pod => 1)) . |
2899 |
|
|
'.' . pod_code $_->get_attribute_value |
2900 |
|
|
('Name', |
2901 |
|
|
default => '<unknown>')), |
2902 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2903 |
wakaba |
1.1 |
my @st; |
2904 |
|
|
for (@{$_->child_nodes}) { |
2905 |
|
|
next unless $_->node_type eq '#element'; |
2906 |
|
|
if ($_->local_name eq 'SubType') { |
2907 |
|
|
push @st, subtype2poditem ($_); |
2908 |
|
|
} elsif ({qw/Name 1 Type 1 |
2909 |
|
|
Description 1 ImplNote 1 |
2910 |
|
|
Condition 1 Level 1 SpecLevel 1/}->{$_->local_name}) { |
2911 |
|
|
# |
2912 |
|
|
} else { |
2913 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
2914 |
|
|
node => $_; |
2915 |
|
|
} |
2916 |
|
|
} |
2917 |
|
|
push @return_xcept, pod_list 4, @st if @st; |
2918 |
|
|
} |
2919 |
|
|
} |
2920 |
|
|
} else { |
2921 |
|
|
is_implemented if => $Status->{IF}, attr => $Status->{Method}, |
2922 |
|
|
condition => $opt{condition}, set => 0, on => 'get'; |
2923 |
|
|
$Status->{is_implemented} = 0; |
2924 |
|
|
$int_code = $code |
2925 |
|
|
= perl_statement perl_exception |
2926 |
|
|
level => 'EXCEPTION', |
2927 |
|
|
class => 'DOMException', |
2928 |
|
|
type => 'NOT_SUPPORTED_ERR', |
2929 |
wakaba |
1.2 |
subtype_uri |
2930 |
|
|
=> ExpandedURI q<MDOM_EXCEPTION:MDOM_IMPL_ATTR_NOT_IMPLEMENTED>, |
2931 |
wakaba |
1.1 |
param => { |
2932 |
|
|
ExpandedURI q<MDOM_EXCEPTION:if> => $Status->{IF}, |
2933 |
|
|
ExpandedURI q<MDOM_EXCEPTION:attr> => $Status->{Method}, |
2934 |
|
|
ExpandedURI q<MDOM_EXCEPTION:on> => 'get', |
2935 |
|
|
}; |
2936 |
|
|
@return = (); |
2937 |
|
|
push @return_xcept, |
2938 |
|
|
pod_item ('Exception: ' . pod_code ('DOMException') . '.' . |
2939 |
|
|
pod_code ('NOT_SUPPORTED_ERR')), |
2940 |
|
|
pod_para ('Getting of this attribute allways result in |
2941 |
|
|
this exception raisen, since this |
2942 |
|
|
attribute is not implemented yet.'); |
2943 |
|
|
} |
2944 |
|
|
push @desc, pod_para ('DOM applications can get the value by:'), |
2945 |
|
|
pod_pre (qq{\$return = \$obj->$m_name}), |
2946 |
|
|
pod_list (4, |
2947 |
|
|
@return ? (pod_item pod_code q<$return>, |
2948 |
|
|
pod_list 4, @return): (), |
2949 |
|
|
@return_xcept); |
2950 |
|
|
|
2951 |
|
|
my @set_desc; |
2952 |
|
|
my @set_xcept; |
2953 |
|
|
if ($set_code_node) { |
2954 |
|
|
is_implemented if => $Status->{IF}, attr => $Status->{Method}, |
2955 |
|
|
condition => $opt{condition}, set => 1, on => 'set'; |
2956 |
|
|
if ($set_code_node->get_attribute_value ('cast-input', |
2957 |
|
|
default => $set_code eq '' ? 0 : 1)) { |
2958 |
|
|
my $type = type_normalize |
2959 |
|
|
type_expanded_uri $set->get_attribute_value |
2960 |
|
|
('Type', |
2961 |
|
|
default => q<DOMMain:any>); |
2962 |
|
|
if (type_isa $type, ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>) { |
2963 |
|
|
$set_code = perl_builtin_code ($type, |
2964 |
|
|
s => 'given', r => 'given', |
2965 |
|
|
condition => $opt{condition}) |
2966 |
|
|
. $set_code; |
2967 |
|
|
} |
2968 |
|
|
} |
2969 |
|
|
$set_code = get_warning_perl_code ($set) . $set_code; |
2970 |
|
|
|
2971 |
|
|
push @set_desc, pod_item (type_label (type_expanded_uri |
2972 |
|
|
($set->get_attribute_value |
2973 |
|
|
('Type', |
2974 |
|
|
default => 'DOMMain:any')), |
2975 |
|
|
is_pod => 1)), |
2976 |
wakaba |
1.3 |
pod_paras (get_description $set); |
2977 |
wakaba |
1.1 |
for (@{$set->child_nodes}) { |
2978 |
|
|
if ($_->local_name eq 'InCase') { |
2979 |
|
|
push @set_desc, pod_item (get_incase_label $_, is_pod => 1), |
2980 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2981 |
wakaba |
1.1 |
} elsif ($_->local_name eq 'Exception') { |
2982 |
|
|
push @set_xcept, pod_item ('Exception: ' . |
2983 |
|
|
(type_label ($_->get_attribute_value |
2984 |
|
|
('Type', |
2985 |
|
|
default => 'DOMMain:any'), |
2986 |
|
|
is_pod => 1)) . |
2987 |
|
|
'.' . pod_code $_->get_attribute_value |
2988 |
|
|
('Name', |
2989 |
|
|
default => '<unknown>')), |
2990 |
wakaba |
1.3 |
pod_paras (get_description $_); |
2991 |
wakaba |
1.1 |
my @st; |
2992 |
|
|
for (@{$_->child_nodes}) { |
2993 |
|
|
next unless $_->node_type eq '#element'; |
2994 |
|
|
if ($_->local_name eq 'SubType') { |
2995 |
|
|
push @st, subtype2poditem ($_); |
2996 |
|
|
} elsif ({qw/Name 1 Type 1 |
2997 |
|
|
Description 1 ImplNote 1 |
2998 |
|
|
Condition 1 Level 1 SpecLevel 1/}->{$_->local_name}) { |
2999 |
|
|
# |
3000 |
|
|
} else { |
3001 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
3002 |
|
|
node => $_; |
3003 |
|
|
} |
3004 |
|
|
} |
3005 |
|
|
push @set_xcept, pod_list 4, @st if @st; |
3006 |
|
|
} |
3007 |
|
|
} |
3008 |
|
|
} elsif ($has_set) { |
3009 |
|
|
is_implemented if => $Status->{IF}, attr => $Status->{Method}, |
3010 |
|
|
condition => $opt{condition}, set => 0, on => 'set'; |
3011 |
|
|
$Status->{is_implemented} = 0; |
3012 |
|
|
$int_set_code = $set_code |
3013 |
|
|
= perl_statement perl_exception |
3014 |
|
|
level => 'EXCEPTION', |
3015 |
|
|
class => 'DOMException', |
3016 |
|
|
type => 'NOT_SUPPORTED_ERR', |
3017 |
wakaba |
1.2 |
subtype_uri |
3018 |
|
|
=> ExpandedURI q<MDOM_EXCEPTION:MDOM_IMPL_ATTR_NOT_IMPLEMENTED>, |
3019 |
wakaba |
1.1 |
param => { |
3020 |
|
|
ExpandedURI q<MDOM_EXCEPTION:if> => $Status->{IF}, |
3021 |
|
|
ExpandedURI q<MDOM_EXCEPTION:attr> => $Status->{Method}, |
3022 |
|
|
ExpandedURI q<MDOM_EXCEPTION:on> => 'set', |
3023 |
|
|
}; |
3024 |
|
|
@set_desc = pod_item '(Not implemented yet)'; |
3025 |
|
|
@set_xcept = (); |
3026 |
|
|
push @set_xcept, pod_item ('Exception: ' . pod_code ('DOMException') . '.' . |
3027 |
|
|
pod_code ('NOT_SUPPORTED_ERR')), |
3028 |
|
|
pod_para ('Setting of this attribute allways result in |
3029 |
|
|
this exception raisen, since this |
3030 |
|
|
attribute is not implemented yet.'); |
3031 |
|
|
} |
3032 |
|
|
|
3033 |
|
|
if ($has_set) { |
3034 |
|
|
push @desc, pod_para ('DOM applications can set the value by:'), |
3035 |
|
|
pod_pre (qq{\$obj->$m_name (\$newValue)}), |
3036 |
|
|
pod_list 4, |
3037 |
|
|
pod_item (pod_code q<$newValue>), |
3038 |
|
|
pod_list 4, @set_desc; |
3039 |
|
|
push @desc, (@set_xcept ? |
3040 |
|
|
(pod_para (q<Setting this attribute may raise exception:>), |
3041 |
|
|
pod_list (4, @set_xcept)) : |
3042 |
|
|
(pod_para (q<Setting this attribute does not raise >. |
3043 |
|
|
q<exception in general.>))); |
3044 |
|
|
} else { |
3045 |
|
|
push @desc, pod_para ('This attribute is read-only.'); |
3046 |
|
|
} |
3047 |
|
|
is_implemented if => $Status->{IF}, method => $Status->{Method}, |
3048 |
|
|
condition => $opt{condition}, set => $Status->{is_implemented}; |
3049 |
|
|
|
3050 |
|
|
push @desc, get_alternate_description $node; |
3051 |
|
|
push @desc, get_redef_description $node, method => 'attribute'; |
3052 |
|
|
|
3053 |
|
|
if ($node->local_name eq 'IntAttr' or |
3054 |
|
|
$Status->{if}->{method_documented}->{$m_name}++) { |
3055 |
|
|
$result .= pod_block pod_comment @desc; |
3056 |
|
|
} else { |
3057 |
|
|
$result .= pod_block @desc; |
3058 |
|
|
} |
3059 |
|
|
|
3060 |
|
|
my $warn = get_warning_perl_code ($node); |
3061 |
|
|
my $proto; |
3062 |
|
|
if ($has_set) { |
3063 |
|
|
$code = perl_statement (perl_assign |
3064 |
|
|
perl_var (scope => 'my', type => '$', local_name => 'self') |
3065 |
|
|
=> 'shift'). |
3066 |
|
|
$warn. |
3067 |
|
|
perl_if |
3068 |
|
|
q<exists $_[0]>, |
3069 |
|
|
($set_code =~/\bgiven\b/ ? |
3070 |
|
|
perl_statement (q<my $given = shift>) : '') . $set_code . |
3071 |
|
|
perl_statement ('undef'), |
3072 |
|
|
$code; |
3073 |
|
|
$int_code = perl_statement (perl_assign |
3074 |
|
|
perl_var (scope => 'my', type => '$', local_name => 'self') |
3075 |
|
|
=> 'shift'). |
3076 |
|
|
perl_if |
3077 |
|
|
q<exists $_[0]>, |
3078 |
|
|
perl_statement (q<my $given = shift>) . $int_set_code, |
3079 |
|
|
$int_code; |
3080 |
|
|
$proto = '$;$'; |
3081 |
|
|
} else { |
3082 |
|
|
$code = q<my $self = shift; > . $warn . $code; |
3083 |
|
|
$int_code = q<my $self = shift; > . $int_code; |
3084 |
|
|
$proto = '$'; |
3085 |
|
|
} |
3086 |
|
|
$result .= perl_sub name => $m_name, |
3087 |
|
|
prototype => $proto, |
3088 |
|
|
code => $code; |
3089 |
|
|
$result .= perl_sub name => perl_internal_name $m_name, |
3090 |
|
|
prototype => $proto, |
3091 |
|
|
code => $int_code |
3092 |
|
|
if $int_code_node; |
3093 |
|
|
|
3094 |
|
|
if (my $op = get_perl_definition_node $node, name => 'Operator') { |
3095 |
|
|
$Status->{Operator}->{$op->value} = '\\' . perl_var type => '&', |
3096 |
|
|
local_name => $m_name; |
3097 |
|
|
} |
3098 |
|
|
|
3099 |
|
|
$result; |
3100 |
|
|
} # attr2perl |
3101 |
|
|
|
3102 |
|
|
=head2 DataType element |
3103 |
|
|
|
3104 |
|
|
The C<DataType> element defines a datatype. |
3105 |
|
|
|
3106 |
|
|
=cut |
3107 |
|
|
|
3108 |
|
|
sub datatype2perl ($;%) { |
3109 |
|
|
my ($node, %opt) = @_; |
3110 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3111 |
|
|
my $pack_name = perl_package_name |
3112 |
|
|
name => my $if_name |
3113 |
|
|
= perl_name $node->get_attribute_value ('Name'), |
3114 |
|
|
ucfirst => 1; |
3115 |
|
|
local $Status->{IF} = $if_name; |
3116 |
|
|
local $Status->{if} = {}; ## Temporary data |
3117 |
|
|
local $Info->{Namespace} = {%{$Info->{Namespace}}}; |
3118 |
|
|
local $Info->{Require_perl_package} = {%{$Info->{Require_perl_package}}}; |
3119 |
|
|
local $Info->{Require_perl_package_use} = {}; |
3120 |
|
|
local $Status->{Operator} = {}; |
3121 |
|
|
my $result = perl_package full_name => $pack_name; |
3122 |
|
|
my @isa; |
3123 |
|
|
for (@{$node->child_nodes}) { |
3124 |
|
|
next unless $_->node_type eq '#element' and |
3125 |
|
|
$_->local_name eq 'ISA' and |
3126 |
|
|
condition_match $_, condition => $opt{condition}, |
3127 |
|
|
default_any => 1, ge => 1; |
3128 |
|
|
push @isa, perl_package_name qname_with_condition => $_->value, |
3129 |
|
|
condition => $opt{condition}; |
3130 |
|
|
} |
3131 |
|
|
$result .= perl_inherit [@isa, perl_package_name (name => 'ManakaiDOMObject'), |
3132 |
|
|
perl_package_name (if => $if_name)]; |
3133 |
wakaba |
1.4 |
$Status->{def_pack}->{$pack_name} = 1; |
3134 |
|
|
$Status->{def_pack}->{perl_package_name if => $if_name} = 1; |
3135 |
wakaba |
1.1 |
|
3136 |
|
|
my @level = @{$opt{level} || []}; |
3137 |
|
|
my $mod = get_level_description $node, level => \@level; |
3138 |
|
|
$result .= pod_block |
3139 |
|
|
pod_head ($Status->{depth}, 'Type ' . pod_code $if_name), |
3140 |
|
|
pod_paras (get_description ($node)), |
3141 |
|
|
($mod ? pod_para ('This type is ' . $mod) : ()); |
3142 |
|
|
|
3143 |
|
|
for (@{$node->child_nodes}) { |
3144 |
|
|
if ($_->local_name eq 'Method' or |
3145 |
|
|
$_->local_name eq 'IntMethod') { |
3146 |
|
|
$result .= method2perl ($_, level => \@level, |
3147 |
|
|
condition => $opt{condition}); |
3148 |
|
|
} elsif ($_->local_name eq 'Attr' or |
3149 |
|
|
$_->local_name eq 'IntAttr') { |
3150 |
|
|
$result .= attr2perl ($_, level => \@level, condition => $opt{condition}); |
3151 |
|
|
} elsif ($_->local_name eq 'ConstGroup') { |
3152 |
|
|
$result .= constgroup2perl ($_, level => \@level, |
3153 |
|
|
condition => $opt{condition}, |
3154 |
|
|
package => $pack_name); |
3155 |
|
|
} elsif ($_->local_name eq 'Const') { |
3156 |
|
|
$result .= const2perl ($_, level => \@level, |
3157 |
|
|
condition => $opt{condition}, |
3158 |
|
|
package => $pack_name); |
3159 |
|
|
} elsif ($_->local_name eq 'ISA') { |
3160 |
|
|
push @{$Info->{DataTypeAlias}->{type_expanded_uri $if_name} |
3161 |
|
|
->{isa_uri}||=[]}, |
3162 |
|
|
type_expanded_uri $_->value; |
3163 |
|
|
} elsif ({qw/Name 1 FullName 1 Spec 1 Description 1 |
3164 |
|
|
Level 1 SpecLevel 1 Def 1 ImplNote 1/}->{$_->local_name}) { |
3165 |
|
|
# |
3166 |
|
|
} else { |
3167 |
|
|
valid_warn qq{Element @{[$_->local_name]} not supported}; |
3168 |
|
|
} |
3169 |
|
|
} |
3170 |
|
|
|
3171 |
|
|
$result .= ops2perl; |
3172 |
|
|
|
3173 |
|
|
$result; |
3174 |
|
|
} # datatype2perl |
3175 |
|
|
|
3176 |
|
|
sub datatypealias2perl ($;%) { |
3177 |
|
|
my ($node, %opt) = @_; |
3178 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3179 |
|
|
my $if_name = $node->get_attribute_value ('Name'); |
3180 |
|
|
my $long_name = expanded_uri $if_name; |
3181 |
|
|
my $real_long_name = type_expanded_uri |
3182 |
|
|
(my $real_name = $node->get_attribute_value |
3183 |
|
|
('Type', default => 'DOMMain:any')); |
3184 |
|
|
if (type_label ($real_long_name) eq type_label ($long_name)) { |
3185 |
|
|
$Info->{DataTypeAlias}->{$long_name}->{canon_uri} = $real_long_name; |
3186 |
|
|
return perl_comment sprintf '%s <%s> := %s <%s>', |
3187 |
|
|
type_label ($long_name), $long_name, |
3188 |
|
|
type_label ($real_long_name), $real_long_name; |
3189 |
|
|
} |
3190 |
|
|
$Info->{DataTypeAlias}->{$long_name}->{canon_uri} = $real_long_name; |
3191 |
|
|
|
3192 |
|
|
$if_name = perl_name $if_name, ucfirst => 1; |
3193 |
|
|
$real_name = type_package_name $real_name; |
3194 |
|
|
my $pack_name = perl_package_name name => $if_name; |
3195 |
|
|
local $Status->{IF} = $if_name; |
3196 |
|
|
local $Status->{if} = {}; ## Temporary data |
3197 |
|
|
local $Info->{Namespace} = {%{$Info->{Namespace}}}; |
3198 |
|
|
local $Info->{Require_perl_package} = {%{$Info->{Require_perl_package}}}; |
3199 |
|
|
local $Info->{Require_perl_package_use} = {}; |
3200 |
|
|
my $result = perl_package full_name => $pack_name; |
3201 |
|
|
$result .= perl_inherit [perl_package_name (full_name => $real_name), |
3202 |
|
|
perl_package_name (if => $if_name)]; |
3203 |
wakaba |
1.4 |
$Status->{def_pack}->{perl_package_name if => $if_name} = 1; |
3204 |
wakaba |
1.1 |
|
3205 |
|
|
my @level = @{$opt{level} || []}; |
3206 |
|
|
my $mod = get_level_description $node, level => \@level; |
3207 |
|
|
$result .= pod_block |
3208 |
|
|
pod_head ($Status->{depth}, 'Type ' . pod_code $if_name), |
3209 |
|
|
pod_paras (get_description ($node)), |
3210 |
|
|
pod_para ('This type is an alias of the type ' . |
3211 |
|
|
(type_label $real_long_name, is_pod => 1) . '.'), |
3212 |
|
|
($mod ? pod_para ('This type is ' . $mod) : ()); |
3213 |
|
|
|
3214 |
|
|
for (@{$node->child_nodes}) { |
3215 |
|
|
if ({qw/Name 1 FullName 1 Spec 1 Type 1 Description 1 |
3216 |
|
|
Level 1 SpecLevel 1 Condition 1 ImplNote 1 |
3217 |
|
|
Def 1/}->{$_->local_name}) { |
3218 |
|
|
# |
3219 |
|
|
} else { |
3220 |
|
|
valid_warn qq{Element @{[$_->local_name]} not supported}; |
3221 |
|
|
} |
3222 |
|
|
} |
3223 |
|
|
|
3224 |
|
|
$result; |
3225 |
|
|
} # datatypealias2perl |
3226 |
|
|
|
3227 |
|
|
=item Exception top-level element |
3228 |
|
|
|
3229 |
|
|
=item Warning top-level element |
3230 |
|
|
|
3231 |
|
|
=cut |
3232 |
|
|
|
3233 |
|
|
sub exception2perl ($;%) { |
3234 |
|
|
my ($node, %opt) = @_; |
3235 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3236 |
|
|
local $Status->{const} = {}; |
3237 |
|
|
local $Status->{if} = {}; ## Temporary data |
3238 |
|
|
local $Status->{in_exception} = 1; |
3239 |
|
|
local $Info->{Namespace} = {%{$Info->{Namespace}}}; |
3240 |
|
|
local $Info->{Require_perl_package} = {%{$Info->{Require_perl_package}}}; |
3241 |
|
|
local $Info->{Require_perl_package_use} = {}; |
3242 |
|
|
my $pack_name = perl_package_name |
3243 |
|
|
name => my $if_name |
3244 |
|
|
= perl_name $node->get_attribute_value ('Name'), |
3245 |
|
|
ucfirst => 1; |
3246 |
|
|
my $type = $node->local_name eq 'Exception' ? 'Exception' : 'Warning'; |
3247 |
|
|
local $Status->{IF} = $if_name; |
3248 |
|
|
my $result = perl_package full_name => $pack_name; |
3249 |
wakaba |
1.4 |
$Status->{def_pack}->{$pack_name} = 1; |
3250 |
wakaba |
1.1 |
my @isa = perl_package_name (if => $if_name); |
3251 |
|
|
if ($if_name eq 'ManakaiDOM'.$type) { |
3252 |
|
|
push @isa, perl_package_name name => 'ManakaiDOMExceptionOrWarning'; |
3253 |
|
|
} elsif ($if_name eq 'ManakaiDOMExceptionOrWarning') { |
3254 |
|
|
push @isa, 'Message::Util::Error'; |
3255 |
|
|
} else { |
3256 |
|
|
push @isa, perl_package_name name => 'ManakaiDOM'.$type |
3257 |
|
|
} |
3258 |
|
|
$result .= perl_inherit [@isa]; |
3259 |
wakaba |
1.4 |
$Status->{def_pack}->{perl_package_name if => $if_name} = 1; |
3260 |
wakaba |
1.1 |
my @level = @{$opt{level} || []}; |
3261 |
|
|
my $mod = get_level_description $node, level => \@level; |
3262 |
|
|
$result .= pod_block |
3263 |
|
|
pod_head ($Status->{depth}, $type . ' ' . pod_code $if_name), |
3264 |
|
|
pod_paras (get_description ($node)), |
3265 |
|
|
($mod ? pod_para ('This ' . lc ($type) . ' is introduced in ' . |
3266 |
|
|
$mod . '.') : ()), |
3267 |
|
|
($type eq 'Exception' ? |
3268 |
|
|
(pod_para ('To catch this class of exceptions:'), |
3269 |
|
|
pod_pre (join "\n", |
3270 |
|
|
q|try { |, |
3271 |
|
|
q| ... |, |
3272 |
|
|
q|} catch | . $pack_name . q| with { |, |
3273 |
|
|
q| my $err = shift; |, |
3274 |
|
|
q| if ($err->{type} eq 'ERROR_NAME') { |, |
3275 |
|
|
q| ... # Recover from some error, |, |
3276 |
|
|
q| } else { |, |
3277 |
|
|
q| $err->throw; # rethrow if other |, |
3278 |
|
|
q| } |, |
3279 |
|
|
q|}; # Don't forget semicolon! |)) |
3280 |
|
|
: ()); |
3281 |
|
|
|
3282 |
|
|
for (@{$node->child_nodes}) { |
3283 |
|
|
if ($_->local_name eq 'Method' or |
3284 |
|
|
$_->local_name eq 'IntMethod' or |
3285 |
|
|
$_->local_name eq 'ReMethod') { |
3286 |
|
|
$result .= method2perl ($_, level => \@level, |
3287 |
|
|
condition => $opt{condition}, |
3288 |
|
|
any_unless_condition => 1); |
3289 |
|
|
} elsif ($_->local_name eq 'Attr' or |
3290 |
|
|
$_->local_name eq 'IntAttr' or |
3291 |
|
|
$_->local_name eq 'ReAttr') { |
3292 |
|
|
my $get; |
3293 |
|
|
if ($_->local_name eq 'Attr' and |
3294 |
|
|
$_->get_attribute_value ('Name') eq 'code' and |
3295 |
|
|
$get = $_->get_attribute ('Get') and |
3296 |
|
|
not get_perl_definition_node $get, name => 'Def') { |
3297 |
|
|
for ($get->append_new_node (type => '#element', |
3298 |
|
|
local_name => 'Def', |
3299 |
|
|
value => q{ |
3300 |
|
|
$r = $self->{<Q:ManakaiDOM:code>}; |
3301 |
|
|
})) { |
3302 |
|
|
$_->set_attribute (type => 'lang:Perl'); ## ISSUE: NS prefix assoc. |
3303 |
|
|
} |
3304 |
|
|
} |
3305 |
|
|
$result .= attr2perl ($_, level => \@level, condition => $opt{condition}, |
3306 |
|
|
any_unless_condition => 1); |
3307 |
|
|
} elsif ($_->local_name eq 'ConstGroup') { |
3308 |
|
|
$result .= constgroup2perl ($_, level => \@level, |
3309 |
|
|
condition => $opt{condition}, |
3310 |
|
|
package => $pack_name, |
3311 |
|
|
any_unless_condition => 1); |
3312 |
|
|
} elsif ($_->local_name eq 'Const') { |
3313 |
|
|
$result .= const2perl ($_, level => \@level, |
3314 |
|
|
condition => $opt{condition}, |
3315 |
|
|
package => $pack_name, |
3316 |
|
|
any_unless_condition => 1); |
3317 |
|
|
} elsif ({qw/Name 1 Spec 1 Description 1 |
3318 |
|
|
Level 1 SpecLevel 1 Condition 1 |
3319 |
|
|
ImplNote 1/}->{$_->local_name}) { |
3320 |
|
|
# |
3321 |
|
|
} else { |
3322 |
|
|
valid_warn qq{Element @{[$_->local_name]} not supported}; |
3323 |
|
|
} |
3324 |
|
|
} |
3325 |
|
|
|
3326 |
|
|
$result .= perl_sub |
3327 |
|
|
name => '___error_def', prototype => '', |
3328 |
|
|
code => perl_list { |
3329 |
|
|
map { |
3330 |
|
|
$_ => { |
3331 |
|
|
ExpandedURI q<DOMCore:code> => perl_code_literal |
3332 |
|
|
($Status->{const}->{$_}->{code_literal}), |
3333 |
|
|
description |
3334 |
|
|
=> $Status->{const}->{$_}->{description}, |
3335 |
|
|
ExpandedURI q<MDOM_EXCEPTION:subtype> |
3336 |
|
|
=> $Status->{const}->{$_}->{subtype}, |
3337 |
|
|
} |
3338 |
|
|
} sort keys %{$Status->{const}} |
3339 |
|
|
}; |
3340 |
|
|
|
3341 |
|
|
$result; |
3342 |
|
|
} # exception2perl |
3343 |
|
|
|
3344 |
|
|
sub constgroup2perl ($;%); |
3345 |
|
|
sub constgroup2perl ($;%) { |
3346 |
|
|
my ($node, %opt) = @_; |
3347 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3348 |
|
|
my $name = $node->get_attribute ('Name'); |
3349 |
|
|
if (defined $name) { |
3350 |
|
|
$name = perl_name $name->value, ucfirst => 1; |
3351 |
|
|
} |
3352 |
|
|
local $Status->{IF} = $name || q<[anonymous constant group]>; |
3353 |
|
|
my @level = @{$opt{level} || []}; |
3354 |
|
|
my $mod = get_level_description $node, level => \@level; |
3355 |
|
|
my $result = ''; |
3356 |
|
|
my $consts = {}; |
3357 |
|
|
$Info->{DataTypeAlias}->{expanded_uri $node->get_attribute_value ('Name')} |
3358 |
|
|
->{isa_uri} = [type_expanded_uri $node->get_attribute_value |
3359 |
|
|
('Type', default => q<DOMMain:any>)] |
3360 |
|
|
if defined $name; |
3361 |
|
|
|
3362 |
|
|
my $i = 0; |
3363 |
|
|
{ |
3364 |
|
|
local $Status->{EXPORT_OK} = $consts; |
3365 |
|
|
for (@{$node->child_nodes}) { |
3366 |
|
|
my $only_document = $opt{only_document} || 0; |
3367 |
|
|
unless ($_->node_type eq '#element' and |
3368 |
|
|
condition_match $_, level_default => \@level, |
3369 |
|
|
condition => $opt{condition}, |
3370 |
|
|
any_unless_condition |
3371 |
|
|
=> $opt{any_unless_condition}) { |
3372 |
|
|
$only_document = 1; |
3373 |
|
|
} |
3374 |
|
|
|
3375 |
|
|
if ($_->local_name eq 'ConstGroup') { |
3376 |
|
|
$result .= constgroup2perl ($_, level => \@level, |
3377 |
|
|
condition => $opt{condition}, |
3378 |
|
|
without_document => $opt{without_document}, |
3379 |
|
|
only_document => $only_document, |
3380 |
|
|
package => $opt{package}, |
3381 |
|
|
any_unless_condition |
3382 |
|
|
=> $opt{any_unless_condition}); |
3383 |
|
|
$i++; |
3384 |
|
|
} elsif ($_->local_name eq 'Const') { |
3385 |
|
|
$result .= const2perl ($_, level => \@level, |
3386 |
|
|
condition => $opt{condition}, |
3387 |
|
|
without_document => $opt{without_document}, |
3388 |
|
|
only_document => $only_document, |
3389 |
|
|
package => $opt{package}, |
3390 |
|
|
any_unless_condition |
3391 |
|
|
=> $opt{any_unless_condition}); |
3392 |
|
|
$i++; |
3393 |
|
|
} elsif ({qw/Name 1 Spec 1 ISA 1 Description 1 Type 1 IsBitMask 1 |
3394 |
|
|
Level 1 SpecLevel 1 Def 1 ImplNote 1 |
3395 |
|
|
FullName 1/}->{$_->local_name}) { |
3396 |
|
|
# |
3397 |
|
|
} else { |
3398 |
|
|
valid_warn qq{Element @{[$_->local_name]} not supported}; |
3399 |
|
|
} |
3400 |
|
|
} |
3401 |
|
|
} |
3402 |
|
|
|
3403 |
|
|
for (keys %$consts) { |
3404 |
|
|
$Status->{EXPORT_OK}->{$_} = 1; |
3405 |
|
|
$Status->{EXPORT_TAGS}->{$name}->{$_} = 1 if defined $name; |
3406 |
|
|
} |
3407 |
|
|
|
3408 |
|
|
return $result if $opt{without_document}; |
3409 |
|
|
|
3410 |
|
|
my @desc; |
3411 |
|
|
if (defined $name) { |
3412 |
|
|
push @desc, pod_head $Status->{depth}, 'Constant Group ' . pod_code $name; |
3413 |
|
|
} else { |
3414 |
|
|
push @desc, pod_head $Status->{depth}, 'Constant Group: ' . |
3415 |
|
|
get_description ($node, |
3416 |
|
|
name => 'FullName'); |
3417 |
|
|
} |
3418 |
|
|
|
3419 |
|
|
push @desc, pod_paras (get_description ($node)), |
3420 |
|
|
($mod ? pod_para ('This constant group has been ' . $mod . '.') |
3421 |
|
|
: ()), |
3422 |
|
|
pod_para ('This constant group has ' . |
3423 |
|
|
english_number $i, singular => q<value.>, |
3424 |
|
|
plural => q<values.>); |
3425 |
|
|
|
3426 |
|
|
push @desc, pod_para ('To export all constant values in this group:'), |
3427 |
|
|
pod_pre (perl_statement "use $Info->{Package} qw/:$name/") |
3428 |
|
|
if defined $name; |
3429 |
|
|
|
3430 |
|
|
$result = pod_block (@desc) . $result; |
3431 |
|
|
|
3432 |
|
|
$result; |
3433 |
|
|
} # constgroup2perl |
3434 |
|
|
|
3435 |
|
|
sub const2perl ($;%) { |
3436 |
|
|
my ($node, %opt) = @_; |
3437 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3438 |
|
|
my $name = perl_name $node->get_attribute_value ('Name'); |
3439 |
|
|
my $longname = perl_var local_name => $name, |
3440 |
|
|
package => {full_name => $opt{package} || |
3441 |
|
|
$Info->{Package}}; |
3442 |
|
|
local $Status->{IF} = $name; |
3443 |
|
|
local $Status->{const_subtype} = {}; |
3444 |
|
|
my @level = @{$opt{level} || []}; |
3445 |
|
|
my $mod = get_level_description $node, level => \@level; |
3446 |
|
|
my @desc; |
3447 |
|
|
unless ($opt{without_document}) { |
3448 |
|
|
@desc = (pod_head ($Status->{depth}, 'Constant Value ' . pod_code $name), |
3449 |
|
|
pod_paras (get_description ($node)), |
3450 |
|
|
($mod ? pod_para ('This constant value has been ' . $mod . '.') |
3451 |
|
|
: ())); |
3452 |
|
|
|
3453 |
|
|
if ($Status->{in_exception}) { ## Is Exception/Warning code |
3454 |
|
|
# |
3455 |
|
|
} else { ## Is NOT Exception/Warning code |
3456 |
|
|
push @desc, pod_para ('To export this constant value:'), |
3457 |
|
|
pod_pre (perl_statement "use $Info->{Package} qw/$name/"); |
3458 |
|
|
} |
3459 |
|
|
|
3460 |
|
|
my @param; |
3461 |
|
|
for (@{$node->child_nodes}) { |
3462 |
|
|
next unless $_->node_type eq '#element'; |
3463 |
|
|
if ($_->local_name eq 'Param') { |
3464 |
|
|
if ($Status->{in_exception}) { |
3465 |
|
|
push @param, param2poditem ($_); |
3466 |
|
|
} else { |
3467 |
|
|
valid_err qq{Element "Param" may not be used with non-Exception}. |
3468 |
|
|
qq{/Warning constants}, |
3469 |
|
|
node => $node; |
3470 |
|
|
} |
3471 |
|
|
} elsif ($_->local_name eq 'SubType') { |
3472 |
|
|
if ($Status->{in_exception}) { |
3473 |
|
|
push @param, subtype2poditem ($_); |
3474 |
|
|
} else { |
3475 |
|
|
valid_err qq{Element "SubType" may not be used with non-Exception}. |
3476 |
|
|
qq{/Warning constants}, |
3477 |
|
|
node => $node; |
3478 |
|
|
} |
3479 |
|
|
} elsif ({qw/Name 1 Spec 1 Description 1 |
3480 |
|
|
Condition 1 Level 1 SpecLevel 1 |
3481 |
|
|
Type 1 Value 1 ImplNote 1/}->{$_->local_name}) { |
3482 |
|
|
# |
3483 |
|
|
} else { |
3484 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
3485 |
|
|
node => $node; |
3486 |
|
|
} |
3487 |
|
|
} |
3488 |
|
|
push @desc, pod_list 4, @param if @param; |
3489 |
|
|
} |
3490 |
|
|
|
3491 |
|
|
my $result = ''; |
3492 |
|
|
unless ($opt{only_document}) { |
3493 |
|
|
$result = perl_sub name => $longname, prototype => '', |
3494 |
|
|
code => my $code = get_value_literal |
3495 |
|
|
$node, name => 'Value'; |
3496 |
|
|
$result .= perl_sub name => perl_var (package => {full_name |
3497 |
|
|
=> $Info->{Package}}, |
3498 |
|
|
local_name => $name), prototype => '', |
3499 |
|
|
code => $code |
3500 |
|
|
if $opt{package} and $Info->{Package} ne $opt{package}; |
3501 |
|
|
my $desc_template = get_description $node, |
3502 |
|
|
type => ExpandedURI q<lang:muf>, |
3503 |
|
|
default => $name; |
3504 |
|
|
$Status->{const}->{$name} = { |
3505 |
|
|
description => $desc_template, |
3506 |
|
|
code_literal => $code, |
3507 |
|
|
subtype => $Status->{const_subtype} || {}, |
3508 |
|
|
}; |
3509 |
|
|
} |
3510 |
|
|
|
3511 |
|
|
$Status->{EXPORT_OK}->{$name} = 1; |
3512 |
|
|
|
3513 |
|
|
unless ($opt{without_document}) { |
3514 |
|
|
$result = pod_block (@desc) . $result; |
3515 |
|
|
} |
3516 |
|
|
|
3517 |
|
|
$result; |
3518 |
|
|
} # const2perl |
3519 |
|
|
|
3520 |
|
|
sub param2poditem ($;%) { |
3521 |
|
|
my ($node, %opt) = @_; |
3522 |
|
|
my @desc; |
3523 |
|
|
$opt{name_prefix} = 'Parameter: ' unless defined $opt{name_prefix}; |
3524 |
|
|
if ($node->get_attribute ('Name')) { |
3525 |
|
|
push @desc, $opt{name_prefix} . pod_code $node->get_attribute_value ('Name'); |
3526 |
|
|
} elsif ($node->get_attribute ('QName')) { |
3527 |
|
|
push @desc, pod_item $opt{name_prefix} . |
3528 |
|
|
qname_label ($node, |
3529 |
|
|
out_type => ExpandedURI q<lang:pod>); |
3530 |
|
|
} else { |
3531 |
|
|
valid_err q<Attribute "Name" or "QName" required>, |
3532 |
|
|
node => $node; |
3533 |
|
|
} |
3534 |
|
|
|
3535 |
|
|
my @val; |
3536 |
|
|
push @val, pod_item (type_label (type_expanded_uri |
3537 |
|
|
($node->get_attribute_value |
3538 |
|
|
('Type', |
3539 |
|
|
default => 'DOMMain:any')), |
3540 |
|
|
is_pod => 1)), |
3541 |
wakaba |
1.3 |
pod_paras (get_description $node); |
3542 |
wakaba |
1.1 |
for (@{$node->child_nodes}) { |
3543 |
|
|
last unless $_->node_type eq '#element'; |
3544 |
|
|
if ($_->local_name eq 'InCase') { |
3545 |
|
|
push @val, pod_item (get_incase_label $_, is_pod => 1), |
3546 |
wakaba |
1.3 |
pod_paras (get_description $_); |
3547 |
wakaba |
1.1 |
} elsif ({qw/Name 1 QName 1 Type 1 |
3548 |
|
|
Description 1 ImplNote 1/}->{$_->local_name}) { |
3549 |
|
|
# |
3550 |
|
|
} else { |
3551 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
3552 |
|
|
node => $_; |
3553 |
|
|
} |
3554 |
|
|
} |
3555 |
|
|
|
3556 |
|
|
if (@val) { |
3557 |
|
|
push @desc, pod_list 4, @val; |
3558 |
|
|
} |
3559 |
|
|
|
3560 |
|
|
@desc; |
3561 |
|
|
} # param2poditem |
3562 |
|
|
|
3563 |
|
|
sub subtype2poditem ($;%) { |
3564 |
|
|
my ($node, %opt) = @_; |
3565 |
|
|
my @desc; |
3566 |
|
|
$opt{name_prefix} = 'SubType: ' unless defined $opt{name_prefix}; |
3567 |
|
|
my $qname = $node->get_attribute_value ('QName'); |
3568 |
|
|
if (defined $qname) { |
3569 |
|
|
push @desc, pod_item $opt{name_prefix} . |
3570 |
|
|
qname_label ($node, qname => $qname, |
3571 |
|
|
out_type => ExpandedURI q<lang:pod>); |
3572 |
|
|
} else { |
3573 |
|
|
valid_err q<Attribute "QName" required>, |
3574 |
|
|
node => $node; |
3575 |
|
|
} |
3576 |
|
|
|
3577 |
wakaba |
1.3 |
push @desc, pod_paras (get_description $node); |
3578 |
wakaba |
1.1 |
my @param; |
3579 |
|
|
for (@{$node->child_nodes}) { |
3580 |
|
|
last unless $_->node_type eq '#element'; |
3581 |
|
|
if ($_->local_name eq 'Param') { |
3582 |
|
|
push @param, param2poditem ($_); |
3583 |
|
|
} elsif ({qw/QName 1 Type 1 SpecLevel 1 |
3584 |
|
|
Description 1 ImplNote 1/}->{$_->local_name}) { |
3585 |
|
|
# |
3586 |
|
|
} else { |
3587 |
|
|
valid_err qq{Element type "@{[$_->local_name]}" not supported}, |
3588 |
|
|
node => $_; |
3589 |
|
|
} |
3590 |
|
|
} |
3591 |
|
|
|
3592 |
|
|
if (@param) { |
3593 |
|
|
push @desc, pod_list 4, @param; |
3594 |
|
|
} |
3595 |
|
|
|
3596 |
|
|
my $desc_template = get_description $node, |
3597 |
|
|
type => ExpandedURI q<lang:muf>, |
3598 |
|
|
default => $qname; |
3599 |
|
|
$Status->{const_subtype}->{type_expanded_uri $qname} = { |
3600 |
|
|
description => $desc_template, |
3601 |
|
|
}; |
3602 |
|
|
|
3603 |
|
|
|
3604 |
|
|
@desc; |
3605 |
|
|
} # subtype2poditem |
3606 |
|
|
|
3607 |
|
|
=head2 Require element |
3608 |
|
|
|
3609 |
|
|
The C<Require> element indicates that some external modules |
3610 |
|
|
are required. Both DOM-implementing modules and language-specific |
3611 |
|
|
library modules are allowed. |
3612 |
|
|
|
3613 |
|
|
Children: |
3614 |
|
|
|
3615 |
|
|
=over 4 |
3616 |
|
|
|
3617 |
|
|
=item Require/Module (0 - infinite) |
3618 |
|
|
|
3619 |
|
|
A required module. |
3620 |
|
|
|
3621 |
|
|
Children: |
3622 |
|
|
|
3623 |
|
|
=over 4 |
3624 |
|
|
|
3625 |
|
|
=item Require/Module/Name = name (0 - 1) |
3626 |
|
|
|
3627 |
|
|
The DOM module name. Iif it is a DOM-implementing module, |
3628 |
|
|
this attribute MUST be specified. |
3629 |
|
|
|
3630 |
|
|
=item Require/Module/Namespace = namespace-uri (0 - 1) |
3631 |
|
|
|
3632 |
|
|
The namespace URI for the module, if any. Namespace prefix |
3633 |
|
|
C<Name> is to be binded with C<Namespace> if both |
3634 |
|
|
C<Name> and C<Namespace> are available. |
3635 |
|
|
|
3636 |
|
|
=item Require/Module/Def = Type-dependent (0 - infinite) |
3637 |
|
|
|
3638 |
|
|
Language-depending definition of loading of the required module. |
3639 |
|
|
If no appropriate C<Type> of C<Def> element is available, |
3640 |
|
|
loading code is generated from C<Name> attribute. |
3641 |
|
|
|
3642 |
|
|
=back |
3643 |
|
|
|
3644 |
|
|
=back |
3645 |
|
|
|
3646 |
|
|
=cut |
3647 |
|
|
|
3648 |
|
|
sub req2perl ($) { |
3649 |
|
|
my $node = shift; |
3650 |
|
|
my $reqnode = $node->local_name eq 'Require' ? $node : |
3651 |
|
|
$node->get_attribute ('Require', make_new_node => 1); |
3652 |
|
|
my $result = ''; |
3653 |
|
|
for (@{$reqnode->child_nodes}) { |
3654 |
|
|
if ($_->local_name eq 'Module') { |
3655 |
|
|
my $m_name = $_->get_attribute_value ('Name', default => '<anon>'); |
3656 |
|
|
my $ns_uri = $_->get_attribute_value ('Namespace'); |
3657 |
|
|
$Info->{Namespace}->{$m_name} = $ns_uri if defined $ns_uri; |
3658 |
|
|
$m_name = perl_name $m_name, ucfirst => 1; |
3659 |
|
|
my $desc = get_description $_; |
3660 |
|
|
$result .= perl_comment (($m_name ne '<anon>' ? $m_name : '') . |
3661 |
|
|
($desc ? ' - ' . $desc : '')) |
3662 |
|
|
if $desc or $m_name ne '<anon>'; |
3663 |
|
|
my $def = get_perl_definition_node $_, name => 'Def'; |
3664 |
|
|
if ($def) { |
3665 |
|
|
my $s; |
3666 |
|
|
my $req; |
3667 |
|
|
my $pack_name; |
3668 |
|
|
if ($req = $def->get_attribute ('require')) { |
3669 |
|
|
$s = 'require ' . ($pack_name = perl_code $req->value); |
3670 |
|
|
$Info->{uri_to_perl_package}->{$ns_uri} = $pack_name if $ns_uri; |
3671 |
|
|
$Info->{Require_perl_package}->{$pack_name} = 1; |
3672 |
|
|
} elsif ($req = $def->get_attribute ('use')) { |
3673 |
|
|
$s = 'use ' . ($pack_name = perl_code $req->value); |
3674 |
|
|
$Info->{uri_to_perl_package}->{$ns_uri} = $pack_name if $ns_uri; |
3675 |
|
|
$Info->{Require_perl_package}->{$pack_name} = 1; |
3676 |
|
|
$Info->{Require_perl_package_use}->{$pack_name} = 1; |
3677 |
|
|
} elsif (defined ($s = $def->value)) { |
3678 |
|
|
# |
3679 |
|
|
} else { |
3680 |
|
|
valid_warn qq<Required module definition for $m_name is empty>; |
3681 |
|
|
} |
3682 |
|
|
if ($req and my $list = $req->get_attribute_value ('Import', |
3683 |
|
|
as_array => 1)) { |
3684 |
|
|
if (@$list) { |
3685 |
|
|
$s .= ' ' . perl_list @$list; |
3686 |
|
|
$Info->{Require_perl_package_use} |
3687 |
|
|
->{$pack_name . '::::Import'}->{$_} = 1 for @$list; |
3688 |
|
|
} |
3689 |
|
|
} |
3690 |
|
|
$result .= perl_statement $s; |
3691 |
|
|
} else { |
3692 |
|
|
$result .= perl_statement 'require ' . |
3693 |
|
|
perl_code "__CLASS{$m_name}__"; |
3694 |
|
|
} |
3695 |
|
|
} elsif ($_->local_name eq 'Condition') { |
3696 |
|
|
} else { |
3697 |
|
|
valid_warn qq[Requiredness type @{[$_->local_name]} not supported]; |
3698 |
|
|
} |
3699 |
|
|
} |
3700 |
|
|
$result; |
3701 |
|
|
} |
3702 |
|
|
|
3703 |
|
|
=head2 Module element |
3704 |
|
|
|
3705 |
|
|
A "dis" file requires one (and only one) C<Module> top-level element. |
3706 |
|
|
Other elements, such as C<Require>, may include C<Module> elements |
3707 |
|
|
as their children. |
3708 |
|
|
|
3709 |
|
|
Children: |
3710 |
|
|
|
3711 |
|
|
=over 4 |
3712 |
|
|
|
3713 |
|
|
=item Module/Name = name (0 - 1) |
3714 |
|
|
|
3715 |
|
|
The module name. Usually DOM IDL module name is used. |
3716 |
|
|
|
3717 |
|
|
This attribute is required when C<Module> element is used as |
3718 |
|
|
a top-level element. It is optional if C<Module> is a child |
3719 |
|
|
of other element. |
3720 |
|
|
|
3721 |
|
|
=item Module/Package = Type-dependent (0 - infinite) |
3722 |
|
|
|
3723 |
|
|
The module package name. For example, |
3724 |
|
|
|
3725 |
|
|
Module: |
3726 |
|
|
@Name: module1 |
3727 |
|
|
@Package: |
3728 |
|
|
@@@: Module1 |
3729 |
|
|
@@Type: |
3730 |
|
|
lang:Perl |
3731 |
|
|
|
3732 |
|
|
means that general module name is C<module1> and Perl-specific |
3733 |
|
|
module name is C<Module1>. |
3734 |
|
|
|
3735 |
|
|
=item Module/Namespace = namespace (1 - 1) |
3736 |
|
|
|
3737 |
|
|
The namespace URI (an absolute URI with optional fragment identifier) |
3738 |
|
|
that is assigned to this module. Datatypes defined by this module |
3739 |
|
|
(such as C<DataType> or C<Interface>) are considered to belong to |
3740 |
|
|
this namespace. |
3741 |
|
|
|
3742 |
|
|
In addition, the default namespace is binding to this namespace name |
3743 |
|
|
(in other word, special namespace prefix C<#default> is associated |
3744 |
|
|
with the URI reference). |
3745 |
|
|
|
3746 |
|
|
=item Module/FullName = text (0 - infinite) |
3747 |
|
|
|
3748 |
|
|
A human-readable module name. |
3749 |
|
|
|
3750 |
|
|
=item Module/Description = text (0 - infinite) |
3751 |
|
|
|
3752 |
|
|
A human-readable module description. |
3753 |
|
|
|
3754 |
|
|
=item Module/License = qname (1 - 1) |
3755 |
|
|
|
3756 |
|
|
A qname that identify the license term. |
3757 |
|
|
|
3758 |
|
|
=item Module/Date.RCS = <rcs date> (1 - 1) |
3759 |
|
|
|
3760 |
|
|
The last-modified date-time of this module, |
3761 |
|
|
represented in RCS format (text C<Date:> with date and time, |
3762 |
|
|
enclosed by C<$>s). |
3763 |
|
|
|
3764 |
|
|
=item Module/Require (0 - infinite) |
3765 |
|
|
|
3766 |
|
|
A list of modules (DOM modules or other liburary modules) |
3767 |
|
|
that is required by entire module. |
3768 |
|
|
|
3769 |
|
|
=back |
3770 |
|
|
|
3771 |
|
|
=cut |
3772 |
|
|
|
3773 |
|
|
## Get general information |
3774 |
|
|
$Info->{source_filename} = $ARGV; |
3775 |
|
|
|
3776 |
|
|
## Initial Namespace bindings |
3777 |
|
|
for ([ManakaiDOM => ExpandedURI q<ManakaiDOM:>], |
3778 |
|
|
[http => q<http:>]) { |
3779 |
|
|
$Info->{Namespace}->{$_->[0]} = $_->[1]; |
3780 |
|
|
} |
3781 |
|
|
|
3782 |
|
|
## Initial DataType aliasing and inheritance |
3783 |
|
|
for (ExpandedURI q<ManakaiDOM:ManakaiDOMURI>, |
3784 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMNamespaceURI>, |
3785 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatureName>, |
3786 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatureVersion>, |
3787 |
wakaba |
1.3 |
ExpandedURI q<ManakaiDOM:ManakaiDOMFeatures>, |
3788 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMKeyIdentifier>, |
3789 |
|
|
ExpandedURI q<ManakaiDOM:ManakaiDOMKeyIdentifiers>) { |
3790 |
wakaba |
1.1 |
$Info->{DataTypeAlias}->{$_} |
3791 |
|
|
->{isa_uri} = [ExpandedURI q<DOMMain:DOMString>]; |
3792 |
|
|
} |
3793 |
|
|
|
3794 |
|
|
register_namespace_declaration ($source); |
3795 |
|
|
|
3796 |
|
|
my $Module = $source->get_attribute ('Module', make_new_node => 1); |
3797 |
|
|
$Info->{Name} = perl_name $Module->get_attribute_value ('Name'), ucfirst => 1 |
3798 |
|
|
or valid_err q<Module name (/Module/Name) MUST be specified>; |
3799 |
|
|
$Info->{Namespace}->{(DEFAULT_PFX)} |
3800 |
|
|
= $Module->get_attribute_value ('Namespace') |
3801 |
|
|
or valid_err q<Module namespace URI (/Module/Namespace) MUST be specified>; |
3802 |
|
|
$Info->{Namespace}->{$Module->get_attribute_value ('Name')} |
3803 |
|
|
= $Info->{Namespace}->{(DEFAULT_PFX)}; |
3804 |
|
|
my $pack_node = get_perl_definition_node $Module, name => 'BindingName'; |
3805 |
|
|
if ($pack_node) { |
3806 |
|
|
$Info->{Package} = perl_code $pack_node->value; |
3807 |
|
|
} else { |
3808 |
|
|
$Info->{Package} = perl_package_name name => $Info->{Name}; |
3809 |
|
|
} |
3810 |
|
|
$Info->{uri_to_perl_package}->{$Info->{Namespace}->{(DEFAULT_PFX)}} |
3811 |
|
|
= $Info->{Package}; |
3812 |
|
|
$Info->{Require_perl_package} = {}; |
3813 |
|
|
$Info->{Require_perl_package_use} = {}; |
3814 |
|
|
|
3815 |
|
|
## Make source code |
3816 |
|
|
$result .= perl_comment q<This file is automatically generated from> . "\n" . |
3817 |
|
|
q<"> . $Info->{source_filename} . q<" at > . |
3818 |
|
|
rfc3339_date (time) . qq<.\n> . |
3819 |
|
|
q<Don't edit by hand!>; |
3820 |
|
|
|
3821 |
|
|
$result .= perl_statement q<use strict>; |
3822 |
|
|
|
3823 |
|
|
local $Status->{depth} = $Status->{depth} + 1; |
3824 |
|
|
$result .= perl_package full_name => $Info->{Package}; |
3825 |
wakaba |
1.4 |
$Status->{def_pack}->{$Info->{Package}} = 1; |
3826 |
wakaba |
1.1 |
|
3827 |
|
|
$result .= pod_block |
3828 |
|
|
pod_head (1, 'NAME'), |
3829 |
|
|
pod_para ($Info->{Package} . |
3830 |
|
|
' - ' . get_description ($Module, name => 'FullName')), |
3831 |
|
|
section ( |
3832 |
|
|
opt => pod_head (1, 'DESCRIPTION'), |
3833 |
wakaba |
1.3 |
req => pod_paras (get_description ($Module)), |
3834 |
wakaba |
1.1 |
), |
3835 |
|
|
pod_head (1, 'DOM INTERFACES'); |
3836 |
|
|
|
3837 |
|
|
## Conditions |
3838 |
|
|
my $defcond = 0; |
3839 |
|
|
for my $cond (@{$Module->child_nodes}) { |
3840 |
|
|
next unless $cond->node_type eq '#element' and |
3841 |
|
|
$cond->local_name eq 'ConditionDef'; |
3842 |
|
|
my $name = $cond->get_attribute_value ('Name', default => ''); |
3843 |
|
|
my $isa = $cond->get_attribute_value ('ISA', default => []); |
3844 |
|
|
my $fullname = get_description $cond, name => 'FullName'; |
3845 |
|
|
$isa = [$isa] unless ref $isa; |
3846 |
|
|
if ($name =~ /^DOM(\d+)$/) { |
3847 |
|
|
$defcond = $1 if $1 > $defcond; |
3848 |
|
|
$fullname ||= "DOM Level " . (0 + $1); |
3849 |
|
|
} |
3850 |
|
|
$Info->{Condition}->{$name}->{ISA} = $isa; |
3851 |
|
|
$Info->{Condition}->{$name}->{FullName} = $fullname || $name; |
3852 |
|
|
} |
3853 |
|
|
if (keys %{$Info->{Condition}}) { |
3854 |
|
|
$Info->{NormalCondition} = $Module->get_attribute_value |
3855 |
|
|
('NormalCondition') || |
3856 |
|
|
$defcond ? 'DOM' . $defcond : |
3857 |
|
|
valid_err q<Module/NormalCondition required>; |
3858 |
|
|
} |
3859 |
|
|
|
3860 |
|
|
## 'require'ing external modules |
3861 |
|
|
{ |
3862 |
|
|
my $req = $Module->get_attribute ('Require', make_new_node => 1); |
3863 |
|
|
my $reqModule = sub { |
3864 |
|
|
my ($name, $me, $you) = @_; |
3865 |
|
|
if ($you->get_attribute_value ('Name', default => '') eq $name) { |
3866 |
|
|
return 1; |
3867 |
|
|
} else { |
3868 |
|
|
return 0; |
3869 |
|
|
} |
3870 |
|
|
}; |
3871 |
|
|
if (not $req->get_element_by (sub {$reqModule->('ManakaiDOMMain', @_)})) { |
3872 |
|
|
for ($req->append_new_node (type => '#element', |
3873 |
|
|
local_name => 'Module')) { |
3874 |
|
|
$_->set_attribute (Name => 'ManakaiDOMMain'); |
3875 |
|
|
$_->set_attribute (Namespace => ExpandedURI q<ManakaiDOM:>); |
3876 |
|
|
} |
3877 |
|
|
} |
3878 |
|
|
if (not $req->get_element_by (sub {$reqModule->('DOMMain', @_)})) { |
3879 |
|
|
for ($req->append_new_node (type => '#element', |
3880 |
|
|
local_name => 'Module')) { |
3881 |
|
|
$_->set_attribute (Name => 'DOMMain'); |
3882 |
|
|
$_->set_attribute (Namespace => ExpandedURI q<DOMMain:>); |
3883 |
|
|
} |
3884 |
|
|
} |
3885 |
|
|
$result .= req2perl $Module; |
3886 |
|
|
} |
3887 |
|
|
|
3888 |
|
|
for my $node (@{$source->child_nodes}) { |
3889 |
|
|
if ($node->node_type ne '#element') { |
3890 |
|
|
## |
3891 |
|
|
} elsif ($node->local_name eq 'IF') { |
3892 |
|
|
$result .= if2perl $node; |
3893 |
|
|
} elsif ($node->local_name eq 'Exception' or |
3894 |
|
|
$node->local_name eq 'Warning') { |
3895 |
|
|
$result .= exception2perl $node; |
3896 |
|
|
} elsif ($node->local_name eq 'DataType') { |
3897 |
|
|
$result .= datatype2perl $node; |
3898 |
|
|
} elsif ($node->local_name eq 'DataTypeAlias') { |
3899 |
|
|
$result .= datatypealias2perl $node; |
3900 |
|
|
} elsif ($node->local_name eq 'ConstGroup') { |
3901 |
|
|
$result .= constgroup2perl $node; |
3902 |
|
|
} elsif ($node->local_name eq 'Const') { |
3903 |
|
|
$result .= const2perl $node; |
3904 |
|
|
} elsif ({qw/Module 1 Namespace 1 ImplNote 1/}->{$node->local_name}) { |
3905 |
|
|
# |
3906 |
|
|
} else { |
3907 |
|
|
valid_warn qq{Top-level element type "@{[$node->local_name]}" not supported}; |
3908 |
|
|
} |
3909 |
|
|
} |
3910 |
|
|
|
3911 |
|
|
## Export |
3912 |
|
|
if (keys %{$Status->{EXPORT_OK}||{}}) { |
3913 |
|
|
$result .= perl_package full_name => $Info->{Package}; |
3914 |
|
|
$result .= perl_statement 'require Exporter'; |
3915 |
|
|
$result .= perl_inherit ['Exporter']; |
3916 |
|
|
$result .= perl_statement |
3917 |
|
|
perl_assign |
3918 |
|
|
perl_var (type => '@', scope => 'our', |
3919 |
|
|
local_name => 'EXPORT_OK') |
3920 |
|
|
=> '(' . perl_list (keys %{$Status->{EXPORT_OK}}) . ')'; |
3921 |
|
|
if (keys %{$Status->{EXPORT_TAGS}||{}}) { |
3922 |
|
|
$result .= perl_statement |
3923 |
|
|
perl_assign |
3924 |
|
|
perl_var (type => '%', scope => 'our', |
3925 |
|
|
local_name => 'EXPORT_TAGS') |
3926 |
|
|
=> '(' . perl_list (map { |
3927 |
|
|
$_ => [keys %{$Status->{EXPORT_TAGS}->{$_}}] |
3928 |
|
|
} keys %{$Status->{EXPORT_TAGS}}) . ')'; |
3929 |
|
|
} |
3930 |
|
|
} |
3931 |
|
|
|
3932 |
wakaba |
1.4 |
## Packages |
3933 |
|
|
{ |
3934 |
|
|
my $list = join ', ', map {'$'.$_.'::VERSION'} |
3935 |
|
|
sort keys %{$Status->{def_pack}}; |
3936 |
|
|
my $date = perl_literal version_date time; |
3937 |
|
|
$result .= qq{ |
3938 |
|
|
for ($list) { |
3939 |
|
|
\$_ = $date; |
3940 |
|
|
} |
3941 |
|
|
}; |
3942 |
|
|
} |
3943 |
|
|
|
3944 |
wakaba |
1.1 |
## Feature |
3945 |
|
|
my @feature_desc; |
3946 |
|
|
my $features = 0; |
3947 |
|
|
for my $condition (sort keys %{$Info->{Condition}}, '') { |
3948 |
|
|
for my $Feature (@{$Module->child_nodes}) { |
3949 |
|
|
next unless $Feature->node_type eq '#element' and |
3950 |
|
|
$Feature->local_name eq 'Feature' and |
3951 |
|
|
condition_match $Feature, condition => $condition; |
3952 |
|
|
is_all_implemented condition => $condition, |
3953 |
|
|
not_implemented => (my $not_implemented = []); |
3954 |
|
|
|
3955 |
|
|
my $f_name = $Feature->get_attribute_value ('Name', default => ''); |
3956 |
|
|
unless (length $f_name) { |
3957 |
|
|
$f_name = expanded_uri $Feature->get_attribute_value ('QName'); |
3958 |
|
|
} |
3959 |
|
|
my $f_ver = $Feature->get_attribute_value ('Version'); |
3960 |
|
|
|
3961 |
|
|
push @feature_desc, pod_item ('Feature ' . pod_code ($f_name) . |
3962 |
|
|
' version ' . pod_code ($f_ver) . |
3963 |
|
|
($Info->{Condition}->{$condition}->{FullName} ? |
3964 |
|
|
' [' . $Info->{Condition}->{$condition} |
3965 |
|
|
->{FullName} . ']' : '')), |
3966 |
|
|
pod_paras (get_description $Feature); |
3967 |
|
|
|
3968 |
|
|
if (@$not_implemented) { |
3969 |
|
|
push @feature_desc, pod_para ('This module provides interfaces '. |
3970 |
|
|
'of this feature but not yet fully ' . |
3971 |
|
|
'implemented.'); |
3972 |
|
|
$result .= perl_comment "$f_name, $f_ver: $not_implemented->[0]." . |
3973 |
|
|
"$not_implemented->[1]<$not_implemented->[2]>" . |
3974 |
|
|
" not implemented."; |
3975 |
|
|
} else { |
3976 |
|
|
push @feature_desc, pod_para ('This module implements this feature, ' . |
3977 |
|
|
'so that the method calls such as ' . |
3978 |
|
|
pod_code ('$DOMImplementation' . |
3979 |
|
|
'->hasFeature (' . |
3980 |
|
|
perl_literal ($f_name) . |
3981 |
|
|
', ' . perl_literal ($f_ver) . |
3982 |
|
|
')') . ' or ' . |
3983 |
|
|
pod_code ('$DOMImplementation' . |
3984 |
|
|
'->hasFeature (' . |
3985 |
|
|
perl_literal ($f_name) . |
3986 |
|
|
', null)') . |
3987 |
|
|
' will return ' . pod_code ('true') . '.'); |
3988 |
|
|
} |
3989 |
|
|
|
3990 |
|
|
for (@{$Feature->child_nodes}) { |
3991 |
|
|
next unless $_->node_type eq '#element'; |
3992 |
|
|
if ($_->local_name eq 'Contrib') { |
3993 |
|
|
my $n = $_->value; |
3994 |
|
|
my $ccondition; |
3995 |
|
|
if ($n =~ s/::([^:]*)$//) { |
3996 |
|
|
$ccondition = $1; |
3997 |
|
|
} |
3998 |
|
|
if ($n =~ s/^[^:]*://) { |
3999 |
|
|
# currently prefix is not used |
4000 |
|
|
} |
4001 |
|
|
$result .= perl_statement |
4002 |
|
|
perl_assign |
4003 |
|
|
perl_var (type => '$', |
4004 |
|
|
package => { |
4005 |
|
|
name => $n, |
4006 |
|
|
condition => $ccondition, |
4007 |
|
|
is_internal => 1, |
4008 |
|
|
}, |
4009 |
|
|
local_name => 'Feature'). |
4010 |
|
|
## Feature name is case-insensitive |
4011 |
|
|
'->{'.perl_literal (lc $f_name).'}->{'. |
4012 |
|
|
perl_literal (@$not_implemented ? '+dummy+' : $f_ver) . '}' |
4013 |
|
|
=> 1; |
4014 |
|
|
} elsif ({ |
4015 |
|
|
qw/Name 1 QName 1 FullName 1 Version 1 |
4016 |
|
|
Description 1 ImplNote 1 Spec 1 |
4017 |
|
|
Condition 1 / |
4018 |
|
|
}->{$_->local_name}) { |
4019 |
|
|
} else { |
4020 |
|
|
valid_err q<Unknown element type>, node => $_; |
4021 |
|
|
} |
4022 |
|
|
} |
4023 |
|
|
|
4024 |
|
|
$features++; |
4025 |
|
|
} |
4026 |
|
|
} |
4027 |
|
|
if (@feature_desc) { |
4028 |
|
|
$result .= pod_block |
4029 |
|
|
pod_head (1, 'DOM FEATURE'.($features>1?'S':'')), |
4030 |
|
|
pod_list 4, @feature_desc; |
4031 |
|
|
} |
4032 |
|
|
|
4033 |
|
|
## TODO list |
4034 |
|
|
my @todo; |
4035 |
|
|
## From not-implemented list |
4036 |
|
|
for my $if (sort keys %{$Info->{is_implemented}}) { |
4037 |
|
|
for my $mem (sort keys %{$Info->{is_implemented}->{$if}}) { |
4038 |
|
|
for my $cond (sort keys %{$Info->{is_implemented}->{$if}->{$mem}}) { |
4039 |
|
|
if (not $Info->{is_implemented}->{$if}->{$mem}->{$cond}) { |
4040 |
|
|
push @todo, pod_item ('Implement '.pod_code ($if).'.'. |
4041 |
|
|
pod_code ($mem).'.'), |
4042 |
|
|
pod_para ('Condition = '. |
4043 |
|
|
($Info->{Condition}->{$cond}->{FullName} || |
4044 |
|
|
'(empty)')); |
4045 |
|
|
} |
4046 |
|
|
} |
4047 |
|
|
} |
4048 |
|
|
} |
4049 |
|
|
## From Description, ImplNote, Def |
4050 |
|
|
my $a; |
4051 |
|
|
$a = sub { |
4052 |
|
|
my $n = shift; |
4053 |
|
|
for (@{$n->child_nodes}) { |
4054 |
|
|
if ($_->node_type eq '#element') { |
4055 |
|
|
$a->($_); |
4056 |
|
|
} |
4057 |
|
|
} |
4058 |
|
|
if (($n->node_type eq '#element' and |
4059 |
|
|
{qw/Description 1 ImplNote 1 |
4060 |
|
|
Def 1 IntDef 1/}->{$n->local_name}) or |
4061 |
|
|
$n->node_type eq '#comment') { |
4062 |
|
|
my $v = $n->value; |
4063 |
|
|
if (defined $v) { |
4064 |
|
|
if (ref $v eq 'ARRAY') { |
4065 |
|
|
$v = join "\n", @$v; |
4066 |
|
|
} |
4067 |
|
|
if ($v =~ /\b(TODO|ISSUE|BUG):/) { |
4068 |
|
|
push @todo, pod_item ($1.': '.pod_code $n->node_path(key => 'Name')); |
4069 |
|
|
my $t = $n->node_type eq '#comment' ? ExpandedURI q<DOMMain:any> : |
4070 |
|
|
$n->get_attribute_value |
4071 |
|
|
('Type', |
4072 |
|
|
default => { |
4073 |
|
|
Description => ExpandedURI q<lang:disdoc>, |
4074 |
|
|
ImplNote => ExpandedURI q<lang:disdoc>, |
4075 |
|
|
Def => ExpandedURI q<DOMMain:any>, |
4076 |
|
|
IntDef => ExpandedURI q<DOMMain:any>, |
4077 |
|
|
}->{$n->local_name}); |
4078 |
|
|
if ($t eq ExpandedURI q<lang:disdoc>) { |
4079 |
|
|
push @todo, disdoc2pod $v; |
4080 |
|
|
} else { |
4081 |
|
|
push @todo, pod_pre ($v); |
4082 |
|
|
} |
4083 |
|
|
} |
4084 |
|
|
} |
4085 |
|
|
} |
4086 |
|
|
}; |
4087 |
|
|
$a->($source); |
4088 |
|
|
if (@todo) { |
4089 |
|
|
$result .= pod_block |
4090 |
|
|
pod_head (1, 'TO DO'), |
4091 |
|
|
pod_list 4, @todo; |
4092 |
|
|
} |
4093 |
|
|
|
4094 |
|
|
|
4095 |
|
|
## Namespace bindings for documentation |
4096 |
|
|
if (my $n = keys %{$Status->{ns_in_doc}}) { |
4097 |
|
|
my @desc = (pod_head (1, 'NAMESPACE BINDING'.($n > 1 ? 'S' : '')), |
4098 |
|
|
pod_para ('In this documentation, namespace prefix'. |
4099 |
|
|
($n > 1 ? 'es ' : ' '). |
4100 |
|
|
($n > 1 ? 'are' : 'is').' bound to:')); |
4101 |
|
|
push @desc, |
4102 |
|
|
pod_list 4, map { |
4103 |
|
|
pod_item (pod_code $_), |
4104 |
|
|
pod_para (pod_code ($Status->{ns_in_doc}->{$_})), |
4105 |
|
|
} keys %{$Status->{ns_in_doc}}; |
4106 |
|
|
$result .= pod_block @desc; |
4107 |
|
|
} |
4108 |
|
|
|
4109 |
|
|
## See also |
4110 |
|
|
## TODO: implement this. |
4111 |
|
|
|
4112 |
|
|
## Author |
4113 |
|
|
my @desc; |
4114 |
|
|
my @author; |
4115 |
|
|
my $author; |
4116 |
|
|
my $authors = 0; |
4117 |
|
|
for (@{$Module->child_nodes}) { |
4118 |
|
|
if ($_->node_type eq '#element' and $_->local_name eq 'Author') { |
4119 |
|
|
my $n = get_description ($_, name => 'FullName'); |
4120 |
|
|
push @author, pod_item $n; |
4121 |
|
|
my @d; |
4122 |
|
|
$author = defined $author ? $authors ? $author |
4123 |
|
|
: ($authors++, $author . ', et al.') |
4124 |
|
|
: $n; |
4125 |
|
|
for (@{$_->child_nodes}) { |
4126 |
|
|
next unless $_->node_type eq '#element'; |
4127 |
|
|
if ($_->local_name eq 'Mail') { |
4128 |
|
|
push @d, pod_item ('Mail'), pod_para (pod_mail $_->value); |
4129 |
|
|
} elsif ({qw/FullName 1/}->{$_->local_name}) { |
4130 |
|
|
# |
4131 |
|
|
} else { |
4132 |
|
|
valid_err q<Unknown element type>, node => $_; |
4133 |
|
|
} |
4134 |
|
|
} |
4135 |
|
|
push @author, pod_list 6, @d if @d; |
4136 |
|
|
} |
4137 |
|
|
} |
4138 |
|
|
$author = 'AUTHORS' unless defined $author; |
4139 |
|
|
if (@author) { |
4140 |
|
|
push @desc, pod_head (1, 'AUTHOR'.($authors?'S':'')), |
4141 |
|
|
pod_list (4, @author); |
4142 |
|
|
} |
4143 |
|
|
|
4144 |
|
|
## License |
4145 |
|
|
push @desc, pod_head (1, 'LICENSE'); |
4146 |
|
|
my $year = (gmtime)[5]+1900; |
4147 |
|
|
my $license = expanded_uri |
4148 |
|
|
$Module->get_attribute_value ('License', default => ''); |
4149 |
|
|
if ($license eq ExpandedURI q<license:Perl>) { |
4150 |
|
|
push @desc, |
4151 |
|
|
pod_para (qq<Copyright $year $author. All rights reserved.>), |
4152 |
|
|
pod_para q<This program is free software; you can redistribute it and/or |
4153 |
|
|
modify it under the same terms as Perl itself.>; |
4154 |
|
|
} elsif ($license eq ExpandedURI q<license:Perl+MPL>) { |
4155 |
|
|
push @desc, |
4156 |
|
|
pod_para (qq<Copyright $year $author. All rights reserved.>), |
4157 |
|
|
pod_para (q<This program is free software; you can redistribute it and/or >. |
4158 |
|
|
q<modify it under the same terms as Perl itself.>), |
4159 |
|
|
|
4160 |
|
|
pod_para (q<Alternatively, the contents of this file may be used >. |
4161 |
|
|
q<under the following terms (the >.pod_dfn (q<MPL/GPL/LGPL>). |
4162 |
|
|
q<, in which case the provisions of the MPL/GPL/LGPL are applicable instead >. |
4163 |
|
|
q<of those above. If you wish to allow use of your version of this file only >. |
4164 |
|
|
q<under the terms of the MPL/GPL/LGPL, and not to allow others to >. |
4165 |
|
|
q<use your version of this file under the terms of the Perl, indicate your >. |
4166 |
|
|
q<decision by deleting the provisions above and replace them with the notice >. |
4167 |
|
|
q<and other provisions required by the MPL/GPL/LGPL. If you do not delete >. |
4168 |
|
|
q<the provisions above, a recipient may use your version of this file under >. |
4169 |
|
|
q<the terms of any one of the Perl or the MPL/GPL/LGPL. >), |
4170 |
|
|
|
4171 |
|
|
pod_head (2, 'MPL/GPL/LGPL'), |
4172 |
|
|
|
4173 |
|
|
# q<***** BEGIN LICENSE BLOCK *****> |
4174 |
|
|
pod_para (q<Version: MPL 1.1/GPL 2.0/LGPL 2.1>), |
4175 |
|
|
|
4176 |
|
|
pod_para |
4177 |
|
|
(q<The contents of this file are subject to the Mozilla Public License Version >. |
4178 |
|
|
q<1.1 (the >.pod_dfn (q<License>).q<); you may not use this file except in >. |
4179 |
|
|
q<compliance with >. |
4180 |
|
|
q<the License. You may obtain a copy of the License at >. |
4181 |
|
|
pod_uri (q<http://www.mozilla.org/MPL/>).q<.>), |
4182 |
|
|
|
4183 |
|
|
pod_para |
4184 |
|
|
(q<Software distributed under the License is distributed on an ">. |
4185 |
|
|
pod_em (q<AS IS>).q<" basis, >. |
4186 |
|
|
pod_em (q<WITHOUT WARRANTY OF ANY KIND>). |
4187 |
|
|
q<, either express or implied. See the License >. |
4188 |
|
|
q<for the specific language governing rights and limitations under the >. |
4189 |
|
|
q<License. >); |
4190 |
|
|
|
4191 |
|
|
my $orig = $Module->get_attribute ('License')->get_attribute ('Original'); |
4192 |
|
|
if ($orig) { |
4193 |
|
|
push @desc, pod_para ('The Original Code is the '. |
4194 |
|
|
get_description ($orig, name => 'FullName').'.'); |
4195 |
|
|
push @desc, pod_para ('The Initial Developer of the Original Code is '. |
4196 |
|
|
get_description ($orig->get_attribute ('Author'), |
4197 |
|
|
name => 'FullName').'. '. |
4198 |
|
|
q<Portions created by the Initial Developer are >. |
4199 |
|
|
q<Copyright >.pod_char (name => 'copy').' '. |
4200 |
|
|
$orig->get_attribute_value ('Year', |
4201 |
|
|
default => $year). |
4202 |
|
|
q< the Initial Developer. All Rights Reserved.>); |
4203 |
|
|
} else { |
4204 |
|
|
my $a = $author; |
4205 |
|
|
$a =~ /, et al\.$/ if $authors; |
4206 |
|
|
|
4207 |
|
|
push @desc, pod_para |
4208 |
|
|
(q<The Original Code is the manakai DOM module.>), |
4209 |
|
|
|
4210 |
|
|
pod_para (qq<The Initial Developer of the Original Code is $a. >. |
4211 |
|
|
q<Portions created by the Initial Developer are Copyright >. |
4212 |
|
|
pod_char (name => 'copy').qq< $year >. |
4213 |
|
|
## ISSUE: Should first created year provided from some source? |
4214 |
|
|
q<the Initial Developer. All Rights Reserved.>); |
4215 |
|
|
} |
4216 |
|
|
|
4217 |
|
|
push @desc, pod_list 4, |
4218 |
|
|
pod_item (q<Contributor(s):>), |
4219 |
|
|
pod_para (q<See >. |
4220 |
|
|
pod_link (section => 'AUTHOR'.($authors?'S':'')). |
4221 |
|
|
q<.>); |
4222 |
|
|
|
4223 |
|
|
push @desc, pod_para |
4224 |
|
|
q<Alternatively, the contents of this file may be used under the terms of >. |
4225 |
|
|
q<either the GNU General Public License Version 2 or later (the ">. |
4226 |
|
|
pod_dfn (q<GPL>).q<"), or >. |
4227 |
|
|
q<the GNU Lesser General Public License Version 2.1 or later (the ">. |
4228 |
|
|
pod_dfn (q<LGPL>).q<"), >. |
4229 |
|
|
q<in which case the provisions of the GPL or the LGPL are applicable instead >. |
4230 |
|
|
q<of those above. If you wish to allow use of your version of this file only >. |
4231 |
|
|
q<under the terms of either the GPL or the LGPL, and not to allow others to >. |
4232 |
|
|
q<use your version of this file under the terms of the MPL, indicate your >. |
4233 |
|
|
q<decision by deleting the provisions above and replace them with the notice >. |
4234 |
|
|
q<and other provisions required by the GPL or the LGPL. If you do not delete >. |
4235 |
|
|
q<the provisions above, a recipient may use your version of this file under >. |
4236 |
|
|
q<the terms of any one of the MPL, the GPL or the LGPL. >; |
4237 |
|
|
|
4238 |
|
|
# ***** END LICENSE BLOCK ***** |
4239 |
|
|
} elsif ($license) { |
4240 |
|
|
valid_warn q<Unknown license: <$license>>; |
4241 |
|
|
push @desc, |
4242 |
|
|
pod_para (qq<Copyright $year $author. All rights reserved.>), |
4243 |
|
|
pod_para (qq<License: >.pod_uri ($license).q<.>); |
4244 |
|
|
} else { |
4245 |
|
|
valid_err q<Required attribute "/Module/License" not specified>; |
4246 |
|
|
} |
4247 |
|
|
$result .= pod_block @desc; |
4248 |
|
|
|
4249 |
|
|
|
4250 |
|
|
$result .= perl_statement 1; |
4251 |
|
|
|
4252 |
wakaba |
1.4 |
if ($Opt{output_pod} eq 'file') { |
4253 |
|
|
open my $pod, '>', $Opt{output_pod_file} |
4254 |
|
|
or die "$0: $Opt{output_pod_file}: $!"; |
4255 |
|
|
print $pod $result_pod; |
4256 |
|
|
} elsif ($Opt{output_pod} eq 'only') { |
4257 |
|
|
$result = $result_pod; |
4258 |
|
|
} |
4259 |
|
|
|
4260 |
wakaba |
1.1 |
output_result $result; |
4261 |
|
|
|
4262 |
|
|
|
4263 |
|
|
__END__ |
4264 |
|
|
|
4265 |
|
|
=head1 SEE ALSO |
4266 |
|
|
|
4267 |
|
|
W3C DOM Specifications <http://www.w3.org/DOM/DOMTR> |
4268 |
|
|
|
4269 |
|
|
SuikaWiki:DOM <http://suika.fam.cx/~wakaba/-temp/wiki/wiki?DOM> |
4270 |
|
|
|
4271 |
|
|
C<idl2dis.pl>: This script generates "dis" files, |
4272 |
|
|
that can be used as a template for the DOM implementation, |
4273 |
|
|
from DOM IDL files. |
4274 |
|
|
|
4275 |
|
|
=head1 LICENSE |
4276 |
|
|
|
4277 |
|
|
Copyright 2004 Wakaba <w@suika.fam.cx>. All rights reserved. |
4278 |
|
|
|
4279 |
|
|
This program is free software; you can redistribute it and/or |
4280 |
|
|
modify it under the same terms as Perl itself. |
4281 |
|
|
|
4282 |
|
|
Note that copyright holder(s) of this script does not claim |
4283 |
|
|
any rights for materials outputed by this script, although it will |
4284 |
|
|
contain some fragments from this script. License terms for them should be |
4285 |
|
|
defined by the copyright holder of the source document. |
4286 |
|
|
|
4287 |
|
|
=cut |
4288 |
|
|
|
4289 |
wakaba |
1.4 |
# $Date: 2004/10/16 13:34:55 $ |
4290 |
wakaba |
1.1 |
|
4291 |
|
|
|