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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations) (download)
Sun Mar 12 10:13:31 2006 UTC (18 years, 8 months ago) by wakaba
Branch: MAIN
Changes since 1.4: +9 -4 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	12 Mar 2006 10:03:19 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* daf.pl: Don't require |Test| modules for bootstrap.

++ manakai/lib/Message/Util/ChangeLog	12 Mar 2006 10:09:14 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (loadResource): Sets the |srinfo| parameter
	of the |addTypeURI| method call.
	(addTypeURI): The |srinfo| parameter is added.  Sets
	the |srinfo| parameter of the |isSubsetOfURI| and |mergeAsAlias|
	method calls.

++ manakai/lib/Message/Util/DIS/ChangeLog	12 Mar 2006 10:09:53 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* Perl.dis (getPerlModuleMemberCode): Write charset
	category properties.

++ manakai/lib/Message/URI/ChangeLog	12 Mar 2006 10:13:28 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* Generic.pm: Added to the CVS repository since
	it is referenced from |../DOM/DOMCore.pm| and therefore
	it is required to execute the |daf| script.

++ manakai/lib/Message/Charset/ChangeLog	12 Mar 2006 10:06:26 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* Encode.dis (createMCDecodeHandle): New
	parameter |onerror| is added.  Charsets |cs:XML.utf-8|, |cs:XML.utf-16|,
	and |xml-auto-charset:| are implemented.  Throws an error
	if the charset is not supported.
	(getURIFromCharsetName, getCharsetNameFromURI): Algorithmic URIs are
	supported.
	(onerror): Removed from |onoctetstreamerror|.
	(MCXMLDecodeHandle): Removed.
	(inputEncoding, hasBOM): New attributes.

++ manakai/lib/manakai/ChangeLog	12 Mar 2006 10:12:19 -0000
2006-03-12  Wakaba  <wakaba@suika.fam.cx>

	* Charset.dis: The |c:key| property is added to some resources.
	Typos are fixed.
	(icharset:utf-16be, icharset:utf-16le): New charsets.
	(cs:Perl.utf-16be, cs:Perl.utf-16le): New charsets.
	(cs:Perl.ucs-2be, cs:Perl.ucs-2le): New charsets.
	(cs:Perl.utf-32be, cs:Perl.utf-32le): New charsets.
	(cs:ErrorCategory): New type.  Error categories are added.
	(cs:noBOMVariant): New properties.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24