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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (hide annotations) (download)
Sun Apr 9 14:29:41 2006 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
CVS Tags: manakai-release-0-3-1
Changes since 1.11: +14 -13 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	9 Apr 2006 14:25:10 -0000
2006-04-09  Wakaba  <wakaba@suika.fam.cx>

	* daf.pl (daf_generate_perl_test): Old |PerlCode| methods
	are replaced by new ones.

++ manakai/lib/Message/Util/DIS/ChangeLog	9 Apr 2006 14:29:02 -0000
2006-04-09  Wakaba  <wakaba@suika.fam.cx>

	* Perl.dis (plAppendThrow): Use key for exception parameters.

++ manakai/lib/Message/DOM/ChangeLog	9 Apr 2006 14:28:28 -0000
2006-04-09  Wakaba  <wakaba@suika.fam.cx>

	* XMLParser.dis (Require): Requires the |MCharset:Encode|
	module.
	(parse): Set the |inputEncoding| attribute of the generated document
	object.
	(resolveLSInput default implementation): The |byteStream|
	and |encoding| attributes of the |LSInput| interface
	are now supported.
	(resolveLSInput): Parameters |impl| and |parser| are added.
	(InputFile.inputEncoding): New attribute.

++ manakai/lib/Message/Charset/ChangeLog	9 Apr 2006 14:25:44 -0000
2006-04-09  Wakaba  <wakaba@suika.fam.cx>

	* Encode.dis (close): New method.

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3     use Message::Util::QName::Filter {
4 wakaba 1.2 c => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core#>,
5 wakaba 1.1 DIS => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#>,
6     dis => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
7 wakaba 1.2 DOMLS => q<http://suika.fam.cx/~wakaba/archive/2004/dom/ls#>,
8 wakaba 1.1 dp => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#Perl/>,
9     fe => q<http://suika.fam.cx/www/2006/feature/>,
10     ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
11 wakaba 1.2 pc => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/PerlCode#>,
12 wakaba 1.1 swcfg21 => q<http://suika.fam.cx/~wakaba/archive/2005/swcfg21#>,
13 wakaba 1.2 test => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Test#>,
14 wakaba 1.1 Util => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/>,
15 wakaba 1.12 xp => q<http://suika.fam.cx/~wakaba/archive/2004/dom/xml-parser#>,
16 wakaba 1.1 };
17    
18     use Cwd;
19     use Getopt::Long;
20     use Pod::Usage;
21     my %Opt = (create_module => []);
22     GetOptions (
23     'create-perl-module=s' => sub {
24     shift;
25     my $i = [split /\s+/, shift, 3];
26 wakaba 1.2 $i->[3] = 'perl-pm';
27     push @{$Opt{create_module}}, $i;
28     },
29     'create-perl-test=s' => sub {
30     shift;
31     my $i = [split /\s+/, shift, 3];
32     $i->[3] = 'perl-t';
33 wakaba 1.1 push @{$Opt{create_module}}, $i;
34     },
35     'debug' => \$Opt{debug},
36     'dis-file-suffix=s' => \$Opt{dis_suffix},
37     'daem-file-suffix=s' => \$Opt{daem_suffix},
38 wakaba 1.11 'dafs-file-suffix=s' => \$Opt{dafs_suffix},
39 wakaba 1.1 'dafx-file-suffix=s' => \$Opt{dafx_suffix},
40     'help' => \$Opt{help},
41     'search-path|I=s' => sub {
42     shift;
43     my @value = split /\s+/, shift;
44     while (my ($ns, $path) = splice @value, 0, 2, ()) {
45     unless (defined $path) {
46     die qq[$0: Search-path parameter without path: "$ns"];
47     }
48     push @{$Opt{input_search_path}->{$ns} ||= []}, $path;
49     }
50     },
51     'search-path-catalog-file-name=s' => sub {
52     shift;
53     require File::Spec;
54     my $path = my $path_base = shift;
55     $path_base =~ s#[^/]+$##;
56     $Opt{search_path_base} = $path_base;
57     open my $file, '<', $path or die "$0: $path: $!";
58     while (<$file>) {
59     if (s/^\s*\@//) { ## Processing instruction
60     my ($target, $data) = split /\s+/;
61     if ($target eq 'base') {
62     $Opt{search_path_base} = File::Spec->rel2abs ($data, $path_base);
63     } else {
64     die "$0: $target: Unknown target";
65     }
66     } elsif (/^\s*\#/) { ## Comment
67     #
68     } elsif (/\S/) { ## Catalog entry
69     s/^\s+//;
70     my ($ns, $path) = split /\s+/;
71     push @{$Opt{input_search_path}->{$ns} ||= []},
72     File::Spec->rel2abs ($path, $Opt{search_path_base});
73     }
74     }
75     ## NOTE: File paths with SPACEs are not supported
76     ## NOTE: Future version might use file: URI instead of file path.
77     },
78     'undef-check!' => \$Opt{no_undef_check},
79     'verbose!' => \$Opt{verbose},
80     ) or pod2usage (2);
81     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
82     $Opt{no_undef_check} = defined $Opt{no_undef_check}
83     ? $Opt{no_undef_check} ? 0 : 1 : 0;
84     $Opt{dis_suffix} = '.dis' unless defined $Opt{dis_suffix};
85     $Opt{daem_suffix} = '.dafm' unless defined $Opt{daem_suffix};
86     $Opt{dafx_suffix} = '.dafx' unless defined $Opt{dafx_suffix};
87 wakaba 1.11 $Opt{dafs_suffix} = '.dafs' unless defined $Opt{dafs_suffix};
88 wakaba 1.1 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
89     require Error;
90     $Error::Debug = 1 if $Opt{debug};
91     $Message::Util::Error::VERBOSE = 1 if $Opt{verbose};
92    
93     sub status_msg ($) {
94     my $s = shift;
95     $s .= "\n" unless $s =~ /\n$/;
96     print STDERR $s;
97     }
98    
99     sub status_msg_ ($) {
100     my $s = shift;
101     print STDERR $s;
102     }
103    
104     sub verbose_msg ($) {
105     my $s = shift;
106     $s .= "\n" unless $s =~ /\n$/;
107     print STDERR $s if $Opt{verbose};
108     }
109    
110     sub verbose_msg_ ($) {
111     my $s = shift;
112     print STDERR $s if $Opt{verbose};
113     }
114    
115 wakaba 1.2 ## ---- The MAIN Program
116    
117 wakaba 1.1 my $start_time;
118     BEGIN { $start_time = time }
119    
120     use Message::Util::DIS::DNLite;
121     use Message::Util::PerlCode;
122 wakaba 1.5
123     my %feature;
124     eval q{
125     use Message::Util::DIS::Test;
126     use Message::DOM::GenericLS;
127     $feature{ExpandedURI q<fe:GenericLS>} = '3.0';
128     $feature{'+' . ExpandedURI q<DIS:TDT>} = '1.0';
129     };
130 wakaba 1.1
131     my $limpl = $Message::DOM::ImplementationRegistry->get_implementation
132     ({ExpandedURI q<fe:Min> => '3.0',
133     '+' . ExpandedURI q<DIS:DNLite> => '1.0',
134     '+' . ExpandedURI q<DIS:Core> => '1.0',
135     '+' . ExpandedURI q<Util:PerlCode> => '1.0',
136 wakaba 1.5 %feature,
137 wakaba 1.1 });
138     my $impl = $limpl->get_feature (ExpandedURI q<DIS:Core> => '1.0');
139 wakaba 1.2 my $tdt_parser;
140    
141     ## --- Loading and Updating the Database
142 wakaba 1.1
143     my $HasError;
144     my $db = $impl->create_dis_database;
145     $db->pl_database_module_resolver (\&daf_db_module_resolver);
146     $db->dom_config->set_parameter ('error-handler' => \&daf_on_error);
147    
148 wakaba 1.2 my $parser = $impl->create_dis_parser;
149     my $DNi = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0');
150 wakaba 1.1 my %ModuleSourceDISDocument;
151     my %ModuleSourceDNLDocument;
152     my %ModuleNameNamespaceBinding = (
153     DISCore => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Core#>,
154     ## This builtin binding is required since
155     ## some module has |DISCore:author| property before |dis:Require|
156     ## property.
157     );
158    
159     my @target_modules;
160     for (@{$Opt{create_module}}) {
161     my ($mod_uri, $out_path, $mod_for, $out_type) = @$_;
162     push @target_modules, [$mod_uri, $mod_for];
163     }
164    
165     my $ResourceCount = 0;
166     $db->pl_update_module (\@target_modules,
167     get_module_index_file_name => sub {
168     shift; # $db
169     daf_get_module_index_file_name (@_);
170     },
171     get_module_source_document_from_uri => sub {
172     my ($db, $module_uri, $module_for) = @_;
173     status_msg '';
174     status_msg qq<Loading module <$module_uri> for <$module_for>...>;
175     $ResourceCount = 0;
176    
177     unless (defined $ModuleSourceDNLDocument{$module_uri}) {
178     unless (defined $ModuleSourceDISDocument{$module_uri}) {
179     daf_open_source_dis_document ($module_uri);
180     }
181     daf_convert_dis_document_to_dnl_document ();
182     }
183     return $ModuleSourceDNLDocument{$module_uri};
184     },
185     get_module_source_document_from_resource => sub ($$$$$$) {
186     my ($self, $db, $uri, $ns, $ln, $for) = @_;
187     status_msg '';
188     status_msg qq<Loading module "$ln" for <$for>...>;
189     $ResourceCount = 0;
190    
191     my $module_uri = $ns.$ln;
192     unless (defined $ModuleSourceDNLDocument{$module_uri}) {
193     unless (defined $ModuleSourceDISDocument{$module_uri}) {
194     daf_open_source_dis_document ($module_uri);
195     }
196     daf_convert_dis_document_to_dnl_document ();
197     }
198     return $ModuleSourceDNLDocument{$module_uri};
199     },
200     get_module_source_revision => sub {
201     my ($db, $module_uri) = @_;
202     my $ns = $module_uri;
203     $ns =~ s/(\w+)\z//;
204     my $ln = $1;
205    
206     my $name = dac_search_file_path_stem ($ns, $ln, $Opt{dis_suffix});
207     if (defined $name) {
208     return [stat $name.$Opt{dis_suffix}]->[9];
209     } else {
210     return 0;
211     }
212     },
213     get_referring_module_uri_list => sub {
214     my ($db, $module_uri) = @_;
215     unless (defined $ModuleSourceDNLDocument{$module_uri}) {
216     unless (defined $ModuleSourceDISDocument{$module_uri}) {
217     daf_open_source_dis_document ($module_uri);
218     }
219     }
220     return daf_get_referring_module_uri_list ($module_uri);
221     },
222     on_resource_read => sub ($$) {
223     if ((++$ResourceCount % 10) == 0) {
224     status_msg_ "*";
225     status_msg_ " " if ($ResourceCount % (10 * 10)) == 0;
226     status_msg '' if ($ResourceCount % (10 * 50)) == 0;
227     }
228     });
229    
230    
231     ## Removes reference from document to database
232     our @Document;
233     for my $dis (@Document) {
234     $dis->unlink_from_document;
235     $dis->dis_database (undef);
236     }
237    
238     status_msg '';
239    
240     status_msg qq<Reading properties...>;
241     $ResourceCount = 0;
242     $db->read_properties (on_resource_read => sub ($$) {
243     if ((++$ResourceCount % 10) == 0) {
244     status_msg_ "*";
245     status_msg_ " " if ($ResourceCount % (10 * 10)) == 0;
246     status_msg '' if ($ResourceCount % (10 * 50)) == 0;
247     }
248     });
249     status_msg '';
250     status_msg "done";
251    
252     status_msg_ qq<Writing database files...>;
253     $db->pl_store ('dummy', sub ($$) {
254     my ($db, $mod, $type) = @_;
255     my $ns = $mod->namespace_uri;
256     my $ln = $mod->local_name;
257     my $suffix = $type eq ExpandedURI q<dp:ModuleIndexFile>
258     ? $Opt{dafx_suffix} : $Opt{daem_suffix};
259     my $name = dac_search_file_path_stem ($ns, $ln, $suffix);
260     if (defined $name) {
261     $name .= $suffix;
262     } elsif (defined ($name = dac_search_file_path_stem
263     ($ns, $ln, $Opt{dis_suffix}))) {
264     $name .= $suffix;
265     } else {
266     $name = Cwd::abs_path
267     (File::Spec->canonpath
268     (File::Spec->catfile
269     (defined $Opt{input_search_path}->{$ns}->[0]
270     ? $Opt{input_search_path}->{$ns}->[0] : '.',
271     $ln.$suffix)));
272     }
273     verbose_msg qq<Database >.
274     ($type eq <Q::dp|ModuleIndexFile> ? 'index' : 'module').
275     qq< <$ns$ln> is written to "$name">;
276     return $name;
277     }, no_main_database => 1);
278     status_msg "done";
279    
280     daf_check_undefined ();
281    
282 wakaba 1.2 undef $DNi;
283     undef %ModuleSourceDNLDocument;
284     exit $HasError if $HasError;
285    
286     ## --- Creating Files
287    
288 wakaba 1.1 for (@{$Opt{create_module}}) {
289     my ($mod_uri, $out_file_path, $mod_for, $out_type) = @$_;
290     unless (defined $mod_for) {
291     $mod_for = $db->get_module ($mod_uri)
292     ->get_property_text (ExpandedURI q<dis:DefaultFor>,
293     ExpandedURI q<ManakaiDOM:all>);
294     }
295     my $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
296    
297 wakaba 1.2 if ($out_type eq 'perl-pm') {
298 wakaba 1.1 status_msg_ qq<Generating Perl module from <$mod_uri> for <$mod_for>...>;
299 wakaba 1.9 local $Message::Util::DIS::Perl::Implementation
300     = $impl->get_feature (ExpandedURI q<Util:PerlCode> => '1.0');
301 wakaba 1.10 my $pl = $mod->pl_generate_perl_module_file
302     ($impl->get_feature (ExpandedURI q<Util:PerlCode> => '1.0'));
303 wakaba 1.1 status_msg qq<done>;
304    
305     my $output;
306     defined $out_file_path
307     ? (open $output, '>', $out_file_path or die "$0: $out_file_path: $!")
308     : ($output = \*STDOUT);
309    
310     status_msg_ sprintf qq<Writing Perl module %s...>,
311     defined $out_file_path
312     ? q<">.$out_file_path.q<">
313     : 'to stdout';
314     print $output $pl->stringify;
315     close $output;
316     status_msg q<done>;
317 wakaba 1.2 } elsif ($out_type eq 'perl-t') {
318     status_msg_ qq<Generating Perl test from <$mod_uri> for <$mod_for>...>;
319     my $pl = daf_generate_perl_test_file ($mod);
320     status_msg qq<done>;
321    
322 wakaba 1.3 my $cfg = $pl->owner_document->dom_config;
323     $cfg->set_parameter (ExpandedURI q<pc:preserve-line-break> => 1);
324    
325 wakaba 1.2 my $output;
326     defined $out_file_path
327     ? (open $output, '>', $out_file_path or die "$0: $out_file_path: $!")
328     : ($output = \*STDOUT);
329    
330     status_msg_ sprintf qq<Writing Perl test %s...>,
331     defined $out_file_path
332     ? q<">.$out_file_path.q<">
333     : 'to stdout';
334     print $output $pl->stringify;
335     close $output;
336     status_msg q<done>;
337 wakaba 1.1 }
338     }
339    
340     daf_check_undefined ();
341    
342 wakaba 1.2 ## --- The END
343    
344 wakaba 1.1 status_msg_ "Closing the database...";
345     $db->free;
346     undef $db;
347     status_msg "done";
348    
349 wakaba 1.7 undef $limpl;
350     undef $impl;
351    
352 wakaba 1.1 {
353     use integer;
354     my $time = time - $start_time;
355     status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
356     }
357     exit $HasError;
358    
359     END {
360     $db->free if $db;
361     }
362    
363 wakaba 1.2 ## ---- Subroutines
364    
365 wakaba 1.1 sub daf_open_source_dis_document ($) {
366     my ($module_uri) = @_;
367    
368     ## -- Finds |dis| source file
369     my $ns = $module_uri;
370     $ns =~ s/(\w+)\z//;
371     my $ln = $1;
372     my $file_name = dac_search_file_path_stem ($ns, $ln, $Opt{dis_suffix});
373     unless (defined $file_name) {
374     die "$0: Source file for <$ns$ln> is not found";
375     }
376     $file_name .= $Opt{dis_suffix};
377    
378     status_msg_ qq<Opening dis source file "$file_name"...>;
379    
380     ## -- Opens |dis| file and construct |DISDocument| tree
381     open my $file, '<', $file_name or die "$0: $file_name: $!";
382     my $dis = $parser->parse ({character_stream => $file});
383     require File::Spec;
384     $dis->flag (ExpandedURI q<swcfg21:fileName> =>
385     File::Spec->abs2rel ($file_name));
386     $dis->dis_namespace_resolver (\&daf_module_name_namespace_resolver);
387     close $file;
388    
389     ## -- Registers namespace URI
390     my $mod = $dis->module_element;
391     if ($mod) {
392     my $qn = $mod->get_attribute_ns (ExpandedURI q<dis:>, 'QName');
393     if ($qn) {
394     my $prefix = $qn->value;
395     $prefix =~ s/^[^:|]*[:|]\s*//;
396     $prefix =~ s/\s+$//;
397     unless (defined $ModuleNameNamespaceBinding{$prefix}) {
398     $ModuleNameNamespaceBinding{$prefix} = $mod->defining_namespace_uri;
399     }
400     }
401     }
402    
403     $ModuleSourceDISDocument{$module_uri} = $dis;
404     status_msg q<done>;
405    
406     R: for (@{daf_get_referring_module_uri_list ($module_uri)}) {
407     next R if defined $db->{modDef}->{$_};
408     next R if defined $ModuleSourceDNLDocument{$_};
409     next R if defined $ModuleSourceDISDocument{$_};
410     my $idx_file_name = daf_get_module_index_file_name ($_);
411     if (-f $idx_file_name) {
412     daf_open_current_module_index ($_, $idx_file_name);
413     } else {
414     daf_open_source_dis_document ($_);
415     }
416     }
417     } # daf_open_source_dis_document
418    
419     sub daf_open_current_module_index ($$) {
420     my ($module_uri, $file_name) = @_;
421     $db->pl_load_dis_database_index ($file_name);
422    
423     R: for (@{$db->get_module ($module_uri)
424     ->get_referring_module_uri_list}) {
425     next R if defined $db->{modDef}->{$_};
426     next R if defined $ModuleSourceDNLDocument{$_};
427     next R if defined $ModuleSourceDISDocument{$_};
428     my $idx_file_name = daf_get_module_index_file_name ($_);
429     if (-f $idx_file_name) {
430     daf_open_current_module_index ($_, $idx_file_name);
431     } else {
432     daf_open_source_dis_document ($_);
433     }
434     }
435     } # daf_open_current_module_index
436    
437     sub daf_convert_dis_document_to_dnl_document () {
438     M: for my $module_uri (keys %ModuleSourceDISDocument) {
439     my $dis_doc = $ModuleSourceDISDocument{$module_uri};
440     next M unless $dis_doc;
441     verbose_msg_ qq<Converting <$module_uri>...>;
442     my $dnl_doc = $DNi->convert_dis_document_to_dnl_document
443     ($dis_doc, database_arg => $db,
444     base_namespace_binding =>
445     {(map {$_->local_name => $_->target_namespace_uri}
446     grep {$_} values %{$db->{modDef}}),
447     %ModuleNameNamespaceBinding});
448     push @Document, $dnl_doc;
449     $ModuleSourceDNLDocument{$module_uri} = $dnl_doc;
450     $dis_doc->free;
451     delete $ModuleSourceDISDocument{$module_uri};
452     verbose_msg q<done>;
453     }
454     } # daf_convert_dis_document_to_dnl_document
455    
456     sub daf_get_referring_module_uri_list ($) {
457     my $module_uri = shift;
458     my $ns = $module_uri;
459     $ns =~ s/\w+\z//;
460     my $src = $ModuleSourceDNLDocument{$module_uri};
461     $src = $ModuleSourceDISDocument{$module_uri} unless defined $src;
462     my $mod_el = $src->module_element;
463     my $r = [];
464     if ($mod_el) {
465     my $req_el = $mod_el->require_element;
466     if ($req_el) {
467     M: for my $m_el (@{$req_el->child_nodes}) {
468     next M unless $m_el->node_type eq '#element';
469     next M unless $m_el->expanded_uri eq ExpandedURI q<dis:Module>;
470     my $qn_el = $m_el->get_attribute_ns (ExpandedURI q<dis:>, 'QName');
471     if ($qn_el) {
472     push @$r, $qn_el->qname_value_uri;
473     } else {
474     my $n_el = $m_el->get_attribute_ns (ExpandedURI q<dis:>, 'Name');
475     if ($n_el) {
476     push @$r, $ns.$n_el->value;
477     } else {
478     # The module itself
479     }
480     }
481     }
482     }
483     }
484     return $r;
485     } # daf_get_referring_module_uri_list
486    
487     sub dac_search_file_path_stem ($$$) {
488     my ($ns, $ln, $suffix) = @_;
489     require File::Spec;
490 wakaba 1.8 for my $dir (@{$Opt{input_search_path}->{$ns}||[]}) {
491 wakaba 1.1 my $name = Cwd::abs_path
492     (File::Spec->canonpath
493     (File::Spec->catfile ($dir, $ln)));
494     if (-f $name.$suffix) {
495     return $name;
496     }
497     }
498     return undef;
499     } # dac_search_file_path_stem;
500    
501     sub daf_get_module_index_file_name ($$) {
502     my ($module_uri) = @_;
503     my $ns = $module_uri;
504     $ns =~ s/(\w+)\z//;
505     my $ln = $1;
506    
507     verbose_msg qq<Database module index <$module_uri> is requested>;
508     my $suffix = $Opt{dafx_suffix};
509     my $name = dac_search_file_path_stem ($ns, $ln, $suffix);
510     if (defined $name) {
511     $name .= $suffix;
512     } elsif (defined ($name = dac_search_file_path_stem
513     ($ns, $ln, $Opt{dis_suffix}))) {
514     $name .= $suffix;
515     } else {
516     $name = Cwd::abs_path
517     (File::Spec->canonpath
518     (File::Spec->catfile
519     (defined $Opt{input_search_path}->{$ns}->[0]
520     ? $Opt{input_search_path}->{$ns}->[0] : '.',
521     $ln.$suffix)));
522     }
523     return $name;
524     } # daf_get_module_index_file_name
525    
526     sub daf_module_name_namespace_resolver ($) {
527     my $prefix = shift;
528    
529     ## -- From modules in database
530     M: for (values %{$db->{modDef}}) {
531     my $mod = $_;
532     next M unless defined $mod;
533     if ($mod->local_name eq $prefix) {
534     return $mod->target_namespace_uri;
535     }
536     }
537    
538     ## -- From not-in-database-yet module list
539     if (defined $ModuleNameNamespaceBinding{$prefix}) {
540     return $ModuleNameNamespaceBinding{$prefix};
541     }
542     return undef;
543     } # daf_module_name_namespace_resolver
544    
545     sub daf_db_module_resolver ($$$) {
546     my ($db, $mod, $type) = @_;
547     my $ns = $mod->namespace_uri;
548     my $ln = $mod->local_name;
549 wakaba 1.11 my $suffix = {
550     ExpandedURI q<dp:ModuleIndexFile> => $Opt{dafx_suffix},
551     ExpandedURI q<dp:ModuleResourceFile> => $Opt{daem_suffix},
552     ExpandedURI q<dp:ModuleNodeStorageFile> => $Opt{dafs_suffix},
553     }->{$type} or die "Unsupported type: <$type>";
554 wakaba 1.1 verbose_msg qq<Database module <$ns$ln> is requested>;
555     my $name = dac_search_file_path_stem ($ns, $ln, $suffix);
556     if (defined $name) {
557     return $name.$suffix;
558     } else {
559     return undef;
560     }
561     } # daf_db_module_resolver
562    
563     sub daf_on_error ($$) {
564     my ($self, $err) = @_;
565     if ($err->severity == $err->SEVERITY_WARNING) {
566     my $info = ExpandedURI q<dp:info>;
567     if ($err->type =~ /\Q$info\E/) {
568     my $msg = $err->text;
569     if ($msg =~ /\.\.\.\z/) {
570     verbose_msg_ $msg;
571     } else {
572     verbose_msg $msg;
573     }
574     } else {
575     my $msg = $err->text;
576     if ($msg =~ /\.\.\.\z/) {
577     status_msg_ $msg;
578     } else {
579     status_msg $msg;
580     }
581     }
582     } else {
583     warn $err;
584     $HasError = 1;
585     }
586     } # daf_on_error
587    
588     sub daf_check_undefined () {
589     unless ($Opt{no_undef_check}) {
590     status_msg_ "Checking undefined resources...";
591     $db->check_undefined_resource;
592     print STDERR "done\n";
593     }
594     } # daf_check_undefined
595 wakaba 1.2
596     sub daf_generate_perl_test_file ($) {
597     my $mod = shift;
598 wakaba 1.6 my $pc = $impl->get_feature (ExpandedURI q<Util:PerlCode> => '1.0');
599 wakaba 1.9 local $Message::Util::DIS::Perl::Implementation = $pc;
600 wakaba 1.10 my $pl = $pc->create_pc_file;
601     my $factory = $pl->owner_document;
602 wakaba 1.2 my $pack = $pl->get_last_package ("Manakai::Test", make_new_package => 1);
603     $pack->add_use_perl_module_name ("Message::Util::DIS::Test");
604     $pack->add_use_perl_module_name ("Message::Util::Error");
605     $pack->add_require_perl_module_name ($mod->pl_fully_qualified_name);
606    
607     $pl->source_file ($mod->get_property_text (ExpandedURI q<DIS:sourceFile>, ""));
608     $pl->source_module ($mod->name_uri);
609     $pl->source_for ($mod->for_uri);
610     $pl->license_uri ($mod->get_property_resource (ExpandedURI q<dis:License>)
611     ->uri);
612    
613 wakaba 1.7 $pack->append_code ('
614     use Getopt::Long;
615     my %Skip;
616     GetOptions (
617     "Skip=s" => sub {
618     shift;
619     for (split /\s+/, shift) {
620     if (/^(\d+)-(\d+)$/) {
621     $Skip{$_} = 1 for $1..$2;
622     } else {
623     $Skip{$_} = 1;
624     }
625     }
626     },
627     );
628     ');
629    
630 wakaba 1.12 $pack->append_child ($factory->create_pc_statement)
631     ->append_code
632     ('my $impl = $Message::DOM::ImplementationRegistry
633     ->get_implementation ({
634     "http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#Test"
635     => "1.0",
636     })');
637    
638     my $num_statement = $pack->append_child ($factory->create_pc_statement);
639     $num_statement->append_code ('my $test = $impl->create_test_manager');
640 wakaba 1.2
641     my $total_tests = 0;
642     my %processed;
643     for my $res (@{$mod->get_resource_list}) {
644     next if $res->owner_module ne $mod or $processed{$res->uri};
645     $processed{$res->uri} = 1;
646    
647     if ($res->is_type_uri (ExpandedURI q<test:Test>)) {
648     if ($res->is_type_uri (ExpandedURI q<test:StandaloneTest>)) {
649 wakaba 1.7 my $test_num = ++$total_tests;
650     my $test_uri = $res->name_uri || $res->uri;
651    
652 wakaba 1.2 $pack->append_code ('$test->start_new_test (');
653 wakaba 1.7 $pack->append_new_pc_literal ($test_uri);
654 wakaba 1.2 $pack->append_code (');');
655 wakaba 1.7
656     $pack->append_code ('if (not $Skip{'.$test_num.'} and not $Skip{');
657     $pack->append_new_pc_literal ($test_uri);
658     $pack->append_code ('}) {');
659 wakaba 1.2
660     $pack->append_code ('try {');
661    
662 wakaba 1.10 my $test_pc = $res->pl_code_fragment ($factory);
663 wakaba 1.2 if (not defined $test_pc) {
664     die "Perl test code not defined for <".$res->uri.">";
665     }
666    
667 wakaba 1.12 $pack->append_child ($test_pc);
668 wakaba 1.2
669     $pack->append_code ('$test->ok;');
670    
671     $pack->append_code ('} catch Message::Util::IF::DTException with {
672     ##
673     } otherwise {
674     my $err = shift;
675     warn $err;
676     $test->not_ok;
677     };');
678 wakaba 1.7
679     $pack->append_code ('} else { warn "'.$test_num.' skipped\n" }');
680 wakaba 1.2
681     } elsif ($res->is_type_uri (ExpandedURI q<test:ParserTestSet>)) {
682     my $block = $pack->append_new_pc_block;
683     my @test;
684    
685 wakaba 1.3 $tdt_parser ||= $limpl->create_gls_parser
686 wakaba 1.2 ({
687     ExpandedURI q<DIS:TDT> => '1.0',
688     });
689     for my $tres (@{$res->get_child_resource_list_by_type
690     (ExpandedURI q<test:ParserTest>)}) {
691     $total_tests++;
692     push @test, my $ttest = {entity => {}};
693     $ttest->{uri} = $tres->uri;
694     for my $eres (@{$tres->get_child_resource_list_by_type
695     (ExpandedURI q<test:Entity>)}) {
696     my $tent = $ttest->{entity}->{$eres->uri} = {};
697     for (ExpandedURI q<test:uri>, ExpandedURI q<test:baseURI>,
698 wakaba 1.12 ExpandedURI q<test:value>, ExpandedURI q<xp:encoding>) {
699 wakaba 1.2 my $v = $eres->get_property_text ($_);
700     $tent->{$_} = $v if defined $v;
701     }
702     $ttest->{root_uri} = $eres->uri
703     if $eres->is_type_uri (ExpandedURI q<test:RootEntity>) or
704     not defined $ttest->{root_uri};
705 wakaba 1.6 }
706    
707     ## DOM configuration parameters
708     for my $v (@{$tres->get_property_value_list
709     (ExpandedURI q<c:anyDOMConfigurationParameter>)}) {
710     my $cpuri = $v->name;
711     my $cp = $db->get_resource ($cpuri, for_arg => $tres->for_uri);
712     $ttest->{dom_config}->{$cp->get_dom_configuration_parameter_name}
713     = $v->get_perl_code ($block->owner_document, $tres);
714 wakaba 1.2 }
715    
716     ## Result DOM tree
717     my $tree_t = $tres->get_property_text (ExpandedURI q<test:domTree>);
718     if (defined $tree_t) {
719     $ttest->{dom_tree} = $tdt_parser->parse_string ($tree_t);
720     }
721    
722     ## Expected |DOMError|s
723     for (@{$tres->get_property_value_list (ExpandedURI q<c:erred>)}) {
724     my $err = $tdt_parser->parse_tdt_error_string
725     ($_->string_value, $db, $_,
726     undef, $tres->for_uri);
727     push @{$ttest->{dom_error}->{$err->{type}->{value}} ||= []}, $err;
728     }
729     }
730    
731     for ($block->append_statement
732     ->append_new_pc_expression ('=')) {
733     $_->append_new_pc_variable ('$', undef, 'TestData')
734     ->variable_scope ('my');
735     $_->append_new_pc_literal (\@test);
736     }
737    
738 wakaba 1.10 my $plc = $res->pl_code_fragment ($factory);
739 wakaba 1.2 unless ($plc) {
740     die "Resource <".$res->uri."> does not have Perl test code";
741     }
742    
743 wakaba 1.12 $block->append_child ($plc);
744 wakaba 1.2
745     } # test resource type
746     } # test:Test
747     }
748    
749     $num_statement->append_code (' (' . $total_tests . ')');
750    
751     return $pl;
752     } # daf_generate_perl_test_file
753 wakaba 1.1
754     __END__
755    
756     =head1 NAME
757    
758     dac.pl - Creating "dac" Database File from "dis" Source Files
759    
760     =head1 SYNOPSIS
761    
762     perl path/to/dac.pl [--input-db-file-name=input.dac] \
763     --output-file-name=out.dac [options...] \
764     input.dis
765     perl path/to/dac.pl --help
766    
767     =head1 DESCRIPTION
768    
769     This script, C<dac.pl>, compiles "dis" source files into "dac"
770     database file. The generated database file can be used
771     in turn to generate Perl module file, for example, by another
772     script C<dac2pm.pl> or can be used to create larger database
773     by specifying its file name as the C<--input-db-file-name>
774     argument of another C<dac.pl> execution.
775    
776     This script is part of manakai.
777    
778     =head1 OPTIONS
779    
780     =over 4
781    
782     =item I<input.dis> (Required)
783    
784     The unnamed option specifies a file name path of the source "dis" file
785     from which a database is created. This option is required.
786    
787     =item C<--input-db-file-name=I<file-name>> (Default: none)
788    
789     A file path of the base database. This option is optional; if this
790     option is specified, the database file is loaded first
791     and then I<input.dis> file is loaded in the context of it.
792     Otherwise, a new database is created.
793    
794     =item C<--output-file-name=I<file-name>> (Required)
795    
796     The
797    
798     =back
799    
800     =head1 SEE ALSO
801    
802     L<bin/dac2pm.pl> - Generating Perl module from "dac" file.
803    
804     L<lib/Message/Util/DIS.dis> - The actual implementation
805     of the "dis" interpretation.
806    
807     =head1 LICENSE
808    
809     Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
810    
811     This program is free software; you can redistribute it and/or
812     modify it under the same terms as Perl itself.
813    
814     =cut

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24