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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sat Oct 9 07:54:16 2004 UTC (20 years, 1 month ago) by wakaba
Branch: MAIN
File MIME type: text/plain
New

1 wakaba 1.1 #!/usr/bin/perl -w
2     use strict;
3    
4     our $result;
5    
6     sub output_result ($) {
7     print shift;
8     }
9    
10     ## Source file might be broken
11     sub valid_err ($;%) {
12     my ($s, %opt) = @_;
13     require Carp;
14     output_result $result;
15     if ($opt{node}) {
16     if ($opt{node}->isa ('Message::Markup::SuikaWikiConfig20::Node')) {
17     $s = $opt{node}->node_path (key => 'Name') . ': ' . $s;
18     } elsif ($opt{node}->isa ('Message::DOM::IF::Node')) {
19     $s = 'dom:nodeName ("'.$opt{node}->nodeName . '"): ' . $s;
20     }
21     }
22     Carp::croak ($s);
23     }
24     sub valid_warn ($;%) {
25     my ($s, %opt) = @_;
26     require Carp;
27     if ($opt{node}) {
28     $s = $opt{node}->node_path (key => 'Name') . ': ' . $s;
29     }
30     Carp::carp ($s);
31     }
32    
33     ## Implementation (this script) might be broken
34     sub impl_err (@) {
35     require Carp;
36     Carp::croak (@_);
37     }
38     sub impl_warn (@) {
39     require Carp;
40     Carp::carp (@_);
41     }
42    
43    
44     sub english_number ($;%) {
45     my ($num, %opt) = @_;
46     if ($num == 0) {
47     qq<no $opt{singular}>;
48     } elsif ($num == 1) {
49     qq<a $opt{singular}>;
50     } elsif ($num < 0) {
51     qq<$num $opt{plural}>;
52     } elsif ($num < 10) {
53     [qw/0 1 two three four five seven six seven eight nine/]->[$num] . ' ' .
54     $opt{plural};
55     } else {
56     qq<$num $opt{plural}>;
57     }
58     } # english_number
59    
60     sub english_list ($;%) {
61     my ($list, %opt) = @_;
62     if (@$list > 1) {
63     $opt{connector} = defined $opt{connector}
64     ? qq< $opt{connector} > : qq<, >;
65     join (', ', @$list[0..($#$list-1)]).$opt{connector}.
66     $list->[-1];
67     } else {
68     $list->[0];
69     }
70     } # english_list
71    
72    
73     sub perl_comment ($) {
74     my $s = shift;
75     $s =~ s/\n/\n## /g;
76     $s =~ s/\n## $/\n/s;
77     $s .= "\n" unless $s =~ /\n$/;
78     $s = q<## > . $s;
79     $s;
80     }
81    
82     sub perl_statement ($) {
83     my $s = shift;
84     $s . ";\n";
85     }
86    
87     sub perl_assign ($@) {
88     my ($left, @right) = @_;
89     $left . ' = ' . (@right > 1 ? '(' . join (', ', @right) . ')' : $right[0]);
90     }
91    
92     sub perl_name ($;%) {
93     my ($s, %opt) = @_;
94     valid_err q<Uninitialized value in name>, node => $opt{node}
95     unless defined $s;
96     $s =~ s/[- ](.|$)/uc $1/ge;
97     $s = ucfirst $s if $opt{ucfirst};
98     $s = uc $s if $opt{uc};
99     $s;
100     }
101    
102     sub perl_internal_name ($) {
103     my $s = shift;
104     '_' . perl_name $s;
105     }
106    
107     sub perl_inherit ($;$) {
108     my ($isa, $mod) = @_;
109     if ($mod) {
110     perl_statement 'push ' . perl_var (type => '@',
111     local_name => 'ISA',
112     package => {full_name => $mod}) .
113     ', ' . perl_list (@$isa);
114     } else {
115     perl_statement 'push our @ISA, ' . perl_list (@$isa);
116     }
117     }
118    
119     sub perl_sub (%) {
120     my %opt = @_;
121     my $r = 'sub ';
122     $r .= $opt{name} . ' ' if $opt{name};
123     $r .= '(' . $opt{prototype} . ') ' if defined $opt{prototype};
124     $r .= "{\n";
125     $r .= $opt{code};
126     $r .= "}\n";
127     }
128    
129     sub perl_cases (@) {
130     my $r = '';
131     while (my ($when, $code) = splice @_, 0, 2) {
132     $r .= qq<} elsif ($when) {\n$code\n>;
133     }
134     $r =~ s/^\} els//;
135     $r .= qq<}\n> if $r;
136     $r = "\n" . $r if $r;
137     $r;
138     }
139    
140     sub perl_var (%) {
141     my %opt = @_;
142     my $r = $opt{type} || ''; # $, @, *, &, $# or empty
143     $r = $opt{scope} . ' ' . $r if $opt{scope}; # my, our or local
144     $r .= perl_package_name (%{$opt{package}}) . '::' if $opt{package};
145     $r .= $opt{local_name};
146     $r;
147     }
148    
149     {
150     use re 'eval';
151     my $RegBlockContent;
152     $RegBlockContent = qr/(?>[^{}\\]*)(?>(?>[^{}\\]+|\\.|\{(??{$RegBlockContent})\})*)/s;
153     sub perl_code ($;%);
154     sub perl_code ($;%) {
155     my ($s, %opt) = @_;
156     valid_err q<Uninitialized value in perl_code>,
157     node => $opt{node} unless defined $s;
158     $s =~ s[<Q:([^<>]+)>|\b(null|true|false)\b][
159     my ($q, $l) = ($1, $2);
160     if (defined $q) {
161     if ($q =~ /\}/) {
162     valid_warn qq<Possible typo in the QName: "$q">;
163     }
164     perl_literal (expanded_uri ($q));
165     } else {
166     {true => 1, false => 0, null => 'undef'}->{$l};
167     }
168     ]ge;
169     ## TODO: Ensure Message::Util::Error imported if try.
170     ## ISSUE: __FILE__ & __LINE__ will break if multiline substition happens.
171     $s =~ s{
172     \b__([A-Z]+)
173     (?:\{($RegBlockContent)\})?
174     __\b
175     }{
176     my ($name, $data) = ($1, $2);
177     my $r;
178     if ($name eq 'DEEP') { ## Deep Method Call
179     $r = 'do { local $Error::Depth = $Error::Depth + 1;' . perl_code ($data) .
180     '}';
181     } elsif ($name eq 'FILE' or $name eq 'LINE' or $name eq 'PACKAGE') {
182     $r = qq<__${name}__>;
183     } else {
184     valid_err qq<Preprocessing macro "$name" not supported>;
185     }
186     $r;
187     }goex;
188     $s;
189     }
190     }
191    
192     {my $f = 0;
193     sub perl_code_source ($%) {
194     my ($s, %opt) = @_;
195     sprintf qq<\n#line %d "File <%s> Node <%s>"\n%s\n> .
196     qq<#line 1 "File <%s> Chunk #%d"\n>,
197     $opt{line} || 1, $opt{file} || '',
198     $opt{path} || 'x:unknown ()', $s,
199     $opt{file} || '', ++$f;
200     }}
201    
202     sub perl_code_literal ($) {
203     my $s = shift;
204     bless \$s, '__code';
205     }
206    
207     sub perl_literal ($) {
208     my $s = shift;
209     unless (defined $s) {
210     impl_warn q<Undefined value is passed to perl_literal ()>;
211     return q<undef>;
212     } elsif (ref $s eq 'ARRAY') {
213     return q<[> . perl_list (@$s) . q<]>;
214     } elsif (ref $s eq 'HASH') {
215     return q<{> . perl_list (%$s) . q<}>;
216     } elsif (ref $s eq 'CODE') {
217     impl_err q<CODE reference cannot be serialized>;
218     } elsif (ref $s eq '__code') {
219     return $$s;
220     } else {
221     ## NOTE: Don't change quote char - perl_code depends this quote.
222     $s =~ s/(['\\])/\\$1/g;
223     return q<'> . $s . q<'>;
224     }
225     }
226    
227     sub perl_list (@) {
228     join ', ', map perl_literal $_, @_;
229     }
230    
231     sub perl_if ($$;$) {
232     my ($condition, $true, $false) = @_;
233     my $if = q<if>;
234     unless (defined $true) {
235     $if = q<unless>;
236     $true = $false;
237     $false = undef;
238     }
239     for ($true, $false) {
240     $_ = "\n" . $_ if $_ and /\A#\w+/;
241     }
242     my $r = qq<\n$if ($condition) {\n>.
243     qq< $true>.
244     qq<}>;
245     if (defined $false) {
246     $r .= qq< else {\n>.
247     qq< $false>.
248     qq<}>;
249     }
250     $r .= qq<\n>;
251     $r;
252     } # perl_if
253    
254    
255     sub pod_comment (@) {
256     (q<=begin comment>, @_, q<=end comment>);
257     }
258    
259     sub pod_block (@) {
260     my @v = grep ((defined and length), @_);
261     join "\n\n", '', ($v[0] =~ /^=/ ? () : '=pod'), @v, '=cut', '';
262     }
263    
264     sub pod_head ($$) {
265     my ($level, $s) = @_;
266     $s =~ s/\s+/ /g;
267     if ($level < 5) {
268     '=head' . $level . ' ' . $s; ## pod has only head1-head4.
269     } else {
270     'B<' . $s . '>';
271     }
272     }
273    
274     sub pod_list ($@) {
275     my $m = shift;
276     ('=over ' . $m, @_, '=back');
277     }
278    
279     sub pod_item ($) {
280     my ($s) = @_;
281     valid_err q<Uninitialized value in pod_item> unless defined $s;
282     $s =~ s/\s+/ /g;
283     '=item ' . $s;
284     }
285    
286     sub pod_pre ($) {
287     my $s = shift;
288     return '' unless defined $s;
289     $s =~ s/\n/\n /g;
290     ' ' . $s;
291     }
292    
293     sub pod_para ($) {
294     my $s = shift;
295     return '' unless defined $s;
296     $s =~ s/\n\s+/\n/g;
297     $s;
298     }
299    
300     sub pod_paras ($) {
301     shift;
302     }
303    
304     sub pod_cdata ($) {
305     my $s = shift;
306     $s =~ s/([<>])/{'<' => 'E<lt>', '>' => 'E<gt>'}->{$1}/ge;
307     $s;
308     }
309    
310     sub pod_code ($) {
311     my $s = shift;
312     $s =~ s/([<>])/{'<' => 'E<lt>', '>' => 'E<gt>'}->{$1}/ge;
313     qq<C<$s>>;
314     }
315    
316     sub pod_em ($) {
317     my $s = shift;
318     $s =~ s/([<>])/{'<' => 'E<lt>', '>' => 'E<gt>'}->{$1}/ge;
319     qq<I<$s>>;
320     }
321    
322     sub pod_dfn ($) {
323     my $s = shift;
324     $s =~ s/([<>])/{'<' => 'E<lt>', '>' => 'E<gt>'}->{$1}/ge;
325     qq<I<$s>X<$s>>;
326     }
327    
328     sub pod_char (%) {
329     my %opt = @_;
330     if ($opt{name}) {
331     if ($opt{name} eq 'copy') {
332     qq<E<169>>;
333     } else {
334     qq<E<$opt{name}>>;
335     }
336     } else {
337     impl_err q<Bad parameter for "pod_char">;
338     }
339     } # pod_char
340    
341     sub pod_uri ($) {
342     my $uri = shift;
343     qq<E<lt>${uri}E<gt>>;
344     } # pod_uri
345    
346     sub pod_mail ($) {
347     my $mail = shift;
348     qq<E<lt>${mail}E<gt>>;
349     } # pod_mail
350    
351     sub pod_link (%) {
352     my %opt = @_;
353     if ($opt{label}) {
354     $opt{label} .= '|';
355     } else {
356     $opt{label} = '';
357     }
358     if ($opt{section}) {
359     qq<L<$opt{label}/"$opt{section}">>;
360     } elsif ($opt{module}) {
361     qq<L<$opt{label}$opt{module}>>;
362     } else {
363     impl_err q<Bad parameter for "pod_link">;
364     }
365     }
366    
367    
368     sub muf_template ($) {
369     my $s = shift;
370     $s =~ s{<Q:([^<>]+)>}{ ## QName
371     expanded_uri ($1)
372     }ge;
373     $s;
374     }
375    
376     sub section (@) {
377     my @r;
378     while (my ($t, $s) = splice @_, 0, 2) {
379     if ($t eq 'req' and (not defined $s or not length $s)) {
380     return ();
381     } elsif (defined $s and length $s) {
382     push @r, $s;
383     }
384     }
385     return @r;
386     }
387    
388    
389     sub rfc3339_date ($) {
390     my @time = gmtime shift;
391     sprintf q<%04d-%02d-%02dT%02d:%02d:%02d+00:00>,
392     $time[5] + 1900, $time[4] + 1, @time[3,2,1,0];
393     }
394    
395     sub version_date ($) {
396     my @time = gmtime shift;
397     sprintf q<%04d%02d%02d.%02d%02d>,
398     $time[5] + 1900, $time[4] + 1, @time[3,2,1];
399     }
400    
401    
402    
403     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24