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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations) (download)
Mon Apr 3 12:53:22 2006 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.9: +6 -4 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	3 Apr 2006 11:17:32 -0000
2006-04-03  Wakaba  <wakaba@suika.fam.cx>

	* daf.pl (perl-pm): Sets the |impl| argument
	of the |pl_generate_perl_module| method.

++ manakai/lib/Message/Util/ChangeLog	3 Apr 2006 12:18:05 -0000
2006-04-03  Wakaba  <wakaba@suika.fam.cx>

	* Grove.dis (mg:mutations): It is changed from array
	reference to hash reference.

	* PerlCode.dis (replaceVariable): The |pc2:| namespace
	support.
	(IN_USE_NODE_ERR, BAD_CHILD_ERR): Removed.
	(createPCIf, createPCPackage): New methods.
	(createPCFile): Renamed from |createPerlFile|.  Set
	configuration parameters.

++ manakai/lib/Message/Util/DIS/ChangeLog	3 Apr 2006 12:25:32 -0000
2006-04-03  Wakaba  <wakaba@suika.fam.cx>

	* DNLite.dis (plImplementation): Removed.

	* Perl.dis (plImplementation): Removed.
	(plCodeFragment): Changed from attribute to method.
	(plValueCodeFragment, plCodeFragment): The |factory|
	parameter is added.
	(plPreprocessPerlCode, plPreprocessPerlStatement, plAppendThrow):
	The |factory| parameter is added.
	(ManakaiDOM:InputNormalize, dis:GetNodeProp): Removed.
	(plIsDefined): Removed.
	($NS_URI_NO_NULL): Removed.
	(setDefaultValue): Removed.

++ manakai/lib/Message/DOM/ChangeLog	3 Apr 2006 12:04:56 -0000
2006-04-03  Wakaba  <wakaba@suika.fam.cx>

	* DOMMain.dis (GetPropNode, CheckReadOnly): Removed.

	* Node.dis (cfg:dtd-default-attribute): The configuration
	parameter |cfg:dtd-default-attributes| is renamed
	as |cfg:dtd-default-attribute|.
	(Roles): Definitions are changed so that classes
	that implement those classes MUST implement the |Node|
	and its subinterfaces.
	(cfg:dtd-attribute-type): New configuration parameter.

	* Document.dis (adoptNode): Don't throw exception
	if |strictErrorChecking| is |false|.

	* Element.dis (setAttribute, setAttributeNS): Don't
	set [attribute type] if the |cfg:dtd-attribute-type|
	configuration parameter is set to |false|.
	(removeAttribute, removeAttributeNS, removeAttributeNode): Don't
	regenerate default attribute nodes if the |cfg:dtd-default-attribute|
	configuration parameter is set to |false|.

++ manakai/lib/manakai/ChangeLog	3 Apr 2006 12:26:00 -0000
2006-04-03  Wakaba  <wakaba@suika.fam.cx>

	* DISLang.dis (ManakaiDOM:InputNormalize): Removed.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24