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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download)
Sun Feb 26 14:32:38 2006 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.2: +5 -1 lines
File MIME type: text/plain
++ manakai/t/ChangeLog	26 Feb 2006 14:32:29 -0000
	* Makefile (distclean): New rule.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/bin/ChangeLog	26 Feb 2006 14:18:44 -0000
	* daf.pl: Request for |fe:GenericLS| feature was missing.
	Sets the |pc:preserve-line-break| parameter for test
	code as |dac2test.pl| had been.

	* dac.pl, dac2pm.pl, dac2test.pl: Removed.

	* disc.pl, cdis2pm.pl, cdis2rdf.pl: Removed.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/ChangeLog	26 Feb 2006 14:19:17 -0000
2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (distclean): New rule.

++ manakai/lib/Message/Body/ChangeLog	26 Feb 2006 14:19:35 -0000
2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (distclean): New rule.

++ manakai/lib/Message/Field/ChangeLog	26 Feb 2006 14:24:08 -0000
2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (distclean): New rule.

++ manakai/lib/Message/MIME/ChangeLog	26 Feb 2006 14:24:31 -0000
2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (distclean): New rule.

++ manakai/lib/Message/Markup/ChangeLog	26 Feb 2006 14:24:49 -0000
	* Makefile (distclean): New rule.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/Util/ChangeLog	26 Feb 2006 14:27:24 -0000
	* PerlCode.dis (PerlStringLiteral.stringify): If some character
	are escaped, the string should have been quoted by |QUOTATION MARK|.

	* Makefile (.discore-all.pm): The parameter for |DIS/DPG.dis|
	module was misplaced.
	(distclean): New rule.
	(clean): Cleans subdirectories, too.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/Util/DIS/ChangeLog	26 Feb 2006 14:31:14 -0000
	* Perl.dis (plUpdate): Reads |dis:DefaultFor| property
	from the source if it is not available from the module
	in the database, i.e. the |readProperties| method
	is not performed for the module.
	(getPerlInterfaceMemberCode): Renamed
	from |getPerlErrorInterfaceMemberCode|.
	(DISLang:Const.getPerlInterfaceMemberCode): New
	method implementation.  Constants defined in interfaces
	were not reflected to the generated Perl module code
	since the split of |plGeneratePerlModule| method.

	* DPG.dis (Require): Reference to |DIS:Perl| module was missing.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/DOM/ChangeLog	26 Feb 2006 14:21:51 -0000
	* SimpleLS.dis (Require): Reference to the |MDOM:Tree|
	module was missing.

	* ManakaiDOMLS2003.dis: Some property names was incorrect.

	* Makefile (distclean): New rule.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* DOMLS.dis: Removed from the CVS repository, since
	it has been no longer required to make the |daf| system
	itself.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/manakai/ChangeLog	26 Feb 2006 14:32:09 -0000
	* Makefile (distclean): New rule.

2006-02-26  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/ChangeLog	26 Feb 2006 14:19:00 -0000
2006-02-26  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (distclean): New rule.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24