/[suikacvs]/messaging/manakai/bin/mkdisdump.pl
Suika

Contents of /messaging/manakai/bin/mkdisdump.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations) (download)
Sat Oct 1 12:14:29 2005 UTC (19 years, 1 month ago) by wakaba
Branch: MAIN
Changes since 1.12: +124 -31 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	1 Oct 2005 12:10:57 -0000
2005-10-01  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl (append_document_properties): New subroutine.
	(append_datatype_documentation): Outputs "dis:Def"
	and "dis:AppName" properties if available.
	(append_idl_interface_documentation): New subroutine.

++ manakai/lib/Message/Util/DIS/ChangeLog	1 Oct 2005 12:13:22 -0000
2005-10-01  Wakaba  <wakaba@suika.fam.cx>

	* Perl.dis (plLoadDISDatabaseModule): Accepts unknown module
	definitions.

++ manakai/lib/Message/DOM/ChangeLog	1 Oct 2005 12:12:31 -0000
2005-10-01  Wakaba  <wakaba@suika.fam.cx>

	* DOMFeature.dis: Documentation added (still work in progress).
	(MIString): New type.

	* DOMCore.dis (namespaceURI): Fixed to return the namespace
	URI value, not a reference to it.

++ manakai/lib/manakai/ChangeLog	1 Oct 2005 12:14:17 -0000
2005-10-01  Wakaba  <wakaba@suika.fam.cx>

	* DISIDL.dis: Missing properties added.  IDL name
	added to IDL data types.

	* Document.dis (doc:rel): New property.

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3    
4     =head1 NAME
5    
6 wakaba 1.5 mkdisdump.pl - Generating Perl Module Documentation Source
7 wakaba 1.1
8     =head1 SYNOPSIS
9    
10 wakaba 1.5 perl path/to/mkdisdump.pl input.cdis \
11 wakaba 1.1 {--module-name=ModuleName | --module-uri=module-uri} \
12     [--for=for-uri] [options] > ModuleName.pm
13     perl path/to/cdis2pm.pl --help
14    
15     =head1 DESCRIPTION
16    
17     The C<cdis2pm> script generates a Perl module from a compiled "dis"
18     ("cdis") file. It is intended to be used to generate a manakai
19     DOM Perl module files, although it might be useful for other purpose.
20    
21     This script is part of manakai.
22    
23     =cut
24    
25     use Message::Util::QName::Filter {
26 wakaba 1.3 ddel => q<http://suika.fam.cx/~wakaba/archive/2005/disdoc#>,
27 wakaba 1.1 ddoct => q<http://suika.fam.cx/~wakaba/archive/2005/8/disdump-xslt#>,
28     DIS => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#>,
29     dis => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
30     dis2pm => q<http://suika.fam.cx/~wakaba/archive/2004/11/8/dis2pm#>,
31     DISCore => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Core#>,
32     DISLang => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Lang#>,
33     DISPerl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Perl#>,
34 wakaba 1.12 doc => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Document#>,
35 wakaba 1.1 DOMLS => q<http://suika.fam.cx/~wakaba/archive/2004/dom/ls#>,
36     dump => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#DISDump/>,
37 wakaba 1.8 dx => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException#>,
38 wakaba 1.5 ecore => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/>,
39 wakaba 1.13 idl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/IDL#>,
40 wakaba 1.3 infoset => q<http://www.w3.org/2001/04/infoset#>,
41 wakaba 1.12 lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>,
42 wakaba 1.1 ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
43     Markup => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Markup#>,
44     Util => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/>,
45     xml => q<http://www.w3.org/XML/1998/namespace>,
46 wakaba 1.3 xmlns => q<http://www.w3.org/2000/xmlns/>,
47 wakaba 1.1 };
48    
49     =head1 OPTIONS
50    
51     =over 4
52    
53     =item --for=I<for-uri> (Optional)
54    
55     Specifies the "For" URI reference for which the outputed module is.
56     If this parameter is ommitted, the default "For" URI reference
57     for the module, if any, or the C<ManakaiDOM:all> is assumed.
58    
59     =item --help
60    
61     Shows the help message.
62    
63     =item --module-uri=I<module-uri>
64    
65     A URI reference that identifies a module to output. Either
66     C<--module-name> or C<--module-uri> is required.
67    
68 wakaba 1.5 =item --verbose / --noverbose (default)
69 wakaba 1.1
70 wakaba 1.5 Whether a verbose message mode should be selected or not.
71 wakaba 1.1
72 wakaba 1.5 =item --with-implementators-note / --nowith-implementators-note (default)
73 wakaba 1.1
74 wakaba 1.5 Whether the implemetator's notes should also be included
75     in the result or not.
76 wakaba 1.1
77     =back
78    
79     =cut
80    
81     use Getopt::Long;
82     use Pod::Usage;
83     use Storable;
84     use Message::Util::Error;
85 wakaba 1.4 my %Opt = (
86     module_uri => {},
87 wakaba 1.12 resource_uri => {},
88 wakaba 1.4 );
89 wakaba 1.1 GetOptions (
90 wakaba 1.8 'debug' => \$Opt{debug},
91 wakaba 1.10 'dis-file-suffix=s' => \$Opt{dis_suffix},
92     'daem-file-suffix=s' => \$Opt{daem_suffix},
93 wakaba 1.1 'for=s' => \$Opt{For},
94     'help' => \$Opt{help},
95 wakaba 1.4 'module-uri=s' => sub {
96     shift;
97 wakaba 1.12 my ($nuri, $furi) = split /\s+/, shift, 2;
98     $furi ||= '';
99     $Opt{module_uri}->{$nuri}->{$furi} = 1;
100     },
101     'resource-uri=s' => sub {
102     shift;
103     my ($nuri, $furi) = split /\s+/, shift, 2;
104     $furi ||= '';
105     $Opt{resource_uri}->{$nuri}->{$furi} = 1;
106 wakaba 1.4 },
107 wakaba 1.10 'search-path|I=s' => sub {
108     shift;
109     my @value = split /\s+/, shift;
110     while (my ($ns, $path) = splice @value, 0, 2, ()) {
111     unless (defined $path) {
112     die qq[$0: Search-path parameter without path: "$ns"];
113     }
114     push @{$Opt{input_search_path}->{$ns} ||= []}, $path;
115     }
116     },
117     'search-path-catalog-file-name=s' => sub {
118     shift;
119     require File::Spec;
120     my $path = my $path_base = shift;
121     $path_base =~ s#[^/]+$##;
122     $Opt{search_path_base} = $path_base;
123     open my $file, '<', $path or die "$0: $path: $!";
124     while (<$file>) {
125     if (s/^\s*\@//) { ## Processing instruction
126     my ($target, $data) = split /\s+/;
127     if ($target eq 'base') {
128     $Opt{search_path_base} = File::Spec->rel2abs ($data, $path_base);
129     } else {
130     die "$0: $target: Unknown target";
131     }
132     } elsif (/^\s*\#/) { ## Comment
133     #
134     } elsif (/\S/) { ## Catalog entry
135     s/^\s+//;
136     my ($ns, $path) = split /\s+/;
137     push @{$Opt{input_search_path}->{$ns} ||= []},
138     File::Spec->rel2abs ($path, $Opt{search_path_base});
139     }
140     }
141     ## NOTE: File paths with SPACEs are not supported
142     ## NOTE: Future version might use file: URI instead of file path.
143     },
144 wakaba 1.5 'with-implementators-note' => \$Opt{with_impl_note},
145 wakaba 1.10 'verbose!' => \$Opt{verbose},
146 wakaba 1.1 ) or pod2usage (2);
147     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
148     $Opt{file_name} = shift;
149     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
150 wakaba 1.12 pod2usage (2) unless (keys %{$Opt{module_uri}}) + (keys %{$Opt{resource_uri}});
151 wakaba 1.8 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
152 wakaba 1.10 $Opt{dis_suffix} = '.dis' unless defined $Opt{dis_suffix};
153     $Opt{daem_suffix} = '.daem' unless defined $Opt{daem_suffix};
154 wakaba 1.1
155     sub status_msg ($) {
156     my $s = shift;
157     $s .= "\n" unless $s =~ /\n$/;
158     print STDERR $s;
159     }
160    
161     sub status_msg_ ($) {
162     my $s = shift;
163     print STDERR $s;
164     }
165    
166     sub verbose_msg ($) {
167     my $s = shift;
168     $s .= "\n" unless $s =~ /\n$/;
169 wakaba 1.10 print STDERR $s if $Opt{verbose};
170 wakaba 1.1 }
171    
172     sub verbose_msg_ ($) {
173     my $s = shift;
174 wakaba 1.10 print STDERR $s if $Opt{verbose};
175 wakaba 1.1 }
176    
177 wakaba 1.7 {
178     my $ResourceCount = 0;
179 wakaba 1.8 sub progress_inc (;$) {
180     $ResourceCount += (shift || 1);
181     if (($ResourceCount % 10) == 0) {
182 wakaba 1.7 print STDERR "*";
183     print STDERR " " if ($ResourceCount % (10 * 10)) == 0;
184     print STDERR "\n" if ($ResourceCount % (10 * 50)) == 0;
185     }
186     }
187    
188     sub progress_reset () {
189     $ResourceCount = 0;
190     }
191     }
192    
193 wakaba 1.8 my $start_time;
194     BEGIN { $start_time = time }
195    
196     use Message::DOM::GenericLS;
197     use Message::DOM::SimpleLS;
198     use Message::Util::DIS::DISDump;
199 wakaba 1.12 use Message::Util::DIS::DISDoc;
200 wakaba 1.8 use Message::Util::DIS::DNLite;
201    
202 wakaba 1.5 my $impl = $Message::DOM::ImplementationRegistry->get_implementation
203 wakaba 1.1 ({
204     ExpandedURI q<ManakaiDOM:Minimum> => '3.0',
205     '+' . ExpandedURI q<DOMLS:LS> => '3.0',
206     '+' . ExpandedURI q<DIS:Doc> => '2.0',
207 wakaba 1.8 '+' . ExpandedURI q<DIS:DNLite> => '1.0',
208 wakaba 1.1 ExpandedURI q<DIS:Dump> => '1.0',
209     });
210    
211     ## -- Load input dac database file
212     status_msg_ qq<Opening dac file "$Opt{file_name}"...>;
213 wakaba 1.8 our $db = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0')
214 wakaba 1.10 ->pl_load_dis_database ($Opt{file_name}, sub ($$) {
215     my ($db, $mod) = @_;
216     my $ns = $mod->namespace_uri;
217     my $ln = $mod->local_name;
218     verbose_msg qq<Database module <$ns$ln> is requested>;
219     my $name = dac_search_file_path_stem ($ns, $ln, $Opt{daem_suffix});
220     if (defined $name) {
221     return $name.$Opt{daem_suffix};
222     } else {
223     return $ln.$Opt{daem_suffix};
224     }
225     });
226 wakaba 1.1 status_msg qq<done\n>;
227    
228 wakaba 1.2 our %ReferredResource;
229 wakaba 1.5 our %ClassMembers;
230     our %ClassInheritance;
231     our @ClassInheritance;
232     our %ClassImplements;
233 wakaba 1.2
234 wakaba 1.12 sub append_module_group_documentation (%) {
235     my %opt = @_;
236     my $section = $opt{result_parent}
237     ->append_child ($opt{result_parent}->owner_document
238     ->create_element_ns (ExpandedURI q<dump:>, 'moduleGroup'));
239    
240     add_uri ($opt{source_resource} => $section);
241    
242     my $path = $opt{source_resource}->get_property_text
243     (ExpandedURI q<dis:FileName>,
244     $opt{source_resource}->local_name);
245     $section->resource_file_path_stem ($path);
246    
247     $section->set_attribute_ns
248     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
249    
250     append_description (source_resource => $opt{source_resource},
251     result_parent => $section,
252     has_label => 1);
253    
254     ## -- Member modules
255    
256     for my $rres (@{$opt{source_resource}->get_property_module_list
257     (ExpandedURI q<DISCore:module>)}) {
258     $Opt{module_uri}->{$rres->name_uri}->{$rres->for_uri} = 1;
259     my $mod_el = $section->append_child
260     ($section->owner_document
261     ->create_element_ns (ExpandedURI q<dump:>, 'module'));
262     $mod_el->ref ($rres->uri);
263     }
264    
265     ## -- Member resources
266    
267     for my $rres (@{$opt{source_resource}->get_property_resource_list
268     (ExpandedURI q<DISCore:resource>)}) {
269     progress_inc;
270     if ($rres->is_type_uri (ExpandedURI q<doc:Document>)) {
271     append_document_documentation (source_resource => $rres,
272     result_parent => $section);
273     } else {
274     #
275     }
276     }
277     status_msg "";
278     } # append_module_group_documentation
279    
280     sub append_document_documentation (%) {
281     my %opt = @_;
282     my $section = $opt{result_parent}
283     ->append_child ($opt{result_parent}->owner_document
284     ->create_element_ns (ExpandedURI q<dump:>, 'document'));
285     my $od = $section->owner_document;
286    
287     add_uri ($opt{source_resource} => $section);
288    
289     my $path = $opt{source_resource}->get_property_text
290     (ExpandedURI q<dis:FileName>,
291     lcfirst $opt{source_resource}->local_name);
292     $section->resource_file_path_stem ($path);
293    
294     $section->set_attribute_ns
295     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
296    
297 wakaba 1.13 if ($opt{source_resource}->is_type_uri (ExpandedURI q<doc:Document>)) {
298     $section->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
299     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri',
300     ExpandedURI q<doc:Document>);
301     }
302 wakaba 1.12
303     ## TODO: Conneg
304     for my $con (@{$opt{source_resource}->get_property_value_list
305     (ExpandedURI q<doc:content>)}) {
306     my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
307     my $tree = $cond->get_disdoc_tree
308     ($od, ExpandedURI q<lang:disdoc>,
309     $opt{source_resource}->database,
310     default_name_uri => $opt{source_resource}->source_node_id,
311     default_for_uri => $opt{source_resource}->for_uri);
312     $section
313     ->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'content'))
314     ->append_child (transform_disdoc_tree ($tree));
315     }
316    
317 wakaba 1.13 append_document_properties
318     (source_resource => $opt{source_resource},
319     result_parent => $section);
320 wakaba 1.12
321     for my $v (@{$opt{source_resource}->get_property_value_list
322     (ExpandedURI q<doc:part>)}) {
323     my $res = $v->get_resource ($opt{source_resource}->database);
324     $ReferredResource{$res->uri} ||= 1;
325     my $doc = $section->append_child
326     ($od->create_element_ns (ExpandedURI q<dump:>, 'document'));
327     $doc->ref ($res->uri);
328 wakaba 1.13 for my $vv (@{$v->get_property (ExpandedURI q<doc:rel>)||[]}) {
329     $doc->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
330     ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $vv->uri);
331     }
332 wakaba 1.12 }
333     } # append_document_documentation
334    
335 wakaba 1.1 sub append_module_documentation (%) {
336     my %opt = @_;
337     my $section = $opt{result_parent}->create_module ($opt{source_resource}->uri);
338 wakaba 1.2
339     add_uri ($opt{source_resource} => $section);
340 wakaba 1.1
341     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
342     if (defined $pl_full_name) {
343     $section->perl_package_name ($pl_full_name);
344 wakaba 1.5
345     my $path = $opt{source_resource}->get_property_text
346     (ExpandedURI q<dis:FileName>, $pl_full_name);
347 wakaba 1.1 $path =~ s#::#/#g;
348     $section->resource_file_path_stem ($path);
349 wakaba 1.5
350 wakaba 1.1 $section->set_attribute_ns
351     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
352 wakaba 1.2 $pl_full_name =~ s/.*:://g;
353     $section->perl_name ($pl_full_name);
354 wakaba 1.1 }
355    
356     append_description (source_resource => $opt{source_resource},
357     result_parent => $section);
358    
359 wakaba 1.2 if ($opt{is_partial}) {
360     $section->resource_is_partial (1);
361     return;
362     }
363    
364 wakaba 1.11 for my $rres (@{$opt{source_resource}->get_resource_list}) {
365 wakaba 1.4 if ($rres->owner_module eq $opt{source_resource} and## Defined in this module
366     not ($ReferredResource{$rres->uri} < 0)) {
367 wakaba 1.1 ## TODO: Modification required to support modplans
368 wakaba 1.7 progress_inc;
369 wakaba 1.8 if ($rres->is_type_uri (ExpandedURI q<DISLang:Class>)) {
370 wakaba 1.1 append_class_documentation
371     (result_parent => $section,
372     source_resource => $rres);
373 wakaba 1.8 } elsif ($rres->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
374 wakaba 1.1 append_interface_documentation
375     (result_parent => $section,
376     source_resource => $rres);
377 wakaba 1.12 } elsif ($rres->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
378 wakaba 1.3 append_datatype_documentation
379     (result_parent => $section,
380     source_resource => $rres);
381 wakaba 1.1 }
382     } else { ## Aliases
383     #
384     }
385     }
386 wakaba 1.2 status_msg "";
387 wakaba 1.1 } # append_module_documentation
388    
389 wakaba 1.3 sub append_datatype_documentation (%) {
390     my %opt = @_;
391 wakaba 1.13 my $od = $opt{result_parent}->owner_document;
392     my $section = $opt{result_parent}->can ('create_data_type')
393     ? $opt{result_parent}->create_data_type
394     ($opt{source_resource}->uri)
395     : $opt{result_parent}->append_child
396     ($od->create_element_ns
397     (ExpandedURI q<dump:>, 'dataType'));
398 wakaba 1.3
399     add_uri ($opt{source_resource} => $section);
400    
401 wakaba 1.4 my $uri = $opt{source_resource}->name_uri;
402     if ($uri) {
403     my $fu = $opt{source_resource}->for_uri;
404     unless ($fu eq ExpandedURI q<ManakaiDOM:all>) {
405     $fu =~ /([\w.-]+)[^\w.-]*$/;
406     $uri .= '-' . $1;
407     }
408     } else {
409     $opt{source_resource}->uri;
410     }
411     $uri =~ s#\b(\d\d\d\d+)/(\d\d?)/(\d\d?)#sprintf '%04d%02d%02d', $1, $2, $3#ge;
412     my @file = map {s/[^\w-]/_/g; $_} split m{[/:#?]+}, $uri;
413 wakaba 1.3
414     $section->resource_file_path_stem (join '/', @file);
415 wakaba 1.5 $section->set_attribute_ns
416     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x (@file - 1));
417 wakaba 1.3
418 wakaba 1.13 for my $con (@{$opt{source_resource}->get_property_value_list
419     (ExpandedURI q<dis:AppName>)},
420     @{$opt{source_resource}->get_property_value_list
421     (ExpandedURI q<dis:Def>)}) {
422     my $ns = $con->name;
423     my $ln = $1 if ($ns =~ s/(\w+)$//);
424     $section->append_child ($od->create_element_ns ($ns, $ln))
425     ->text_content ($con->string_value);
426     if ($con->isa ('Message::Util::IF::DVURIValue')) {
427     $ReferredResource{$con->uri} ||= 1;
428     }
429     }
430    
431     append_document_properties
432     (source_resource => $opt{source_resource},
433     result_parent => $section);
434    
435 wakaba 1.3 append_description (source_resource => $opt{source_resource},
436 wakaba 1.12 result_parent => $section,
437     has_label => 1);
438 wakaba 1.3
439     if ($opt{is_partial}) {
440     $section->resource_is_partial (1);
441     return;
442     }
443    
444 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
445     result_parent => $section);
446 wakaba 1.3 } # append_datatype_documentation
447    
448 wakaba 1.1 sub append_interface_documentation (%) {
449     my %opt = @_;
450     my $section = $opt{result_parent}->create_interface
451 wakaba 1.5 (my $class_uri = $opt{source_resource}->uri);
452     push @ClassInheritance, $class_uri;
453 wakaba 1.2
454     add_uri ($opt{source_resource} => $section);
455 wakaba 1.1
456     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
457     if (defined $pl_full_name) {
458     $section->perl_package_name ($pl_full_name);
459 wakaba 1.5
460     my $path = $opt{source_resource}->get_property_text
461     (ExpandedURI q<dis:FileName>, $pl_full_name);
462 wakaba 1.1 $path =~ s#::#/#g;
463     $section->resource_file_path_stem ($path);
464 wakaba 1.5
465 wakaba 1.1 $section->set_attribute_ns
466     (ExpandedURI q<ddoct:>, 'ddoct:basePath',
467     join '', '../' x ($path =~ tr#/#/#));
468 wakaba 1.2 $pl_full_name =~ s/.*:://g;
469     $section->perl_name ($pl_full_name);
470 wakaba 1.1 }
471    
472     $section->is_exception_interface (1)
473 wakaba 1.8 if $opt{source_resource}->is_type_uri (ExpandedURI q<dx:Interface>);
474 wakaba 1.1
475     append_description (source_resource => $opt{source_resource},
476     result_parent => $section);
477    
478 wakaba 1.2 if ($opt{is_partial}) {
479     $section->resource_is_partial (1);
480     }
481    
482 wakaba 1.11 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
483 wakaba 1.1 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
484     append_method_documentation (source_resource => $memres,
485 wakaba 1.5 result_parent => $section,
486 wakaba 1.12 class_uri => $class_uri,
487     is_partial => $opt{is_partial});
488 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
489     append_attr_documentation (source_resource => $memres,
490 wakaba 1.5 result_parent => $section,
491 wakaba 1.12 class_uri => $class_uri,
492     is_partial => $opt{is_partial});
493 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
494 wakaba 1.3 append_constgroup_documentation (source_resource => $memres,
495 wakaba 1.5 result_parent => $section,
496 wakaba 1.12 class_uri => $class_uri,
497     is_partial => $opt{is_partial});
498 wakaba 1.1 }
499     }
500 wakaba 1.12
501     return if $opt{is_partial};
502    
503     ## Inheritance
504     append_inheritance (source_resource => $opt{source_resource},
505     result_parent => $section,
506     class_uri => $class_uri);
507    
508 wakaba 1.1 } # append_interface_documentation
509    
510 wakaba 1.13 sub append_idl_interface_documentation (%) {
511     my %opt = @_;
512     my $section = $opt{result_parent}->append_child
513     ($opt{result_parent}->owner_document->create_element_ns
514     (ExpandedURI q<dump:>, 'interface'));
515    
516     add_uri ($opt{source_resource} => $section);
517    
518     my $path = $opt{source_resource}->get_property_text
519     (ExpandedURI q<dis:FileName>,
520     $opt{source_resource}->local_name);
521     $path =~ s#::#/#g;
522     $section->resource_file_path_stem ($path);
523    
524     $section->set_attribute_ns
525     (ExpandedURI q<ddoct:>, 'ddoct:basePath',
526     join '', '../' x ($path =~ tr#/#/#));
527    
528     $section->is_exception_interface (1)
529     if $opt{source_resource}->is_type_uri (ExpandedURI q<idl:Exception>);
530    
531     append_description (source_resource => $opt{source_resource},
532     result_parent => $section);
533    
534     for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
535     if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
536     append_method_documentation (source_resource => $memres,
537     result_parent => $section);
538     } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
539     append_attr_documentation (source_resource => $memres,
540     result_parent => $section);
541     } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
542     append_constgroup_documentation (source_resource => $memres,
543     result_parent => $section);
544     }
545     }
546    
547     ## Inheritance
548     append_inheritance (source_resource => $opt{source_resource},
549     result_parent => $section,
550     target => 'idl');
551    
552     $ReferredResource{ExpandedURI q<idl:void>} ||= 1;
553     } # append_idl_interface_documentation
554    
555 wakaba 1.1 sub append_class_documentation (%) {
556     my %opt = @_;
557 wakaba 1.5 my $section = $opt{result_parent}->create_class
558     (my $class_uri = $opt{source_resource}->uri);
559     push @ClassInheritance, $class_uri;
560 wakaba 1.2
561     add_uri ($opt{source_resource} => $section);
562 wakaba 1.1
563     my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
564     if (defined $pl_full_name) {
565     $section->perl_package_name ($pl_full_name);
566 wakaba 1.5
567     my $path = $opt{source_resource}->get_property_text
568     (ExpandedURI q<dis:FileName>, $pl_full_name);
569 wakaba 1.1 $path =~ s#::#/#g;
570 wakaba 1.5
571 wakaba 1.1 $section->resource_file_path_stem ($path);
572     $section->set_attribute_ns
573     (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
574 wakaba 1.2 $pl_full_name =~ s/.*:://g;
575     $section->perl_name ($pl_full_name);
576 wakaba 1.1 }
577    
578     append_description (source_resource => $opt{source_resource},
579     result_parent => $section);
580    
581 wakaba 1.2 if ($opt{is_partial}) {
582     $section->resource_is_partial (1);
583     }
584    
585 wakaba 1.5 my $has_const = 0;
586 wakaba 1.11 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
587 wakaba 1.1 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
588     append_method_documentation (source_resource => $memres,
589 wakaba 1.5 result_parent => $section,
590 wakaba 1.12 class_uri => $class_uri,
591     is_partial => $opt{is_partial});
592 wakaba 1.1 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
593     append_attr_documentation (source_resource => $memres,
594 wakaba 1.5 result_parent => $section,
595 wakaba 1.12 class_uri => $class_uri,
596     is_partial => $opt{is_partial});
597 wakaba 1.8 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
598 wakaba 1.5 $has_const = 1;
599 wakaba 1.3 append_constgroup_documentation
600     (source_resource => $memres,
601 wakaba 1.5 result_parent => $section,
602 wakaba 1.12 class_uri => $class_uri,
603     is_partial => $opt{is_partial});
604 wakaba 1.1 }
605     }
606 wakaba 1.5
607 wakaba 1.12 return if $opt{is_partial};
608    
609 wakaba 1.5 ## Inheritance
610     append_inheritance (source_resource => $opt{source_resource},
611     result_parent => $section,
612     append_implements => 1,
613     class_uri => $class_uri,
614     has_const => $has_const,
615     is_class => 1);
616    
617 wakaba 1.1 } # append_class_documentation
618    
619     sub append_method_documentation (%) {
620     my %opt = @_;
621     my $perl_name = $opt{source_resource}->pl_name;
622     my $m;
623     if (defined $perl_name) {
624     $m = $opt{result_parent}->create_method ($perl_name);
625 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
626     = {
627     resource => $opt{source_resource},
628     type => 'method',
629     };
630 wakaba 1.1
631     } else { ## Anonymous
632     ## TODO
633     return;
634     }
635 wakaba 1.2
636     add_uri ($opt{source_resource} => $m);
637 wakaba 1.1
638     append_description (source_resource => $opt{source_resource},
639 wakaba 1.4 result_parent => $m,
640     method_resource => $opt{source_resource});
641 wakaba 1.1
642 wakaba 1.12 $m->resource_access ('private')
643     if $opt{source_resource}->get_property_boolean
644     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
645    
646     if ($opt{is_partial}) {
647     $m->resource_is_partial (1);
648     return;
649     }
650    
651 wakaba 1.1 my $ret = $opt{source_resource}->get_child_resource_by_type
652     (ExpandedURI q<DISLang:MethodReturn>);
653     if ($ret) {
654     my $r = $m->dis_return;
655    
656     try {
657 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
658     $ReferredResource{$u} ||= 1;
659     $r->resource_actual_data_type
660     ($u = $ret->dis_actual_data_type_resource->uri);
661     $ReferredResource{$u} ||= 1;
662    
663 wakaba 1.1 ## TODO: Exceptions
664     } catch Message::Util::DIS::ManakaiDISException with {
665    
666     };
667 wakaba 1.4
668     append_description (source_resource => $ret,
669     result_parent => $r,
670     has_case => 1,
671     method_resource => $opt{source_resource});
672 wakaba 1.5
673     append_raises (source_resource => $ret,
674     result_parent => $r,
675     method_resource => $opt{source_resource});
676 wakaba 1.1 }
677    
678 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
679 wakaba 1.1 if ($cr->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
680     append_param_documentation (source_resource => $cr,
681 wakaba 1.4 result_parent => $m,
682     method_resource => $opt{source_resource});
683 wakaba 1.1 }
684     }
685     } # append_method_documentation
686    
687     sub append_attr_documentation (%) {
688     my %opt = @_;
689     my $perl_name = $opt{source_resource}->pl_name;
690     my $m;
691     if (defined $perl_name) {
692     $m = $opt{result_parent}->create_attribute ($perl_name);
693 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
694     = {
695     resource => $opt{source_resource},
696     type => 'attr',
697     };
698 wakaba 1.1
699     } else { ## Anonymous
700     ## TODO
701     return;
702     }
703 wakaba 1.2
704     add_uri ($opt{source_resource} => $m);
705 wakaba 1.12
706     $m->resource_access ('private')
707     if $opt{source_resource}->get_property_boolean
708     (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
709    
710     if ($opt{is_partial}) {
711     $m->resource_is_partial (1);
712     $m->is_read_only_attribute (1)
713     if $opt{source_resource}->get_child_resource_by_type
714     (ExpandedURI q<DISLang:AttributeSet>);
715     return;
716     }
717 wakaba 1.1
718     append_description (source_resource => $opt{source_resource},
719     result_parent => $m,
720     has_case => 1);
721    
722     my $ret = $opt{source_resource}->get_child_resource_by_type
723     (ExpandedURI q<DISLang:AttributeGet>);
724     if ($ret) {
725     my $r = $m->dis_get;
726    
727 wakaba 1.2 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
728     $ReferredResource{$u} ||= 1;
729     $r->resource_actual_data_type
730     ($u = $ret->dis_actual_data_type_resource->uri);
731     $ReferredResource{$u} ||= 1;
732    
733 wakaba 1.1 append_description (source_resource => $ret,
734     result_parent => $r,
735     has_case => 1);
736    
737 wakaba 1.5 append_raises (source_resource => $ret,
738     result_parent => $r);
739 wakaba 1.1 }
740    
741     my $set = $opt{source_resource}->get_child_resource_by_type
742     (ExpandedURI q<DISLang:AttributeSet>);
743     if ($set) {
744     my $r = $m->dis_set;
745    
746 wakaba 1.2 $r->resource_data_type (my $u = $set->dis_data_type_resource->uri);
747     $ReferredResource{$u} ||= 1;
748 wakaba 1.1 $r->resource_actual_data_type ($set->dis_actual_data_type_resource->uri);
749 wakaba 1.2 $ReferredResource{$u} ||= 1;
750 wakaba 1.1
751     append_description (source_resource => $set,
752     result_parent => $r,
753     has_case => 1);
754    
755 wakaba 1.5 append_raises (source_resource => $set,
756     result_parent => $r);
757 wakaba 1.1 } else {
758     $m->is_read_only_attribute (1);
759     }
760     } # append_attr_documentation
761    
762 wakaba 1.3 sub append_constgroup_documentation (%) {
763     my %opt = @_;
764     my $perl_name = $opt{source_resource}->pl_name;
765     my $m = $opt{result_parent}->create_const_group ($perl_name);
766 wakaba 1.5 $ClassMembers{$opt{class_uri}}->{$perl_name}
767     = {
768     resource => $opt{source_resource},
769     type => 'const-group',
770     };
771 wakaba 1.3
772     add_uri ($opt{source_resource} => $m);
773 wakaba 1.12
774     if ($opt{is_partial}) {
775     $m->resource_is_partial (1);
776     return;
777     }
778 wakaba 1.3
779     append_description (source_resource => $opt{source_resource},
780     result_parent => $m);
781    
782     $m->resource_data_type
783     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
784     $ReferredResource{$u} ||= 1;
785     $m->resource_actual_data_type
786     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
787     $ReferredResource{$u} ||= 1;
788    
789 wakaba 1.5 append_subclassof (source_resource => $opt{source_resource},
790     result_parent => $m);
791 wakaba 1.3
792 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
793 wakaba 1.3 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:Const>)) {
794     append_const_documentation (source_resource => $cr,
795     result_parent => $m);
796     }
797     }
798     } # append_constgroup_documentation
799    
800     sub append_const_documentation (%) {
801     my %opt = @_;
802     my $perl_name = $opt{source_resource}->pl_name;
803     my $m = $opt{result_parent}->create_const ($perl_name);
804    
805     add_uri ($opt{source_resource} => $m);
806    
807     append_description (source_resource => $opt{source_resource},
808     result_parent => $m);
809    
810     $m->resource_data_type
811     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
812     $ReferredResource{$u} ||= 1;
813     $m->resource_actual_data_type
814     ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
815     $ReferredResource{$u} ||= 1;
816    
817     my $value = $opt{source_resource}->pl_code_fragment;
818     if ($value) {
819     $m->create_value->text_content ($value->stringify);
820     }
821    
822 wakaba 1.11 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
823 wakaba 1.3 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
824     append_xsubtype_documentation (source_resource => $cr,
825     result_parent => $m);
826     }
827     }
828     ## TODO: xparam
829     } # append_const_documentation
830    
831     sub append_xsubtype_documentation (%) {
832     my %opt = @_;
833     my $m = $opt{result_parent}->create_exception_sub_code
834     ($opt{source_resource}->uri);
835     add_uri ($opt{source_resource} => $m);
836    
837     append_description (source_resource => $opt{source_resource},
838     result_parent => $m);
839    
840     ## TODO: xparam
841     } # append_xsubtype_documentation
842    
843 wakaba 1.1 sub append_param_documentation (%) {
844     my %opt = @_;
845    
846     my $is_named_param = $opt{source_resource}->get_property_boolean
847     (ExpandedURI q<DISPerl:isNamedParameter>, 0);
848    
849     my $perl_name = $is_named_param
850     ? $opt{source_resource}->pl_name
851     : $opt{source_resource}->pl_variable_name;
852    
853     my $p = $opt{result_parent}->create_parameter ($perl_name, $is_named_param);
854    
855 wakaba 1.2 add_uri ($opt{source_resource} => $p);
856    
857 wakaba 1.1 $p->is_nullable_parameter ($opt{source_resource}->pl_is_nullable);
858 wakaba 1.2 $p->resource_data_type
859     (my $u = $opt{source_resource}->dis_data_type_resource->uri);
860     $ReferredResource{$u} ||= 1;
861 wakaba 1.1 $p->resource_actual_data_type
862 wakaba 1.2 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
863     $ReferredResource{$u} ||= 1;
864 wakaba 1.1
865     append_description (source_resource => $opt{source_resource},
866     result_parent => $p,
867 wakaba 1.4 has_case => 1,
868     method_resource => $opt{method_resource});
869 wakaba 1.1 } # append_param_documentation
870    
871     sub append_description (%) {
872     my %opt = @_;
873 wakaba 1.2
874 wakaba 1.1 my $od = $opt{result_parent}->owner_document;
875     my $resd = $opt{source_resource}->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
876 wakaba 1.5 my $doc = transform_disdoc_tree
877     ($resd->get_description
878     ($od, undef,
879     $Opt{with_impl_note},
880 wakaba 1.8 parent_value_arg => $opt{source_value}),
881 wakaba 1.5 method_resource => $opt{method_resource});
882 wakaba 1.1 $opt{result_parent}->create_description->append_child ($doc);
883     ## TODO: Negotiation
884    
885 wakaba 1.3 my $fn = $resd->get_full_name ($od);
886     if ($fn) {
887     $opt{result_parent}->create_full_name
888 wakaba 1.4 ->append_child (transform_disdoc_tree
889     ($fn,
890     method_resource => $opt{method_resource}));
891 wakaba 1.3 }
892    
893 wakaba 1.12 if ($opt{has_label}) {
894     my $label = $resd->get_label ($od);
895     if ($label) {
896     if ($opt{result_parent}->can ('create_label')) {
897     $opt{result_parent}->create_label
898     ->append_child (transform_disdoc_tree ($label));
899     } else {
900     $opt{result_parent}->append_child
901     ($od->create_element_ns (ExpandedURI q<dump:>, 'label'))
902     ->append_child (transform_disdoc_tree ($label));;
903     }
904     }
905     }
906    
907 wakaba 1.1 if ($opt{has_case}) {
908 wakaba 1.11 for my $caser (@{$opt{source_resource}->get_child_resource_list}) {
909 wakaba 1.1 if ($caser->is_type_uri (ExpandedURI q<ManakaiDOM:InCase>)) {
910     my $case = $opt{result_parent}->append_case;
911     my $cased = $caser->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
912     my $label = $cased->get_label ($od);
913     if ($label) {
914 wakaba 1.4 $case->create_label->append_child
915     (transform_disdoc_tree ($label,
916     method_resource => $opt{method_resource}));
917 wakaba 1.1 }
918     my $value = $caser->pl_code_fragment;
919     if ($value) {
920     $case->create_value->text_content ($value->stringify);
921     }
922 wakaba 1.3 $case->resource_data_type
923     (my $u = $caser->dis_data_type_resource->uri);
924     $ReferredResource{$u} ||= 1;
925     $case->resource_actual_data_type
926     ($u = $caser->dis_actual_data_type_resource->uri);
927     $ReferredResource{$u} ||= 1;
928    
929 wakaba 1.1 append_description (source_resource => $caser,
930 wakaba 1.4 result_parent => $case,
931     method_resource => $opt{method_resource});
932 wakaba 1.1 }
933     }
934     }
935     } # append_description
936    
937 wakaba 1.13 sub append_document_properties (%) {
938     my %opt = @_;
939     my $od = $opt{result_parent}->owner_document;
940    
941     for my $con (@{$opt{source_resource}->get_property_value_list
942     (ExpandedURI q<dis:Label>)}) {
943     my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
944     my $tree = $cond->get_disdoc_tree
945     ($od, ExpandedURI q<lang:disdocInline>,
946     $opt{source_resource}->database,
947     default_name_uri => $opt{source_resource}->source_node_id,
948     default_for_uri => $opt{source_resource}->for_uri);
949     my $ns = $con->name;
950     my $ln = $1 if ($ns =~ s/(\w+)$//);
951     $opt{result_parent}->append_child ($od->create_element_ns ($ns, $ln))
952     ->append_child (transform_disdoc_tree ($tree));
953     }
954     } # append_document_properties
955    
956 wakaba 1.3 sub transform_disdoc_tree ($;%) {
957     my ($el, %opt) = @_;
958     my @el = ($el);
959     EL: while (defined (my $el = shift @el)) {
960     if ($el->node_type == $el->ELEMENT_NODE and
961     defined $el->namespace_uri) {
962     my $mmParsed = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'mmParsed');
963     if ($mmParsed) {
964     my $lextype = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'lexType');
965 wakaba 1.8 if ($lextype eq ExpandedURI q<DISCore:TFQNames>) {
966 wakaba 1.4 my $uri = dd_get_tfqnames_uri ($el);
967     if (defined $uri) {
968     $ReferredResource{$uri} ||= 1;
969     next EL;
970     }
971 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISCore:QName> or
972 wakaba 1.5 $lextype eq ExpandedURI q<DISCore:NCNameOrQName>) {
973     my $uri = dd_get_qname_uri ($el);
974     if (defined $uri) {
975     $ReferredResource{$uri} ||= 1;
976     next EL;
977     }
978 wakaba 1.8 } elsif ($lextype eq ExpandedURI q<DISLang:MemberRef> or
979     $lextype eq ExpandedURI q<dx:XCRef>) {
980 wakaba 1.4 my @nm = @{$el->get_elements_by_tag_name_ns
981     (ExpandedURI q<ddel:>, 'name')};
982     if (@nm == 1) {
983 wakaba 1.5 my $uri = dd_get_tfqnames_uri ($nm[0]);
984     if (defined $uri) {
985     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
986     $ReferredResource{$uri} ||= 1;
987     next EL;
988     }
989     } elsif (@nm == 3) {
990     my $uri = dd_get_tfqnames_uri ($nm[2]);
991 wakaba 1.4 if (defined $uri) {
992 wakaba 1.5 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
993 wakaba 1.4 $ReferredResource{$uri} ||= 1;
994     next EL;
995     }
996     } elsif (@nm == 2) {
997     my $uri = dd_get_tfqnames_uri ($nm[0]);
998     if (not defined $uri) {
999     #
1000     } elsif ($nm[1]->get_elements_by_tag_name_ns
1001     (ExpandedURI q<ddel:>, 'prefix')->[0]) {
1002     #my $luri = dd_get_qname_uri ($nm[1]);
1003     ## QName: Currently not used
1004     } else {
1005     my $lnel = $nm[1]->get_elements_by_tag_name_ns
1006     (ExpandedURI q<ddel:>, 'localName')->[0];
1007     my $lname = $lnel ? $lnel->text_content : '';
1008 wakaba 1.5 my $res;
1009 wakaba 1.8 if ($lextype eq ExpandedURI q<dx:XCRef> or
1010 wakaba 1.5 {
1011     ExpandedURI q<ddel:C> => 1,
1012     ExpandedURI q<ddel:X> => 1,
1013     }->{$el->namespace_uri . $el->local_name}) {
1014     ## NOTE: $db
1015     $res = $db->get_resource ($uri)
1016     ->get_const_resource_by_name ($lname);
1017     } else {
1018     ## NOTE: $db
1019     $res = $db->get_resource ($uri)
1020     ->get_child_resource_by_name_and_type
1021 wakaba 1.4 ($lname, ExpandedURI q<DISLang:AnyMethod>);
1022 wakaba 1.5 }
1023 wakaba 1.4 if ($res) {
1024     $el->set_attribute_ns
1025     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1026     $ReferredResource{$res->uri} ||= 1;
1027     }
1028     next EL;
1029     }
1030     }
1031     } # lextype
1032     } # mmParsed
1033     elsif ($opt{method_resource} and
1034     $el->namespace_uri eq ExpandedURI q<ddel:> and
1035     $el->local_name eq 'P') {
1036     my $res = $opt{method_resource}
1037     ->get_child_resource_by_name_and_type
1038     ($el->text_content, ExpandedURI q<DISLang:MethodParameter>);
1039     if ($res) {
1040     $el->set_attribute_ns
1041     (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1042     $ReferredResource{$res->uri} ||= 1;
1043 wakaba 1.3 }
1044 wakaba 1.4 next EL;
1045 wakaba 1.3 }
1046 wakaba 1.4 push @el, @{$el->child_nodes};
1047 wakaba 1.3 } elsif ($el->node_type == $el->DOCUMENT_FRAGMENT_NODE or
1048     $el->node_type == $el->DOCUMENT_NODE) {
1049 wakaba 1.4 push @el, @{$el->child_nodes};
1050 wakaba 1.3 }
1051     } # EL
1052     $el;
1053     } # transform_disdoc_tree
1054    
1055 wakaba 1.4 sub dd_get_tfqnames_uri ($;%) {
1056     my ($el, %opt) = @_;
1057     return '' unless $el;
1058     my $turi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1059     (ExpandedURI q<ddel:>, 'nameQName')->[0]);
1060     my $furi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1061     (ExpandedURI q<ddel:>, 'forQName')->[0]);
1062     return undef if not defined $turi or not defined $furi;
1063     my $uri = tfuris2uri ($turi, $furi);
1064     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
1065     $uri;
1066     } # dd_get_tfqnames_uri
1067 wakaba 1.3
1068     sub dd_get_qname_uri ($;%) {
1069     my ($el, %opt) = @_;
1070 wakaba 1.4 return undef unless $el;
1071 wakaba 1.3 my $plel = $el->get_elements_by_tag_name_ns
1072     (ExpandedURI q<ddel:>, 'prefix')->[0];
1073     my $lnel = $el->get_elements_by_tag_name_ns
1074     (ExpandedURI q<ddel:>, 'localName')->[0];
1075     my $nsuri = ($plel ? $plel : $el)->lookup_namespace_uri
1076     ($plel ? $plel->text_content : undef);
1077     $nsuri = '' unless defined $nsuri;
1078     if ($plel and $nsuri eq '') {
1079     $plel->remove_attribute_ns
1080 wakaba 1.4 (ExpandedURI q<xmlns:>, $plel->text_content);
1081     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1082     return undef;
1083     } else {
1084     $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1085 wakaba 1.3 }
1086     if ($lnel) {
1087     $nsuri . $lnel->text_content;
1088     } else {
1089     $el->get_attribute_ns (ExpandedURI q<ddel:>, 'defaultURI');
1090     }
1091     } # dd_get_qname_uri
1092    
1093     sub tfuris2uri ($$) {
1094     my ($turi, $furi) = @_;
1095     my $uri;
1096 wakaba 1.5 if ($furi eq ExpandedURI q<ManakaiDOM:all>) {
1097 wakaba 1.3 $uri = $turi;
1098     } else {
1099     my $__turi = $turi;
1100     my $__furi = $furi;
1101     for my $__uri ($__turi, $__furi) {
1102 wakaba 1.12 $__uri =~ s{([^0-9A-Za-z!\$'()*,:;=?\@_./~-])}{sprintf '%%%02X', ord $1}ge;
1103 wakaba 1.3 }
1104 wakaba 1.12 $uri = qq<tag:suika.fam.cx,2005-09:$__turi+$__furi>;
1105 wakaba 1.3 }
1106     $uri;
1107     } # tfuris2uri
1108    
1109 wakaba 1.1 sub append_inheritance (%) {
1110     my %opt = @_;
1111     if (($opt{depth} ||= 0) == 100) {
1112     warn "<".$opt{source_resource}->uri.">: Loop in inheritance";
1113     return;
1114     }
1115 wakaba 1.5
1116     my $has_isa = 0;
1117 wakaba 1.1
1118     for my $isa (@{$opt{source_resource}->get_property_resource_list
1119     (ExpandedURI q<dis:ISA>,
1120 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>)}) {
1121 wakaba 1.5 $has_isa = 1;
1122 wakaba 1.1 append_inheritance
1123     (source_resource => $isa,
1124     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1125 wakaba 1.5 depth => $opt{depth} + 1,
1126     is_class => $opt{is_class});
1127     $ReferredResource{$isa->uri} ||= 1;
1128     if ($opt{class_uri}) {
1129     unshift @ClassInheritance, $isa->uri;
1130     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1131     }
1132     }
1133    
1134     if ($opt{source_resource}->is_defined) {
1135     for my $isa_pack (@{$opt{source_resource}->pl_additional_isa_packages}) {
1136     my $isa;
1137     if ($isa_pack eq 'Message::Util::Error') {
1138     ## NOTE: $db
1139     $isa = $db->get_resource (ExpandedURI q<ecore:MUError>,
1140     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1141     } elsif ($isa_pack eq 'Tie::Array') {
1142     ## NOTE: $db
1143     $isa = $db->get_resource (ExpandedURI q<DISPerl:TieArray>);
1144     } elsif ($isa_pack eq 'Error') {
1145     ## NOTE: $db
1146     $isa = $db->get_resource (ExpandedURI q<ecore:Error>,
1147     for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1148     } else {
1149     ## TODO: What to do?
1150     }
1151     if ($isa) {
1152     $has_isa = 1;
1153     append_inheritance
1154     (source_resource => $isa,
1155     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1156     depth => $opt{depth} + 1,
1157     is_class => $opt{is_class});
1158     $ReferredResource{$isa->uri} ||= 1;
1159     if ($opt{class_uri}) {
1160     unshift @ClassInheritance, $isa->uri;
1161     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1162     }
1163     }
1164     }} # AppISA
1165    
1166     if ($opt{has_const}) {
1167     ## NOTE: $db
1168     my $isa = $db->get_resource (ExpandedURI q<DISPerl:Exporter>);
1169     append_inheritance
1170     (source_resource => $isa,
1171     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1172     depth => $opt{depth} + 1,
1173     is_class => $opt{is_class});
1174     $ReferredResource{$isa->uri} ||= 1;
1175     if ($opt{class_uri}) {
1176     unshift @ClassInheritance, $isa->uri;
1177     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1178     }
1179     }
1180    
1181     if (not $has_isa and $opt{is_class} and
1182     $opt{source_resource}->uri ne ExpandedURI q<DISPerl:UNIVERSAL>) {
1183     ## NOTE: $db
1184     my $isa = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSAL>);
1185     append_inheritance
1186     (source_resource => $isa,
1187     result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1188     depth => $opt{depth} + 1,
1189     is_class => $opt{is_class});
1190 wakaba 1.2 $ReferredResource{$isa->uri} ||= 1;
1191 wakaba 1.5 if ($opt{class_uri}) {
1192     unshift @ClassInheritance, $isa->uri;
1193     push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1194     }
1195 wakaba 1.1 }
1196    
1197     if ($opt{append_implements}) {
1198 wakaba 1.5 ## NOTE: $db
1199     my $u = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSALInterface>);
1200 wakaba 1.1 for my $impl (@{$opt{source_resource}->get_property_resource_list
1201     (ExpandedURI q<dis:Implement>,
1202 wakaba 1.8 default_media_type => ExpandedURI q<DISCore:TFQNames>,
1203 wakaba 1.5 isa_recursive => 1)}, $u) {
1204 wakaba 1.1 append_inheritance
1205     (source_resource => $impl,
1206     result_parent => $opt{result_parent}->append_new_implements
1207     ($impl->uri),
1208     depth => $opt{depth});
1209 wakaba 1.2 $ReferredResource{$impl->uri} ||= 1;
1210 wakaba 1.5 $ClassImplements{$opt{class_uri}}->{$impl->uri} = 1
1211     if $opt{class_uri};
1212 wakaba 1.1 }
1213     }
1214     } # append_inheritance
1215    
1216 wakaba 1.5 sub append_subclassof (%) {
1217     my %opt = @_;
1218    
1219     ## NOTE: This subroutine directly access to internal structure
1220     ## of ManakaiDISResourceDefinition
1221    
1222     my $a;
1223     $a = sub ($$) {
1224     my ($gdb, $s) = @_;
1225     my %s = keys %$s;
1226     while (my $i = [keys %s]->[0]) {
1227     ## Removes itself
1228     delete $s->{$i};
1229     #warn $i;
1230    
1231     my $ires = $gdb->get_resource ($i);
1232     for my $j (keys %$s) {
1233     next if $i eq $j;
1234     if ($ires->{subOf}->{$j}) {
1235     $s->{$i}->{$j} = $s->{$j};
1236     delete $s->{$j};
1237     delete $s{$j};
1238     }
1239     }
1240    
1241     delete $s{$i};
1242     } # %s
1243    
1244     for my $i (keys %$s) {
1245     $a->($s->{$i}) if keys %{$s->{$i}};
1246     }
1247     };
1248    
1249     my $b;
1250     $b = sub ($$) {
1251     my ($s, $p) = @_;
1252     for my $i (keys %$s) {
1253     my $el = $p->append_new_sub_class_of ($i);
1254     $b->($s->{$i}, $el) if keys %{$s->{$i}};
1255     }
1256     };
1257    
1258    
1259     my $sub = {$opt{source_resource}->uri =>
1260     {map {$_ => {}} keys %{$opt{source_resource}->{subOf}}}};
1261     ## NOTE: $db
1262     $a->($db, $sub);
1263     $b->($sub, $opt{result_parent});
1264     } # append_subclassof
1265    
1266 wakaba 1.2 sub add_uri ($$;%) {
1267     my ($res, $el, %opt) = @_;
1268     my $canon_uri = $res->uri;
1269     for my $uri (@{$res->uris}) {
1270     $el->add_uri ($uri, $canon_uri eq $uri ? 0 : 1);
1271     $ReferredResource{$uri} = -1;
1272     }
1273 wakaba 1.3
1274     my $nsuri = $res->namespace_uri;
1275     $el->resource_namespace_uri ($nsuri) if defined $nsuri;
1276     my $lname = $res->local_name;
1277     $el->resource_local_name ($lname) if defined $lname;
1278 wakaba 1.2 } # add_uri
1279    
1280 wakaba 1.5 sub append_raises (%) {
1281     my %opt = @_;
1282    
1283 wakaba 1.8 for my $el (@{$opt{source_resource}->get_property_value_list
1284     (ExpandedURI q<dx:raises>)}) {
1285     next unless $el->isa ('Message::Util::IF::DVURIValue');
1286     my $e = $el->get_resource ($db);
1287     my ($a, $b, $c); ## NOTE: $db
1288     if ($e->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1289     $c = $e;
1290 wakaba 1.10 $b = $c->parent_resource;
1291     $a = $b->parent_resource->parent_resource;
1292 wakaba 1.8 } elsif ($e->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1293     $b = $e;
1294 wakaba 1.10 $a = $b->parent_resource->parent_resource;
1295 wakaba 1.8 } else {
1296     $a = $e;
1297     }
1298     my $rel = $opt{result_parent}->create_raises
1299 wakaba 1.5 ($a->uri, $b ? $b->uri : undef, $c ? $c->uri : undef);
1300    
1301 wakaba 1.8 append_description (source_resource => $opt{source_resource},
1302     source_value => $el,
1303     result_parent => $rel,
1304     method_resource => $opt{method_resource});
1305 wakaba 1.5 }
1306     } # append_raises
1307 wakaba 1.4
1308    
1309 wakaba 1.1 my $doc = $impl->create_disdump_document;
1310    
1311     my $body = $doc->document_element;
1312    
1313 wakaba 1.4 ## -- Outputs requested modules
1314    
1315 wakaba 1.12 for my $res_nuri (keys %{$Opt{resource_uri}}) {
1316     for my $res_furi (keys %{$Opt{resource_uri}->{$res_nuri}}) {
1317     $res_furi = ExpandedURI q<ManakaiDOM:all> unless length $res_furi;
1318     my $res = $db->get_resource ($res_nuri, for_arg => $res_furi);
1319     unless ($res->is_defined) {
1320     die qq{$0: Resource <$res_nuri> for <$res_furi> is not defined};
1321 wakaba 1.4 }
1322    
1323 wakaba 1.12 if ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1324     status_msg_ qq<Document <$res_nuri> for <$res_furi>...>;
1325    
1326     append_document_documentation
1327     (result_parent => $body,
1328     source_resource => $res);
1329 wakaba 1.4
1330 wakaba 1.12 status_msg qq<done>;
1331     } elsif ($res->is_type_uri (ExpandedURI q<dis:ModuleGroup>)) {
1332     status_msg qq<Module group <$res_nuri> for <$res_furi>...>;
1333    
1334     append_module_group_documentation
1335     (result_parent => $body,
1336     source_resource => $res);
1337    
1338     status_msg qq<done>;
1339     } else {
1340     die qq{$0: --resource-uri: Resource <$res_nuri> for <$res_furi>}.
1341     qq{ is not a resource set};
1342     }
1343     } # res_furi
1344     } # res_nuri
1345 wakaba 1.5
1346 wakaba 1.12 for my $mod_uri (keys %{$Opt{module_uri}}) {
1347     for my $mod_for (keys %{$Opt{module_uri}->{$mod_uri}}) {
1348     $mod_for = $Opt{For} unless length $mod_for;
1349     my $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1350     unless (defined $mod_for) {
1351     $mod_for = $mod->get_property_text (ExpandedURI q<dis:DefaultFor>);
1352     if (defined $mod_for) {
1353     $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1354     }
1355     }
1356     unless ($mod->is_defined) {
1357     die qq<$0: Module <$mod_uri> for <$mod_for> is not defined>;
1358     }
1359    
1360     status_msg qq<Module <$mod_uri> for <$mod_for>...>;
1361     progress_reset;
1362    
1363     append_module_documentation
1364     (result_parent => $body,
1365     source_resource => $mod);
1366    
1367     status_msg qq<done>;
1368     } # mod_for
1369 wakaba 1.4 } # mod_uri
1370    
1371     ## -- Outputs referenced resources in external modules
1372 wakaba 1.2
1373 wakaba 1.5 status_msg q<Other modules...>;
1374 wakaba 1.7 progress_reset;
1375 wakaba 1.5
1376 wakaba 1.10 my %debug_res_list;
1377 wakaba 1.2 while (my @ruri = grep {$ReferredResource{$_} > 0} keys %ReferredResource) {
1378     U: while (defined (my $uri = shift @ruri)) {
1379     next U if $ReferredResource{$uri} < 0; ## Already done
1380 wakaba 1.10 if ($Opt{debug}) {
1381     warn "Resource <$uri>: $debug_res_list{$uri} times\n"
1382     if ++$debug_res_list{$uri} > 10;
1383     }
1384 wakaba 1.7 progress_inc;
1385 wakaba 1.2 my $res = $db->get_resource ($uri);
1386     unless ($res->is_defined) {
1387     $res = $db->get_module ($uri);
1388     unless ($res->is_defined) {
1389     $ReferredResource{$uri} = -1;
1390     next U;
1391     }
1392     append_module_documentation
1393     (result_parent => $body,
1394     source_resource => $res,
1395     is_partial => 1);
1396 wakaba 1.13 } elsif ($res->is_type_uri (ExpandedURI q<idl:Interface>) or
1397     $res->is_type_uri (ExpandedURI q<idl:Exception>)) {
1398     append_idl_interface_documentation
1399     (result_parent => $body,
1400     source_resource => $res);
1401 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Class>)) {
1402 wakaba 1.2 my $mod = $res->owner_module;
1403     unless ($ReferredResource{$mod->uri} < 0) {
1404     unshift @ruri, $uri;
1405     unshift @ruri, $mod->uri;
1406     next U;
1407     }
1408     append_class_documentation
1409     (result_parent => $body->create_module ($mod->uri),
1410     source_resource => $res,
1411     is_partial => 1);
1412 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1413 wakaba 1.2 my $mod = $res->owner_module;
1414     unless ($mod->is_defined) {
1415     $ReferredResource{$uri} = -1;
1416     next U;
1417     } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1418     unshift @ruri, $uri;
1419     unshift @ruri, $mod->uri;
1420     next U;
1421     }
1422     append_interface_documentation
1423     (result_parent => $body->create_module ($mod->uri),
1424     source_resource => $res,
1425     is_partial => 1);
1426 wakaba 1.12 } elsif ($res->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
1427 wakaba 1.13 if ($res->is_type_uri (ExpandedURI q<idl:IDLDataType>)) {
1428     append_datatype_documentation
1429     (result_parent => $body,
1430     source_resource => $res);
1431     } else {
1432     my $mod = $res->owner_module;
1433     unless ($mod->is_defined) {
1434     $ReferredResource{$uri} = -1;
1435     next U;
1436     } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1437     unshift @ruri, $uri;
1438     unshift @ruri, $mod->uri;
1439     next U;
1440     }
1441     append_datatype_documentation
1442     (result_parent => $body->create_module ($mod->uri),
1443     source_resource => $res);
1444 wakaba 1.3 }
1445     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:AnyMethod>) or
1446 wakaba 1.8 $res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1447 wakaba 1.10 my $cls = $res->parent_resource;
1448 wakaba 1.2 if (not ($ReferredResource{$cls->uri} < 0) and
1449 wakaba 1.8 ($cls->is_type_uri (ExpandedURI q<DISLang:Class>) or
1450     $cls->is_type_uri (ExpandedURI q<DISLang:Interface>))) {
1451 wakaba 1.2 unshift @ruri, $uri;
1452     unshift @ruri, $cls->uri;
1453     next U;
1454     }
1455     my $model = $body->create_module ($cls->owner_module->uri);
1456 wakaba 1.8 my $clsel = $cls->is_type_uri (ExpandedURI q<DISLang:Class>)
1457 wakaba 1.2 ? $model->create_class ($cls->uri)
1458     : $model->create_interface ($cls->uri);
1459     if ($res->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1460     append_method_documentation
1461     (result_parent => $clsel,
1462     source_resource => $res);
1463 wakaba 1.3 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
1464 wakaba 1.2 append_attr_documentation
1465 wakaba 1.3 (result_parent => $clsel,
1466     source_resource => $res);
1467 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1468 wakaba 1.3 append_constgroup_documentation
1469     (result_parent => $clsel,
1470 wakaba 1.2 source_resource => $res);
1471 wakaba 1.8 } else {
1472     $ReferredResource{$res->uri} = -1;
1473 wakaba 1.2 }
1474     } elsif ($res->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
1475 wakaba 1.10 my $m = $res->parent_resource;
1476 wakaba 1.2 if (not ($ReferredResource{$m->uri} < 0) and
1477     $m->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1478     unshift @ruri, $m->uri;
1479 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1480 wakaba 1.2 next U;
1481 wakaba 1.10 } else {
1482     $ReferredResource{$res->uri} = -1;
1483     }
1484 wakaba 1.8 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1485 wakaba 1.10 my $m = $res->parent_resource;
1486 wakaba 1.3 if (not ($ReferredResource{$m->uri} < 0) and
1487 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1488 wakaba 1.3 unshift @ruri, $m->uri;
1489 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1490 wakaba 1.3 next U;
1491 wakaba 1.8 } else {
1492     $ReferredResource{$res->uri} = -1;
1493     next U;
1494     }
1495 wakaba 1.3 } elsif ($res->is_type_uri
1496     (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1497 wakaba 1.10 my $m = $res->parent_resource;
1498 wakaba 1.3 if (not ($ReferredResource{$m->uri} < 0) and
1499 wakaba 1.8 $m->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1500 wakaba 1.3 unshift @ruri, $m->uri;
1501 wakaba 1.4 $ReferredResource{$res->uri} = -1;
1502 wakaba 1.3 next U;
1503 wakaba 1.8 } else {
1504     $ReferredResource{$res->uri} = -1;
1505     next U;
1506     }
1507 wakaba 1.12 } elsif ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1508     append_document_documentation (source_resource => $res,
1509     result_parent => $body);
1510 wakaba 1.2 } else { ## Unsupported type
1511     $ReferredResource{$uri} = -1;
1512     }
1513     } # U
1514     }
1515    
1516 wakaba 1.8 status_msg '';
1517 wakaba 1.5 status_msg q<done>;
1518    
1519     ## -- Inheriting methods information
1520 wakaba 1.1
1521 wakaba 1.5 {
1522     verbose_msg_ q<Adding inheritance information...>;
1523     my %class_done;
1524     for my $class_uri (@ClassInheritance) {
1525     next if $class_done{$class_uri};
1526     $class_done{$class_uri};
1527     for my $sclass_uri (@{$ClassInheritance{$class_uri}}) {
1528     for my $scm_name (keys %{$ClassMembers{$sclass_uri}}) {
1529     if ($ClassMembers{$class_uri}->{$scm_name}) {
1530     $ClassMembers{$class_uri}->{$scm_name}->{overrides}
1531     ->{$ClassMembers{$sclass_uri}->{$scm_name}->{resource}->uri} = 1;
1532     } else {
1533     $ClassMembers{$class_uri}->{$scm_name}
1534     = {
1535     %{$ClassMembers{$sclass_uri}->{$scm_name}},
1536     is_inherited => 1,
1537     };
1538     }
1539     }
1540     } # superclasses
1541     } # classes
1542 wakaba 1.1
1543 wakaba 1.8 verbose_msg_ q<...>;
1544    
1545 wakaba 1.5 for my $class_uri (keys %ClassImplements) {
1546     for my $if_uri (keys %{$ClassImplements{$class_uri}||{}}) {
1547     for my $mem_name (keys %{$ClassMembers{$if_uri}}) {
1548     unless ($ClassMembers{$class_uri}->{$mem_name}) {
1549     ## Not defined - error
1550     $ClassMembers{$class_uri}->{$mem_name}
1551     = {
1552     %{$ClassMembers{$if_uri}->{$mem_name}},
1553     is_inherited => 1,
1554     };
1555     }
1556     $ClassMembers{$class_uri}->{$mem_name}->{implements}
1557     ->{$ClassMembers{$if_uri}->{$mem_name}->{resource}->uri} = 1;
1558     }
1559     } # interfaces
1560     } # classes
1561    
1562 wakaba 1.8 verbose_msg_ q<...>;
1563    
1564 wakaba 1.5 for my $class_uri (keys %ClassMembers) {
1565     my $cls_res = $db->get_resource ($class_uri);
1566     next unless $cls_res->is_defined;
1567     verbose_msg_ q<.>;
1568     my $cls_el = $body->create_module ($cls_res->owner_module->uri);
1569 wakaba 1.8 if ($cls_res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1570 wakaba 1.5 $cls_el = $cls_el->create_interface ($class_uri);
1571     } else {
1572     $cls_el = $cls_el->create_class ($class_uri);
1573     }
1574     for my $mem_name (keys %{$ClassMembers{$class_uri}}) {
1575     my $mem_info = $ClassMembers{$class_uri}->{$mem_name};
1576     my $el;
1577     if ($mem_info->{type} eq 'const-group') {
1578     $el = $cls_el->create_const_group ($mem_name);
1579     } elsif ($mem_info->{type} eq 'attr') {
1580     $el = $cls_el->create_attribute ($mem_name);
1581     } else {
1582     $el = $cls_el->create_method ($mem_name);
1583     }
1584     if ($mem_info->{is_inherited}) {
1585     $el->ref ($mem_info->{resource}->uri);
1586     }
1587     for my $or (keys %{$mem_info->{overrides}||{}}) {
1588     $el->append_new_overrides ($or);
1589     }
1590     for my $or (keys %{$mem_info->{implements}||{}}) {
1591     $el->append_new_implements ($or);
1592     }
1593     } # members
1594     } # classes
1595    
1596     verbose_msg q<done>;
1597     undef %ClassMembers;
1598     }
1599    
1600     {
1601     status_msg_ qq<Writing file ""...>;
1602    
1603     require Encode;
1604     my $lsimpl = $impl->get_feature (ExpandedURI q<DOMLS:LS> => '3.0');
1605     my $serializer = $lsimpl->create_mls_serializer
1606 wakaba 1.1 ({ExpandedURI q<DOMLS:SerializeDocumentInstance> => ''});
1607 wakaba 1.10 print STDOUT Encode::encode ('utf8', $serializer->write_to_string ($doc));
1608 wakaba 1.5 close STDOUT;
1609     status_msg qq<done>;
1610 wakaba 1.9 $doc->free;
1611 wakaba 1.5 }
1612 wakaba 1.1
1613     verbose_msg_ qq<Checking undefined resources...>;
1614     $db->check_undefined_resource;
1615     verbose_msg qq<done>;
1616    
1617     verbose_msg_ qq<Closing database...>;
1618 wakaba 1.5 $db->free;
1619 wakaba 1.1 undef $db;
1620     verbose_msg qq<done>;
1621    
1622 wakaba 1.8 {
1623     use integer;
1624     my $time = time - $start_time;
1625     status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
1626     }
1627    
1628 wakaba 1.10 exit;
1629    
1630 wakaba 1.5 END {
1631     $db->free if $db;
1632     }
1633    
1634 wakaba 1.10 sub dac_search_file_path_stem ($$$) {
1635     my ($ns, $ln, $suffix) = @_;
1636     require Cwd;
1637     require File::Spec;
1638     for my $dir ('.', @{$Opt{input_search_path}->{$ns}||[]}) {
1639     my $name = Cwd::abs_path
1640     (File::Spec->canonpath
1641     (File::Spec->catfile ($dir, $ln)));
1642     if (-f $name.$suffix) {
1643     return $name;
1644     }
1645     }
1646     return undef;
1647     } # dac_search_file_path_stem;
1648    
1649 wakaba 1.1 =head1 SEE ALSO
1650    
1651     L<lib/manakai/dis.pl> and L<bin/cdis2pm.pl> - Old version of
1652     this script.
1653    
1654 wakaba 1.5 L<lib/Message/Util/DIS.dis> - The I<dis> object implementation.
1655 wakaba 1.1
1656     L<lib/Message/Util/PerlCode.dis> - The Perl code generator.
1657    
1658     L<lib/manakai/DISCore.dis> - The definition for the "dis" format.
1659    
1660     L<lib/manakai/DISPerl.dis> - The definition for the "dis" Perl-specific
1661     vocabulary.
1662    
1663     =head1 LICENSE
1664    
1665     Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
1666    
1667     This program is free software; you can redistribute it and/or
1668     modify it under the same terms as Perl itself.
1669    
1670     =cut
1671    
1672 wakaba 1.13 1; # $Date: 2005/09/30 13:06:13 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24