1 |
wakaba |
1.1 |
#!/usr/bin/perl -w |
2 |
|
|
use strict; |
3 |
|
|
use Message::Markup::SuikaWikiConfig20::Node; |
4 |
|
|
|
5 |
|
|
my $LastCategory = ''; |
6 |
|
|
my $LastComment = ''; |
7 |
|
|
my $LastAttr; |
8 |
|
|
my $NAME = qr/[\w:.]+/; |
9 |
|
|
my $Status; |
10 |
|
|
sub err ($); |
11 |
|
|
sub level ($); |
12 |
|
|
sub raises ($$$); |
13 |
|
|
|
14 |
|
|
my $tree = Message::Markup::SuikaWikiConfig20::Node->new (type => '#document'); |
15 |
|
|
|
16 |
|
|
sub fws ($) { |
17 |
|
|
my $s = shift; |
18 |
|
|
while ($$s =~ m{\G(?=[#\s]|/[/\*])}gc) { |
19 |
|
|
if ($$s =~ /\G\s+/gc) { |
20 |
|
|
# |
21 |
|
|
} elsif ($$s =~ /\G\#(.+)(?:\n|$)/gc) { |
22 |
|
|
my $l = $1; |
23 |
|
|
my $m = $tree->get_attribute ('Module'); |
24 |
|
|
if ($l =~ /^include\s+"([^"]+)"/) { |
25 |
|
|
my $f = $1; |
26 |
|
|
my $c = $m->get_attribute ('Require', make_new_node => 1) |
27 |
|
|
->append_new_node (type => '#element', |
28 |
|
|
local_name => 'Module'); |
29 |
|
|
$c->set_attribute (Name => undef); |
30 |
|
|
$c->set_attribute (FileName => $f) |
31 |
|
|
->set_attribute (For => 'lang:IDL-DOM'); |
32 |
|
|
$f =~ s/\.idl$//; |
33 |
|
|
$c->set_attribute (Name => $f); |
34 |
|
|
$c->set_attribute (Namespace => q<:: TBD ::>); |
35 |
|
|
} elsif ($l =~ /^pragma\s+prefix\s+"([^"]+)"/) { |
36 |
|
|
$m->get_element_by (sub { |
37 |
|
|
my ($me, $you) = @_; |
38 |
|
|
$you->local_name eq 'BindingName' and |
39 |
|
|
$you->get_attribute_value ('Type', default => '') |
40 |
|
|
eq 'lang:IDL-DOM' |
41 |
|
|
}, make_new_node => sub { |
42 |
|
|
my ($me, $you) = @_; |
43 |
|
|
$you->local_name ('BindingName'); |
44 |
|
|
$you->set_attribute (Type => 'lang:IDL-DOM'); |
45 |
|
|
}) |
46 |
|
|
->set_attribute (prefix => $1); |
47 |
|
|
} else { |
48 |
|
|
$tree->append_new_node (type => '#comment', value => ' #'.$l); |
49 |
|
|
} |
50 |
|
|
} elsif ($$s =~ m#\G//\s*(\w+)\s*\n#gc) { |
51 |
|
|
$LastComment = $LastCategory = $1; |
52 |
|
|
} elsif ($$s =~ m#\G//(.+\n(?:\s*//.+\n)*)#gc) { |
53 |
|
|
$LastComment = $1; |
54 |
|
|
$LastComment =~ s#\n\s*//\s*# #g; |
55 |
|
|
$LastComment =~ s/^\s+//; |
56 |
|
|
$LastComment =~ s/\s+$//; |
57 |
|
|
if ($LastComment =~ /raises\s*(\([^()]+\)|[^()\s]+)\s+on\s+setting/) { |
58 |
|
|
my ($x, $t) = ($1, $2); |
59 |
|
|
if ($LastAttr) { |
60 |
|
|
raises \$x => $LastAttr, 'Set'; |
61 |
|
|
} else { |
62 |
|
|
warn "Unassociated attribute exception comment found: $LastComment"; |
63 |
|
|
} |
64 |
|
|
} |
65 |
|
|
if ($LastComment =~ /raises\s*(\([^()]+\)|[^()\s]+)\s+on\s+retrieval/) { |
66 |
|
|
my ($x, $t) = ($1, $2); |
67 |
|
|
if ($LastAttr) { |
68 |
|
|
raises \$x => $LastAttr, 'Get'; |
69 |
|
|
} else { |
70 |
|
|
warn "Unassociated attribute exception comment found: $LastComment"; |
71 |
|
|
} |
72 |
|
|
} |
73 |
|
|
} elsif ($$s =~ m#\G(/\*(?>(?!\*/).)*\*/)#gcs) { |
74 |
|
|
$tree->append_new_node (type => '#comment', value => $1); |
75 |
|
|
} else { |
76 |
|
|
err $s; |
77 |
|
|
} |
78 |
|
|
} |
79 |
|
|
} |
80 |
|
|
|
81 |
|
|
sub type ($) { |
82 |
|
|
my $s = shift; |
83 |
|
|
$$s =~ /\G($NAME)/gc or return 0; |
84 |
|
|
my $type = $1; |
85 |
|
|
if ($type eq 'unsigned' or $type eq 'signed') { |
86 |
|
|
fws $s; |
87 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
88 |
|
|
$type .= '-' . $1; |
89 |
|
|
if ($1 eq 'long' and $$s =~ /\G\s+long\b/gc) { |
90 |
|
|
$type .= '-long'; |
91 |
|
|
} |
92 |
|
|
} |
93 |
|
|
if ($type =~ /:/) { |
94 |
|
|
$type =~ s/::/:/; |
95 |
|
|
if ($type =~ /^([^:]+):/) { |
96 |
|
|
register_required_module (Name => $1); |
97 |
|
|
} |
98 |
|
|
} |
99 |
|
|
if ($type !~ /[^a-z-]/ and |
100 |
|
|
not {qw/attribute 1 readonly 1 in 1 const 1 void 1/}->{$type}) { |
101 |
|
|
$type = 'DOMMain:' . $type; |
102 |
|
|
} elsif ({DOMString => 1, Object => 1}->{$type}) { |
103 |
|
|
unless ($Status->{datatype_defined}->{$type}) { |
104 |
|
|
$type = 'DOMMain:' . $type; |
105 |
|
|
} |
106 |
|
|
} |
107 |
|
|
return $type; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
my $CONST = qr/^Constants|Types$|[oe]rs$|Values$|Options$|^Exception/; |
111 |
|
|
|
112 |
|
|
sub const ($$) { |
113 |
|
|
my ($s, $parent) = @_; |
114 |
|
|
if ($LastCategory or $LastComment =~ /$CONST/) { |
115 |
|
|
if ($parent->child_nodes->[-1] and |
116 |
|
|
$parent->child_nodes->[-1]->local_name eq 'ConstGroup' and |
117 |
|
|
($parent->child_nodes->[-1]->get_attribute_value ('Name', default => ' ') |
118 |
|
|
eq $LastCategory or |
119 |
|
|
$parent->child_nodes->[-1]->get_attribute_value ('FullName', |
120 |
|
|
default => ' ') |
121 |
|
|
eq $LastComment)) { |
122 |
|
|
$parent = $parent->child_nodes->[-1]; |
123 |
|
|
} elsif ($parent->child_nodes->[-1] and |
124 |
|
|
$parent->child_nodes->[-1]->local_name eq 'Exception') { |
125 |
|
|
$parent = $parent->child_nodes->[-1]; |
126 |
|
|
if ($parent->child_nodes->[-1] and |
127 |
|
|
$parent->child_nodes->[-1]->local_name eq 'ConstGroup' and |
128 |
|
|
($parent->child_nodes->[-1]->get_attribute_value ('Name', default => ' ') |
129 |
|
|
eq $LastCategory or |
130 |
|
|
$parent->child_nodes->[-1]->get_attribute_value ('FullName', |
131 |
|
|
default => ' ') |
132 |
|
|
eq $LastComment)) { |
133 |
|
|
$parent = $parent->child_nodes->[-1]; |
134 |
|
|
} else { |
135 |
|
|
$parent = $parent->append_new_node (type => '#element', local_name => 'ConstGroup'); |
136 |
|
|
if ($LastCategory) { |
137 |
|
|
$parent->set_attribute (Name => $LastCategory); |
138 |
|
|
} else { |
139 |
|
|
$parent->set_attribute (FullName => $LastComment) |
140 |
|
|
->set_attribute (lang => 'en'); |
141 |
|
|
} |
142 |
|
|
} |
143 |
|
|
} else { |
144 |
|
|
$parent = $parent->append_new_node (type => '#element', local_name => 'ConstGroup'); |
145 |
|
|
if ($LastCategory) { |
146 |
|
|
$parent->set_attribute (Name => $LastCategory); |
147 |
|
|
} else { |
148 |
|
|
$parent->set_attribute (FullName => $LastComment) |
149 |
|
|
->set_attribute (lang => 'en'); |
150 |
|
|
} |
151 |
|
|
} |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
fws $s; |
155 |
|
|
my $type = type $s or err $s; |
156 |
|
|
fws $s; |
157 |
|
|
if ($parent->node_type eq '#element' and |
158 |
|
|
$parent->local_name eq 'ConstGroup' and |
159 |
|
|
not $parent->get_attribute ('Type')) { |
160 |
|
|
$parent->set_attribute (Type => $type); |
161 |
|
|
} |
162 |
|
|
my $const = $parent->append_new_node (type => '#element', local_name => 'Const'); |
163 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
164 |
|
|
$const->set_attribute (Name => $1); |
165 |
|
|
$const->set_attribute (Type => $type); |
166 |
|
|
fws $s; |
167 |
|
|
$$s =~ /\G=/gc or err $s; |
168 |
|
|
fws $s; |
169 |
|
|
$$s =~ /\G([^\s;]+)/gc or err $s; |
170 |
|
|
$const->set_attribute (Value => $1); |
171 |
|
|
level $const; |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
sub idlname2name ($) { |
175 |
|
|
my $s = shift; |
176 |
|
|
$s =~ s/^_//; |
177 |
|
|
$s; |
178 |
|
|
} |
179 |
|
|
|
180 |
|
|
sub semicolon ($) { |
181 |
|
|
my $s = shift; |
182 |
|
|
$$s =~ /\G;/gc or return 0; |
183 |
|
|
$LastComment = '' unless $LastComment =~ /$CONST/; |
184 |
|
|
return 1; |
185 |
|
|
} |
186 |
|
|
|
187 |
|
|
sub clear_comment () { |
188 |
|
|
$LastComment = ''; |
189 |
|
|
$LastCategory = ''; |
190 |
|
|
} |
191 |
|
|
|
192 |
|
|
sub level ($) { |
193 |
|
|
my $n = shift; |
194 |
|
|
if ($LastComment =~ /Introduced in DOM Level (\d+)/) { |
195 |
|
|
my $l = $1; |
196 |
|
|
my $p = $n->get_attribute_value ('Level', default => [], as_array => 1); |
197 |
|
|
$n->set_attribute (Level => [@$p, $l]); |
198 |
|
|
$n->set_attribute (SpecLevel => [@$p, $l]); |
199 |
|
|
} elsif ($LastComment =~ /Modified in DOM Level (\d+)/) { |
200 |
|
|
my $l = $1; |
201 |
|
|
my $p = $n->get_attribute_value ('Level', default => [':: TBD ::'], |
202 |
|
|
as_array => 1); |
203 |
|
|
$n->set_attribute (Level => [@$p, $l]); |
204 |
|
|
$n->set_attribute (SpecLevel => [@$p, $l]); |
205 |
|
|
} |
206 |
|
|
} |
207 |
|
|
|
208 |
|
|
sub raises ($$$) { |
209 |
|
|
my ($s, $n, $nm) = @_; |
210 |
|
|
$$s =~ /\G\(/gc; |
211 |
|
|
fws $s; |
212 |
|
|
my $p = $n->get_attribute ($nm, make_new_node => 1); |
213 |
|
|
while ($$s =~ /\G($NAME)/gc) { |
214 |
|
|
my $name = $1; |
215 |
|
|
$name =~ s/::/:/g; |
216 |
|
|
$name = 'DOMCore:'.$name if $name eq 'DOMException' and |
217 |
|
|
not $Status->{datatype_defined}->{$name}; |
218 |
|
|
if ($name =~ /^([^:]+):/) { |
219 |
|
|
register_required_module (Name => $1); |
220 |
|
|
} |
221 |
|
|
for my $except ($p->append_new_node (type => '#element', |
222 |
|
|
local_name => 'Exception')) { |
223 |
|
|
$except->set_attribute (Name => '** TBD **'); |
224 |
|
|
$except->set_attribute (Type => $name); |
225 |
|
|
} |
226 |
|
|
fws $s; |
227 |
|
|
$$s =~ /\G,/gc; |
228 |
|
|
fws $s; |
229 |
|
|
} |
230 |
|
|
$$s =~ /\G\)/gc; |
231 |
|
|
return 1; |
232 |
|
|
} |
233 |
|
|
|
234 |
|
|
sub err ($) { |
235 |
|
|
use Carp; |
236 |
|
|
my $s = shift; |
237 |
|
|
print $tree->stringify; |
238 |
|
|
Carp::croak "Invalid input (either input is broken or struct not implemented found): ", |
239 |
|
|
substr $$s, pos $$s, 100; |
240 |
|
|
} |
241 |
|
|
|
242 |
|
|
sub register_required_module (%) { |
243 |
|
|
my %opt = @_; |
244 |
|
|
my $mod = $tree->get_attribute ('Module') |
245 |
|
|
->get_attribute ('Require', make_new_node => 1) |
246 |
|
|
->get_element_by (sub { |
247 |
|
|
my ($me, $you) = @_; |
248 |
|
|
$you->local_name eq 'Module' and |
249 |
|
|
$you->get_attribute_value ('Name', default => '') eq $opt{Name}; |
250 |
|
|
}, make_new_node => sub { |
251 |
|
|
my ($me, $you) = @_; |
252 |
|
|
$you->local_name ('Module'); |
253 |
|
|
$you->set_attribute (Name => $opt{Name}); |
254 |
|
|
}); |
255 |
|
|
$mod->set_attribute (Namespace => $opt{Namespace} || q<:: TBD ::>); |
256 |
|
|
if ($opt{PerlRequire}) { |
257 |
|
|
unless ($mod->get_element_by (sub { |
258 |
|
|
my ($me, $you) = @_; |
259 |
|
|
$you->local_name eq 'Def' and |
260 |
|
|
$you->get_attribute_value ('Type', default => '') eq q<lang:Perl>; |
261 |
|
|
})) { |
262 |
|
|
for ($mod->append_new_node (type => '#element', local_name => 'Def')) { |
263 |
|
|
$_->set_attribute (Type => q<lang:Perl>); |
264 |
|
|
$_->set_attribute (require => $opt{PerlRequire}); |
265 |
|
|
} |
266 |
|
|
} |
267 |
|
|
} |
268 |
|
|
} |
269 |
|
|
|
270 |
|
|
sub supply_incase ($$) { |
271 |
|
|
my ($type, $node) = @_; |
272 |
|
|
if ($type eq 'DOMMain:boolean') { |
273 |
|
|
for my $b ('true', 'false') { |
274 |
|
|
for ($node->append_new_node (type => '#element', |
275 |
|
|
local_name => 'InCase')) { |
276 |
|
|
$_->set_attribute (Value => $b); |
277 |
|
|
} |
278 |
|
|
} |
279 |
|
|
} |
280 |
|
|
} # supply_incase |
281 |
|
|
|
282 |
|
|
my $s; |
283 |
|
|
{ |
284 |
|
|
local $/ = undef; |
285 |
|
|
$s = \(<> or die "$0: $ARGV: $!"); |
286 |
|
|
} |
287 |
|
|
|
288 |
|
|
pos $$s = 0; |
289 |
|
|
|
290 |
|
|
for my $ns ($tree->get_attribute ('Namespace', make_new_node => 1)) { |
291 |
|
|
$ns->set_attribute (lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>); |
292 |
|
|
$ns->set_attribute (license => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/license#>); |
293 |
|
|
} |
294 |
|
|
|
295 |
|
|
for my $module ($tree->append_new_node (type => '#element', |
296 |
|
|
local_name => 'Module')) { |
297 |
|
|
$module->set_attribute (Name => q<## TBD ##>); |
298 |
|
|
$module->set_attribute (Namespace => q<:: TBD ::>); |
299 |
|
|
$module->set_attribute (BindingName => q<** TBD **>) |
300 |
|
|
->set_attribute (Type => q<lang:IDL-DOM>); |
301 |
|
|
for ($module->set_attribute (Author => undef)) { |
302 |
|
|
$_->set_attribute (FullName => q<** TBD **>); |
303 |
|
|
$_->set_attribute (Mail => q<** TBD **>); |
304 |
|
|
} |
305 |
|
|
$module->set_attribute (License => q<license:Perl+MPL>); |
306 |
|
|
$module->set_attribute ('Date.RCS' => q<$Date: 2004/09/27 12:11:53 $>); |
307 |
|
|
} |
308 |
|
|
|
309 |
|
|
fws $s; |
310 |
|
|
if ($$s =~ /\Gpragma\s+prefix\s+"([^"]+)"\s*/gc) { |
311 |
|
|
for ($tree->get_attribute ('Module') |
312 |
|
|
->get_element_by (sub { |
313 |
|
|
my ($me, $you) = @_; |
314 |
|
|
$you->local_name eq 'BindingName' and |
315 |
|
|
$you->get_attribute_value ('Type', default => '') eq 'lang:IDL-DOM'; |
316 |
|
|
}, make_new_node => sub { |
317 |
|
|
my ($me, $you) = @_; |
318 |
|
|
$you->local_name ('BindingName'); |
319 |
|
|
$you->set_attribute (Type => 'lang:IDL-DOM'); |
320 |
|
|
})) { |
321 |
|
|
$_->set_attribute (prefix => $1); |
322 |
|
|
$_->set_attribute (Type => 'lang:IDL-DOM'); |
323 |
|
|
} |
324 |
|
|
} |
325 |
|
|
if ($$s =~ /\Gmodule\b/gc) { |
326 |
|
|
fws $s; |
327 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
328 |
|
|
for ($tree->get_attribute ('Module')) { |
329 |
|
|
$_->get_element_by (sub { |
330 |
|
|
my ($me, $you) = @_; |
331 |
|
|
$you->local_name eq 'BindingName' and |
332 |
|
|
$you->get_attribute_value ('Type', default => '') eq 'lang:IDL-DOM'; |
333 |
|
|
}, make_new_node => sub { |
334 |
|
|
my ($me, $you) = @_; |
335 |
|
|
$you->local_name ('BindingName'); |
336 |
|
|
$you->set_attribute (Type => 'lang:IDL-DOM'); |
337 |
|
|
})->inner_text (new_value => $1); |
338 |
|
|
$_->set_attribute (Name => $1); |
339 |
|
|
} |
340 |
|
|
fws $s; |
341 |
|
|
$$s =~ /\G\{/gc; |
342 |
|
|
fws $s; |
343 |
|
|
} |
344 |
|
|
|
345 |
|
|
|
346 |
|
|
while (pos $$s < length $$s) { |
347 |
|
|
my $r = $tree; |
348 |
|
|
if ($$s =~ /\Ginterface\b/gc) { |
349 |
|
|
fws $s; |
350 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
351 |
|
|
my $name = $1; |
352 |
|
|
my @isa; |
353 |
|
|
fws $s; |
354 |
|
|
if ($$s =~ /\G:/gc) { |
355 |
|
|
fws $s; |
356 |
|
|
while ($$s =~ /\G($NAME)/gc) { |
357 |
|
|
my $name = $1; |
358 |
|
|
$name =~ s/::/:/g; |
359 |
|
|
if ($name =~ /^([^:]+):/) { |
360 |
|
|
register_required_module (Name => $1); |
361 |
|
|
} |
362 |
|
|
push @isa, $name; |
363 |
|
|
fws $s; |
364 |
|
|
$$s =~ /\G,/gc or last; |
365 |
|
|
fws $s; |
366 |
|
|
} |
367 |
|
|
} |
368 |
|
|
if ($$s =~ /\G\{/gc) { |
369 |
|
|
my $if = $r->append_new_node (type => '#element', local_name => 'IF'); |
370 |
|
|
$if->set_attribute (Name => $name); |
371 |
|
|
for (@isa) { |
372 |
|
|
$if->append_new_node (type => '#element', |
373 |
|
|
local_name => 'ISA', |
374 |
|
|
value => $_); |
375 |
|
|
} |
376 |
|
|
level $if; |
377 |
|
|
clear_comment; |
378 |
|
|
fws $s; |
379 |
|
|
while (my $type = type $s) { |
380 |
|
|
fws $s; |
381 |
|
|
if ($type eq 'attribute' or $type eq 'readonly') { |
382 |
|
|
my $attr = $LastAttr = $if->append_new_node (type => '#element', local_name => 'Attr'); |
383 |
|
|
my $readonly; |
384 |
|
|
if ($type eq 'readonly') { |
385 |
|
|
$$s =~ /\Gattribute\b/gc or err $s; |
386 |
|
|
fws $s; |
387 |
|
|
$readonly = 1; |
388 |
|
|
} |
389 |
|
|
$type = type $s or err $s; |
390 |
|
|
fws $s; |
391 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
392 |
|
|
$attr->set_attribute (Name => idlname2name $1); |
393 |
|
|
fws $s; |
394 |
|
|
$attr->get_attribute ('Get', make_new_node => 1) |
395 |
|
|
->set_attribute (Type => $type); |
396 |
|
|
$attr->get_attribute ('Set', make_new_node => 1) |
397 |
|
|
->set_attribute (Type => $type) unless $readonly; |
398 |
|
|
supply_incase ($type => $attr->get_attribute ('Get')); |
399 |
|
|
supply_incase ($type => $attr->get_attribute ('Set')) |
400 |
|
|
unless $readonly; |
401 |
|
|
level $attr; |
402 |
|
|
} elsif ($type eq 'const') { |
403 |
|
|
const $s => $if; |
404 |
|
|
fws $s; |
405 |
|
|
} else { |
406 |
|
|
my $method = $if->append_new_node (type => '#element', |
407 |
|
|
local_name => 'Method'); |
408 |
|
|
if ($$s =~ /\G($NAME)/gc) { |
409 |
|
|
$method->set_attribute (Name => idlname2name $1); |
410 |
|
|
} else { |
411 |
|
|
$method->set_attribute (Name => idlname2name $type); |
412 |
|
|
undef $type; |
413 |
|
|
} |
414 |
|
|
fws $s; |
415 |
|
|
$$s =~ /\G\(/gc or err $s; |
416 |
|
|
{ |
417 |
|
|
fws $s; |
418 |
|
|
my $type = type $s or last; |
419 |
|
|
fws $s; |
420 |
|
|
my $in; |
421 |
|
|
if ($type eq 'in') { |
422 |
|
|
$in = 1; |
423 |
|
|
$type = type $s or err $s; |
424 |
|
|
fws $s; |
425 |
|
|
} |
426 |
|
|
my $p = $method->append_new_node (type => '#element', local_name => 'Param'); |
427 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
428 |
|
|
$p->set_attribute (Name => idlname2name $1); |
429 |
|
|
$p->set_attribute (Type => $type); |
430 |
|
|
$p->set_attribute (Write => 0) unless $in; |
431 |
|
|
supply_incase ($type => $p); |
432 |
|
|
fws $s; |
433 |
|
|
$$s =~ /\G,/gc or last; |
434 |
|
|
redo; |
435 |
|
|
} |
436 |
|
|
$$s =~ /\G\)/gc or err $s; |
437 |
|
|
fws $s; |
438 |
|
|
|
439 |
|
|
my $return = $method->get_attribute ('Return', make_new_node => 1); |
440 |
|
|
if ($type and $type ne 'void') { |
441 |
|
|
$return->set_attribute (Type => $type); |
442 |
|
|
supply_incase ($type => $return); |
443 |
|
|
} |
444 |
|
|
if ($$s =~ /\Graises\b/gc) { |
445 |
|
|
raises $s => $method, 'Return' or err $s; |
446 |
|
|
fws $s; |
447 |
|
|
} |
448 |
|
|
level $method; |
449 |
|
|
} # attr or method |
450 |
|
|
semicolon $s or err $s; |
451 |
|
|
fws $s; |
452 |
|
|
} |
453 |
|
|
$$s =~ /\G\}/gc or err $s; |
454 |
|
|
} # definition |
455 |
|
|
fws $s; |
456 |
|
|
} elsif ($$s =~ /\Gconst\b/gc) { |
457 |
|
|
const $s => $r; |
458 |
|
|
fws $s; |
459 |
|
|
} elsif ($$s =~ /\Gexception\b/gc) { |
460 |
|
|
my $except = $r->append_new_node (type => '#element', local_name => 'Exception'); |
461 |
|
|
fws $s; |
462 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
463 |
|
|
$except->set_attribute (Name => $1); |
464 |
|
|
level $except; |
465 |
|
|
fws $s; |
466 |
|
|
$$s =~ /\G\{/gc or err $s; |
467 |
|
|
clear_comment; |
468 |
|
|
fws $s; |
469 |
|
|
while (my $type = type $s) { |
470 |
|
|
fws $s; |
471 |
|
|
my $attr = $except->append_new_node (type => '#element', local_name => 'Attr'); |
472 |
|
|
$$s =~ /\G($NAME)/gc or err $s; |
473 |
|
|
$attr->set_attribute (Name => idlname2name $1); |
474 |
|
|
$attr->get_attribute ('Get', make_new_node => 1) |
475 |
|
|
->set_attribute (Type => $type); |
476 |
|
|
fws $s; |
477 |
|
|
semicolon $s or err $s; |
478 |
|
|
fws $s; |
479 |
|
|
} |
480 |
|
|
$$s =~ /\G\}/gc or err $s; |
481 |
|
|
fws $s; |
482 |
|
|
} elsif ($$s =~ /\Gvaluetype\b/gc) { |
483 |
|
|
fws $s; |
484 |
|
|
my $valtype = $r->append_new_node (type => '#element', |
485 |
|
|
local_name => 'DataType'); |
486 |
|
|
my $type = type $s or err $s; |
487 |
|
|
$valtype->set_attribute (Name => $type); |
488 |
|
|
fws $s; |
489 |
|
|
$$s =~ /\G([^;]+)/gc or err $s; |
490 |
|
|
$valtype->set_attribute (Def => $1) |
491 |
|
|
->set_attribute (Type => q<lang:IDL-DOM>); |
492 |
|
|
fws $s; |
493 |
|
|
} elsif ($$s =~ /\Gtypedef\b/gc) { |
494 |
|
|
fws $s; |
495 |
|
|
my $type = type $s or err $s; |
496 |
|
|
fws $s; |
497 |
|
|
my $valtype = $r->append_new_node (type => '#element', |
498 |
|
|
local_name => 'DataTypeAlias'); |
499 |
|
|
my $name = $$s =~ /\G($NAME)/gc ? $1 : err $s; |
500 |
|
|
$valtype->set_attribute (Name => $name); |
501 |
|
|
$valtype->set_attribute (Type => $type); |
502 |
|
|
$Status->{datatype_defined}->{$name} = 1; |
503 |
|
|
fws $s; |
504 |
|
|
} else { |
505 |
|
|
last; |
506 |
|
|
} |
507 |
|
|
semicolon $s ;#or err $s; |
508 |
|
|
fws $s; |
509 |
|
|
} |
510 |
|
|
|
511 |
|
|
$$s =~ /\G\}/gc; # module name {...} |
512 |
|
|
fws $s; |
513 |
|
|
semicolon $s; |
514 |
|
|
fws $s; |
515 |
|
|
|
516 |
|
|
$$s =~ /\G./gc and err $s; |
517 |
|
|
|
518 |
|
|
print $tree->stringify; |