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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations) (download)
Sun Sep 25 14:53:02 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.12: +84 -37 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	25 Sep 2005 14:45:44 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* dac.pl, dac2pm.pl, mkdisdump.pl: Parameters "--dis-file-suffix",
	"--daem-file-suffix", "--search-path-catalog-file-name", and
	"--search-path" added.  New dae and daem database format support.
	(dac_search_file_stem): New function.

++ manakai/lib/Message/Markup/ChangeLog	25 Sep 2005 14:47:09 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/Message/Util/ChangeLog	25 Sep 2005 14:50:33 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (RESOURCE_NOT_DEFINED_ERR): New error code.
	(getResource): New "dae" and "daem" database format support.
	(DISResourceList): New type.
	(uriRef, ownerModuleURI, ownerModuleURIRef): New attributes.
	(addChildResource, addDynamicChildResource): New methods.
	(getChildResourceList, getDynamicChildResourceList): New method.
	(getChildResourceListByType): New method.
	(parentResource, dynamicParentResource): New attributes.

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/Message/Util/DIS/ChangeLog	25 Sep 2005 14:52:26 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Perl.dis (plLoadDISDatabase): New "moduleResolver" parameter
	added.
	(plStore): New "moduleResolver" parameter added.
	(plLoadDISDatabaseModule): New method.

++ manakai/lib/Message/DOM/ChangeLog	25 Sep 2005 14:47:15 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

++ manakai/lib/manakai/ChangeLog	25 Sep 2005 14:46:50 -0000
2005-09-25  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (DAC_SUFFIX): Changed to ".dae".
	(DAEM_SUFFIX): New.

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3     use Message::Util::QName::Filter {
4     DIS => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#>,
5     dis => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
6     ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
7 wakaba 1.3 swcfg21 => q<http://suika.fam.cx/~wakaba/archive/2005/swcfg21#>,
8 wakaba 1.1 };
9    
10     use Getopt::Long;
11     use Pod::Usage;
12 wakaba 1.4 my %Opt = ();
13 wakaba 1.1 GetOptions (
14     'db-base-directory-path=s' => \$Opt{db_base_path},
15 wakaba 1.11 'debug' => \$Opt{debug},
16 wakaba 1.13 'dis-file-suffix=s' => \$Opt{dis_suffix},
17     'daem-file-suffix=s' => \$Opt{daem_suffix},
18 wakaba 1.1 'for=s' => \$Opt{For},
19     'help' => \$Opt{help},
20 wakaba 1.4 'input-db-file-name=s' => \$Opt{input_file_name},
21 wakaba 1.1 'output-file-name=s' => \$Opt{output_file_name},
22 wakaba 1.2 'search-path|I=s' => sub {
23     shift;
24     my @value = split /\s+/, shift;
25     while (my ($ns, $path) = splice @value, 0, 2, ()) {
26 wakaba 1.4 unless (defined $path) {
27     die qq[$0: Search-path parameter without path: "$ns"];
28     }
29 wakaba 1.2 push @{$Opt{input_search_path}->{$ns} ||= []}, $path;
30     }
31     },
32 wakaba 1.4 'search-path-catalog-file-name=s' => sub {
33     shift;
34     require File::Spec;
35     my $path = my $path_base = shift;
36     $path_base =~ s#[^/]+$##;
37     $Opt{search_path_base} = $path_base;
38     open my $file, '<', $path or die "$0: $path: $!";
39     while (<$file>) {
40     if (s/^\s*\@//) { ## Processing instruction
41     my ($target, $data) = split /\s+/;
42     if ($target eq 'base') {
43     $Opt{search_path_base} = File::Spec->rel2abs ($data, $path_base);
44     } else {
45     die "$0: $target: Unknown target";
46     }
47     } elsif (/^\s*\#/) { ## Comment
48     #
49     } elsif (/\S/) { ## Catalog entry
50     s/^\s+//;
51     my ($ns, $path) = split /\s+/;
52     push @{$Opt{input_search_path}->{$ns} ||= []},
53     File::Spec->rel2abs ($path, $Opt{search_path_base});
54     }
55     }
56     ## NOTE: File paths with SPACEs are not supported
57     ## NOTE: Future version might use file: URI instead of file path.
58     },
59 wakaba 1.1 'undef-check!' => \$Opt{no_undef_check},
60 wakaba 1.13 'verbose!' => \$Opt{verbose},
61 wakaba 1.1 ) or pod2usage (2);
62     pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
63     $Opt{file_name} = shift;
64     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
65     pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{output_file_name};
66     $Opt{no_undef_check} = defined $Opt{no_undef_check}
67     ? $Opt{no_undef_check} ? 0 : 1 : 0;
68 wakaba 1.13 $Opt{dis_suffix} = '.dis' unless defined $Opt{dis_suffix};
69     $Opt{daem_suffix} = '.daem' unless defined $Opt{daem_suffix};
70 wakaba 1.11 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
71 wakaba 1.1
72 wakaba 1.13 sub status_msg ($) {
73     my $s = shift;
74     $s .= "\n" unless $s =~ /\n$/;
75     print STDERR $s;
76     }
77    
78     sub status_msg_ ($) {
79     my $s = shift;
80     print STDERR $s;
81     }
82    
83     sub verbose_msg ($) {
84     my $s = shift;
85     $s .= "\n" unless $s =~ /\n$/;
86     print STDERR $s if $Opt{verbose};
87     }
88    
89     sub verbose_msg_ ($) {
90     my $s = shift;
91     print STDERR $s if $Opt{verbose};
92     }
93    
94 wakaba 1.10 my $start_time;
95     BEGIN { $start_time = time }
96    
97     use Message::Util::DIS::DNLite;
98 wakaba 1.5
99 wakaba 1.11 my $limpl = $Message::DOM::ImplementationRegistry->get_implementation
100 wakaba 1.1 ({ExpandedURI q<ManakaiDOM:Minimum> => '3.0',
101 wakaba 1.11 '+' . ExpandedURI q<DIS:DNLite> => '1.0'});
102     my $impl = $limpl->get_feature (ExpandedURI q<DIS:Core> => '1.0');
103 wakaba 1.1 my $parser = $impl->create_dis_parser;
104 wakaba 1.10 our $DNi = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0');
105 wakaba 1.1
106     my $db;
107    
108     if (defined $Opt{input_file_name}) {
109 wakaba 1.13 status_msg_ qq<Loading database "$Opt{input_file_name}"...>;
110     $db = $impl->pl_load_dis_database ($Opt{input_file_name}, sub ($$) {
111     my ($db, $mod) = @_;
112     my $ns = $mod->namespace_uri;
113     my $ln = $mod->local_name;
114     verbose_msg qq<Database module <$ns$ln> is requested>;
115     my $name = dac_search_file_path_stem ($ns, $ln, $Opt{daem_suffix});
116     if (defined $name) {
117     return $name.$Opt{daem_suffix};
118     } else {
119     return undef;
120     }
121     });
122     status_msg qq<done>;
123 wakaba 1.1 } else { ## New database
124     $db = $impl->create_dis_database;
125     }
126    
127     require Cwd;
128     my $file_name = Cwd::abs_path ($Opt{file_name});
129 wakaba 1.13 $Opt{db_base_path} = Cwd::abs_path ($Opt{db_base_path})
130     if length $Opt{db_base_path};
131     my $doc = dac_load_module_file ($db, $parser, $file_name, $Opt{db_base_path});
132 wakaba 1.1
133 wakaba 1.7 my $for = $Opt{For};
134 wakaba 1.1 $for = $doc->module_element->default_for_uri unless length $for;
135 wakaba 1.3 $db->get_for ($for)->is_referred ($doc);
136 wakaba 1.11 status_msg qq<Loading module in file "$file_name" for <$for>...>;
137 wakaba 1.1
138 wakaba 1.6 my $ResourceCount = 0;
139 wakaba 1.1 $db->load_module ($doc, sub ($$$$$$) {
140     my ($self, $db, $uri, $ns, $ln, $for) = @_;
141 wakaba 1.10 status_msg '';
142 wakaba 1.11 status_msg qq<Loading module "$ln" for <$for>...>;
143 wakaba 1.6 $ResourceCount = 0;
144 wakaba 1.2
145     ## -- Already in database
146 wakaba 1.1 my $doc = $db->get_source_file ($ns.$ln);
147 wakaba 1.2 return $doc if $doc;
148 wakaba 1.1
149 wakaba 1.2 ## -- Finds the source file
150 wakaba 1.13 my $name = dac_search_file_path_stem ($ns, $ln, $Opt{dis_suffix});
151     if (defined $name) {
152     return dac_load_module_file
153     ($db, $parser, $name.$Opt{dis_suffix}, $Opt{db_base_path});
154 wakaba 1.2 }
155    
156     ## -- Not found
157     return undef;
158 wakaba 1.6 }, for_arg => $for, on_resource_read => sub ($$) {
159     if ((++$ResourceCount % 10) == 0) {
160 wakaba 1.10 status_msg_ "*";
161     status_msg_ " " if ($ResourceCount % (10 * 10)) == 0;
162     status_msg '' if ($ResourceCount % (10 * 50)) == 0;
163 wakaba 1.6 }
164     });
165 wakaba 1.1
166 wakaba 1.3
167 wakaba 1.10 ## Removes reference from document to database
168     our @Document;
169     for my $dis (@Document) {
170     $dis->unlink_from_document;
171     $dis->dis_database (undef);
172     }
173    
174     status_msg '';
175 wakaba 1.9
176 wakaba 1.10 status_msg qq<Reading properties...>;
177 wakaba 1.9 $ResourceCount = 0;
178     $db->read_properties (on_resource_read => sub ($$) {
179     if ((++$ResourceCount % 10) == 0) {
180 wakaba 1.10 status_msg_ "*";
181     status_msg_ " " if ($ResourceCount % (10 * 10)) == 0;
182     status_msg '' if ($ResourceCount % (10 * 50)) == 0;
183 wakaba 1.9 }
184     });
185 wakaba 1.10 status_msg '';
186     status_msg "done";
187 wakaba 1.9
188 wakaba 1.10 status_msg_ qq<Writing file "$Opt{output_file_name}"...>;
189 wakaba 1.13 $db->pl_store ($Opt{output_file_name}, sub ($$) {
190     my ($db, $mod) = @_;
191     my $ns = $mod->namespace_uri;
192     my $ln = $mod->local_name;
193     my $name = dac_search_file_path_stem ($ns, $ln, $Opt{daem_suffix});
194     if (defined $name) {
195     $name .= $Opt{daem_suffix};
196     } elsif (defined ($name = dac_search_file_path_stem
197     ($ns, $ln, $Opt{dis_suffix}))) {
198     $name .= $Opt{daem_suffix};
199     } else {
200     $name = Cwd::abs_path
201     (File::Spec->canonpath
202     (File::Spec->catfile
203     (defined $Opt{input_search_path}->{$ns}->[0]
204     ? $Opt{input_search_path}->{$ns}->[0] : '.',
205     $ln.$Opt{daem_suffix})));
206     }
207     verbose_msg qq<Database module <$ns$ln> is written to "$name">;
208     return $name;
209     });
210 wakaba 1.10 status_msg "done";
211 wakaba 1.9
212 wakaba 1.8 unless ($Opt{no_undef_check}) {
213 wakaba 1.10 status_msg_ "Checking undefined resources...";
214 wakaba 1.8 $db->check_undefined_resource;
215     print STDERR "done\n";
216     }
217    
218 wakaba 1.10 status_msg_ "Closing the database...";
219 wakaba 1.8 $db->free;
220     undef $db;
221 wakaba 1.10 status_msg "done";
222    
223     undef $DNi;
224 wakaba 1.8
225 wakaba 1.10 {
226     use integer;
227     my $time = time - $start_time;
228 wakaba 1.11 status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
229 wakaba 1.10 }
230 wakaba 1.1 exit;
231    
232 wakaba 1.8 END {
233     $db->free if $db;
234     }
235    
236 wakaba 1.1 ## (db, parser, abs file path, abs base path) -> dis doc obj
237     sub dac_load_module_file ($$$;$) {
238     my ($db, $parser, $file_name, $base_path) = @_;
239     require URI::file;
240     my $base_uri = length $base_path ? URI::file->new ($base_path.'/')
241     : 'http://dummy.invalid/';
242     my $file_uri = URI::file->new ($file_name)->rel ($base_uri);
243     my $dis = $db->get_source_file ($file_uri);
244     unless ($dis) {
245 wakaba 1.13 status_msg_ qq<Opening source file <$file_uri>...>;
246 wakaba 1.1 open my $file, '<', $file_name or die "$0: $file_name: $!";
247     $dis = $parser->parse ({character_stream => $file});
248 wakaba 1.10 $dis->flag (ExpandedURI q<swcfg21:fileName> => $file_uri);
249     $dis->dis_database ($db);
250    
251     my $mod = $dis->module_element;
252     if ($mod) {
253     my $qn = $mod->get_attribute_ns (ExpandedURI q<dis:>, 'QName');
254     if ($qn) {
255     my $prefix = $qn->value;
256 wakaba 1.12 $prefix =~ s/^[^:|]*[:|]\s*//;
257     $prefix =~ s/\s+$//;
258 wakaba 1.10 unless (defined $dis->lookup_namespace_uri ($prefix)) {
259     $dis->add_namespace_binding ($prefix => $mod->defining_namespace_uri);
260     }
261     }
262     }
263    
264 wakaba 1.11 my $old_dis = $dis;
265 wakaba 1.10 status_msg_ qq<...>;
266     $dis = $DNi->convert_dis_document_to_dnl_document
267 wakaba 1.11 ($old_dis, database_arg => $db);
268 wakaba 1.10 push @Document, $dis;
269 wakaba 1.11 $old_dis->free;
270 wakaba 1.10
271 wakaba 1.1 $db->set_source_file ($file_uri => $dis);
272 wakaba 1.10 status_msg qq<done>;
273 wakaba 1.1 }
274     $dis;
275     }
276 wakaba 1.13
277     sub dac_search_file_path_stem ($$$) {
278     my ($ns, $ln, $suffix) = @_;
279     require File::Spec;
280     for my $dir ('.', @{$Opt{input_search_path}->{$ns}||[]}) {
281     my $name = Cwd::abs_path
282     (File::Spec->canonpath
283     (File::Spec->catfile ($dir, $ln)));
284     if (-f $name.$suffix) {
285     return $name;
286     }
287     }
288     return undef;
289     } # dac_search_file_path_stem;
290 wakaba 1.1
291     __END__
292    
293     =head1 NAME
294    
295 wakaba 1.10 dac.pl - Creating "dac" Database File from "dis" Source Files
296 wakaba 1.8
297     =head1 SYNOPSIS
298    
299 wakaba 1.10 perl path/to/dac.pl [--input-db-file-name=input.dac] \
300     --output-file-name=out.dac [options...] \
301     input.dis
302 wakaba 1.8 perl path/to/dac.pl --help
303    
304     =head1 DESCRIPTION
305    
306 wakaba 1.10 This script, C<dac.pl>, compiles "dis" source files into "dac"
307     database file. The generated database file can be used
308     in turn to generate Perl module file, for example, by another
309     script C<dac2pm.pl> or can be used to create larger database
310     by specifying its file name as the C<--input-db-file-name>
311     argument of another C<dac.pl> execution.
312 wakaba 1.8
313     This script is part of manakai.
314 wakaba 1.1
315     =head1 OPTIONS
316    
317 wakaba 1.10 =over 4
318    
319     =item I<input.dis> (Required)
320    
321     The unnamed option specifies a file name path of the source "dis" file
322     from which a database is created. This option is required.
323    
324     =item C<--input-db-file-name=I<file-name>> (Default: none)
325    
326     A file path of the base database. This option is optional; if this
327     option is specified, the database file is loaded first
328     and then I<input.dis> file is loaded in the context of it.
329     Otherwise, a new database is created.
330    
331     =item C<--output-file-name=I<file-name>> (Required)
332    
333     The
334    
335     =back
336 wakaba 1.8
337     =head1 SEE ALSO
338    
339     L<bin/dac2pm.pl> - Generating Perl module from "dac" file.
340    
341     L<lib/Message/Util/DIS.dis> - The actual implementation
342     of the "dis" interpretation.
343    
344     =head1 LICENSE
345    
346     Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
347    
348     This program is free software; you can redistribute it and/or
349     modify it under the same terms as Perl itself.
350 wakaba 1.2
351     =cut

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24