File Coverage

blib/lib/Acme/Comment.pm
Criterion Covered Total %
statement 55 61 90.1
branch 28 30 93.3
condition 7 9 77.7
subroutine 6 7 85.7
pod 0 1 0.0
total 96 108 88.8


line stmt bran cond sub pod time code
1             package Acme::Comment;
2              
3 160     160   5521225 use strict;
  160         411  
  160         6902  
4 160     160   325229 use Filter::Simple;
  160         12054270  
  160         1294  
5              
6             BEGIN {
7 160     160   13523 use vars qw($VERSION);
  160         378  
  160         8365  
8 160     160   7032 $VERSION = '1.04';
9             }
10              
11             my $TypeCount = 0;
12             my $Type = 'C';
13             my $Conf;
14              
15 160     160   1087 { no warnings;
  160         346  
  160         305640  
16             $Conf = {
17             C => {
18             own_line => 1,
19             start => quotemeta '/*',
20             end => quotemeta '*/',
21             one_line => 0,
22             },
23             HTML => {
24             own_line => 1,
25             start => quotemeta '',
27             one_line => 0,
28             },
29             RUBY => {
30             own_line => 1,
31             start => quotemeta '=begin',
32             end => quotemeta '=end',
33             one_line => 0,
34             single => '#',
35             },
36             JAVA => {
37             own_line => 1,
38             start => quotemeta '/*',
39             end => quotemeta '*/',
40             one_line => 0,
41             single => quotemeta '//',
42             },
43             PASCAL => {
44             own_line => 1,
45             start => quotemeta '(*',
46             end => quotemeta '*)',
47             one_line => 0,
48             },
49              
50             ALGOL => {
51             own_line => 1,
52             start => quotemeta "'comment'",
53             end => quotemeta ';',
54             one_line => 0,
55             },
56              
57             HUGO => {
58             own_line => 1,
59             start => quotemeta '!\\',
60             end => quotemeta '\!',
61             one_line => 0,
62             single => '!(?!\\\\)',
63             },
64              
65             BASIC => {
66             single => q['],
67             },
68             PILOT => {
69             single => quotemeta '\/\/',
70             },
71             BLUE => {
72             single => '(?:==)|(?:--)',
73             },
74              
75             INTERCAL => {
76             single => '(?:\(\d+\)\s*)?DO NOTE THAT',
77             },
78             FORTRAN => {
79             single => quotemeta '!',
80             },
81             PERL => {
82             single => quotemeta q[#],
83             },
84             ALAN => {
85             single => "--",
86             },
87             ORTHOGONAL => {
88             single => quotemeta ";",
89             },
90             FOCAL => {
91             single => "comment",
92             },
93             LATEX => {
94             single => quotemeta "%",
95             },
96             FOXBASE => {
97             single => '(?:\*)|(?:&&)',
98             }
99             };
100              
101              
102             ### the comment styles for ADA and Basic are the same ###
103             for my $type(qw|ADA|) { $Conf->{$type} = $Conf->{'BASIC'} }
104              
105             for my $type(qw|POSTSCRIPT|) { $Conf->{$type} = $Conf->{'LATEX'} }
106              
107             for my $type(qw|ADVSYS LISP SCHEME|) { $Conf->{$type} = $Conf->{'ORTHOGONAL'} }
108              
109             for my $type(qw|EIFFEL HASKELL|) { $Conf->{$type} = $Conf->{'ALAN'} }
110              
111             for my $type(qw|BETA BLISS JOY VAR'AQ|) { $Conf->{$type} = $Conf->{'PASCAL'} }
112              
113             for my $type(qw|B PL/I CHILL|) { $Conf->{$type} = $Conf->{'C'} }
114              
115             for my $type(qw|C++ PHP C# CLEAN ELASTIC GUILE|) { $Conf->{$type} = $Conf->{'JAVA'} }
116              
117             for my $type(qw|PYTHON PARROT AWK UNLAMBDA E ICON|) { $Conf->{$type} = $Conf->{'PERL'} }
118             }
119              
120             sub import {
121             my $package = shift;
122             my %args = @_;
123              
124             if(@_%2){
125             die "Incomplete set of arguments to $package\n"
126             }
127              
128             ### see if there are any arguments, if not, we default to the C comment style ###
129             if( keys %args ) {
130              
131             ### check if the user requested a certain type of comments ###
132             if( $args{type} ) {
133              
134             ### and check if it even exists ###
135             if( $Conf->{ uc $args{type} } ) {
136             $Type = uc $args{type};
137              
138             $Conf->{$Type}->{own_line} = $args{own_line} if defined $args{own_line};
139             $Conf->{$Type}->{one_line} = $args{one_line} if defined $args{one_line};
140              
141             ### otherwise die with an error ###
142             } else {
143             die "Requested an unsupported type $args{type} for Acme::Comment\n";
144             }
145              
146             ### otherwise, define a new type for the user ###
147             } else {
148             $Type = ++$TypeCount;
149              
150             unless( (defined $args{start} and defined $args{end}) or defined $args{single} ) {
151             die "You need to specify both start and end tags OR a single line comment!\n";
152             } else {
153             if( defined $args{start} and defined $args{end} and $args{start} eq $args{end} ) {
154             die "Start and end tags must be different!\n";
155             }
156              
157             $Conf->{$TypeCount}->{start} = quotemeta($args{start}) if defined $args{start};
158             $Conf->{$TypeCount}->{end} = quotemeta($args{end}) if defined $args{end};
159             $Conf->{$TypeCount}->{single} = quotemeta($args{single}) if defined $args{single}
160             }
161              
162             $Conf->{$TypeCount}->{own_line} = defined $args{own_line}
163             ? $args{own_line}
164             : 1;
165              
166             $Conf->{$TypeCount}->{one_line} = defined $args{one_line}
167             ? $args{one_line}
168             : 0;
169              
170             }
171              
172             ### no arguments, Let's take the default C comment style ###
173             }
174             }
175              
176             sub parse {
177              
178             #use Data::Dumper;
179             #print scalar @_;
180             #die Dumper \@_;
181              
182 160     160 0 671 my $str = shift;
183              
184 160 100       1470 my $start = $Conf->{$Type}->{start} if $Conf->{$Type}->{start};
185 160 100       955 my $end = $Conf->{$Type}->{end} if $Conf->{$Type}->{end};
186 160 100       1205 my $single = $Conf->{$Type}->{single} if $Conf->{$Type}->{single};
187              
188 160         392 my ($rdel,$ldel);
189 0         0 my ($roneline, $loneline);
190              
191 160 100 66     1558 if( $start && $end ) {
192             ### having the comments on their own line is recommended
193             ### to avoid ambiguity -kane
194 72         286 $roneline = '\s*' . $end . '\s*$';
195 72         233 $loneline = '^\s*' . $start . '\s*';
196              
197 72 100       436 if( $Conf->{$Type}->{own_line} ){
198 36         96 $rdel = '^' . $roneline;
199 36         94 $ldel = $loneline . '$';
200             } else {
201 36         81 $rdel = $roneline;
202 36         2578 $ldel = $loneline;
203             }
204             }
205              
206             ### loop counter ###
207 160         397 my $i;
208              
209             ### tag counter ###
210             my $counter;
211              
212             ### line number of the last found comment open ###
213 0         0 my $lastopen;
214              
215             ### return value container ###
216 0         0 my @return;
217              
218 160         2518 for my $line (split/\n/, $str) {
219             ### increase line counter ###
220 5587         6295 $i++;
221              
222             ### if there is a single line comment available ##
223 5587 100       11096 if($single) {
224 2992 100       16244 if( $line =~ m|^\s*$single| ) {
225 164         1481 push @return, "";
226 164         440 next;
227             }
228             }
229              
230             ### check if we have multiline comment options ###
231 5423 100 66     22002 if($roneline && $loneline) {
232             ### check if we are allowed to have comments on one line
233             ### and if so, see if they match
234 4895 100       11829 if( $Conf->{$Type}->{one_line} ) {
235 2949 100       13929 if( $line =~ /$loneline.*?$roneline/) {
236 105         217 push @return, "";
237 105         213 next;
238             }
239             }
240              
241             ### if we find an opening tag, add to the counter
242             ### and mark the line number
243 4790 100       20975 if( $line =~ /$ldel/ ) {
    100          
244 382         527 $lastopen = $i;
245 382         480 $counter++;
246 382         606 push @return, "";
247 382         1174 next;
248              
249             ### if we find a closing tag, decreate the counter
250             ### if counter was already at zero, there's a syntax error
251             } elsif ( $line =~ /$rdel/ ) {
252 382 50       866 unless($counter) {
253 0         0 die "Missing opening comment for closing comment on line $i\n";
254             }
255 382         442 $counter--;
256 382         635 push @return, "";
257 382         744 next;
258             }
259             }
260              
261             ### if we have a counter, we're still inside a comment
262             ### so dont add it then.. if the line is just whitespace
263             ### we might as well ingore it too
264 4554 100 100     22887 unless($counter or $line =~ /^\s*$/) {
265 2270         3469 push @return, $line ;
266 2270         3369 next;
267             } else {
268 2284         4098 push @return, "";
269 2284         4434 next;
270             }
271             }
272              
273             ### if we have a counter left after parsing all the lines
274             ### we must have an opening tag (or more) that dont have a closing tag
275 160 50       1503 if($counter){ die "No closing bracket found for opening comment at line $lastopen\n" }
  0         0  
276              
277             ### Filter::Simple demands we return $_ ###
278 160         1438 $_ = join "\n", @return;
279              
280 160         1122 return $_;
281             }
282              
283 0     0     sub _gimme_conf { return $Conf };
284              
285             FILTER_ONLY executable => sub { parse($_); };
286              
287              
288             1;
289              
290             =pod
291              
292             =head1 NAME
293              
294             Acme::Comment
295              
296             =head1 SYNOPSIS
297              
298             use Acme::Comment type=>'C++', own_line=>1;
299              
300             /*
301             if (ref $mod) {
302             $bar->{do}->blat(msg => 'blarg');
303             eval {
304              
305             i'm sooo sick of this time for some coffee
306              
307             */
308              
309             // I prefer beer. --sqrn
310              
311             =head1 DESCRIPTION
312              
313             Acme::Comment allows multi-line comments which are filtered out.
314             Unlike the pseudo multi-line comment C, the code being
315             commented out need not be syntactically valid.
316              
317             =head1 USE
318              
319             Acme::Comment contains several different commenting styles.
320              
321             Styles may be specified by the C argument, or by C and
322             C and manipulated with C and C.
323              
324             Styles may contain multi-line comments and single-line comments.
325             Perl, for example, has single-line comments in the form of C<#>.
326              
327             C, on the other hand, has multi-line comments which begin with
328             C and end with C<*/>.
329              
330             With multi-line comments, leaving out a begin or an end comment
331             will cause an error.
332              
333             Both types of comments may only be preceded on a line by whitespace.
334              
335             =head2 own_line
336              
337             By default, C is true, which means that multi-line comments may not
338             be followed by any characters other than whitespace on the same line.
339             This is the safest option if you think your code may contain the
340             comment characters (perhaps in a regex). If you disable it, other
341             characters are allowed on the line after the starting delimiter, but these
342             characters will be ignored. The closing delimiter cannot be followed by
343             any other characters.
344              
345             Thus, in the following example, C<$foo> would be set to 1.
346              
347             /* This is my real comment.
348             */
349             $foo = 1;
350              
351             If you wish to change this option, you must specify either a C or
352             C and C.
353              
354             =head2 one_line
355              
356             By default, this is set to false, which means that multi-line comments
357             may not end on the same line in which they begin. Turning this on
358             allows the following syntax:
359              
360             /* comment */
361              
362             If you wish to change this option, you must specify either a C or
363             C and C.
364              
365             =head2 C and C
366              
367             The C and C arguments allow you to supply your own commenting
368             pattern instead of one of the ones available with C. It is not
369             valid to provide the same pattern for both C and C.
370              
371             You cannot specify both C and C and C, and C
372             and C must both be provided if you provide one of them.
373              
374             =head2 types
375              
376             The C argument specifies what language style should be used.
377             Only one language style may be specified.
378              
379             =over 4
380              
381             =item * Ada
382              
383             Single-line comments begin with C<'>.
384              
385             =item * Advsys
386              
387             Advsys single-line comments begin with C<;>.
388              
389             =item * Alan
390              
391             Single-line comments start with C<-->.
392              
393             =item * Algol
394              
395             Multi-line comments begin with C<'comment'> and end with C<;>.
396              
397             NOTE: You should not use Algol with C set to 0:
398             The source filter will take a C<;> to be an ending tag for your
399             comments, regardless of where it is.
400              
401             =item * AWK
402              
403             Single-line comments use C<#>.
404              
405             =item * B
406              
407             Multi-line comments use C and C<*/>.
408              
409             =item * Basic
410              
411             Single-line comments begin with C<'>.
412              
413             =item * Beta
414              
415             Multi-line comments use C<(*> and C<*)>.
416              
417             =item * Bliss
418              
419             Multi-line comments use C<(*> and C<*)>.
420              
421             =item * Blue
422              
423             Single-line comments use either C<==> or C<-->.
424              
425             =item * C
426              
427             The default for Acme::Comment is C-style multi-line commenting
428             with C and C<*/>. However, if you wish to change C
429             or C, you must explicitly specify the type.
430              
431             =item * C++
432              
433             C++ multi-line style uses C and C<*/>. Single-line uses C.
434              
435             =item * C#
436              
437             C# multi-line style uses C and C<*/>. Single-line uses C.
438              
439             =item * Chill
440              
441             Multi-line comments use C and C<*/>.
442              
443             =item * Clean
444              
445             Clean multi-line style uses C and C<*/>. Single-line uses C.
446              
447             =item * E
448              
449             Single-line comments use C<#>.
450              
451             =item * Eiffel
452              
453             Single-line comments start with C<-->.
454              
455             =item * Elastic
456              
457             Elastic multi-line style uses C and C<*/>. Single-line uses C.
458              
459             =item * Focal
460              
461             Single-line comments start with C.
462              
463             =item * Fortran
464              
465             Single-line comments use C.
466              
467             =item * Guile
468              
469             Guile multi-line style uses C and C<*/>. Single-line uses C.
470              
471             =item * Haskell
472              
473             Single-line comments start with C<-->.
474              
475             =item * HTML
476              
477             HTML style has multi-line commenting in the form of C!--> and
478             C<--E>.
479              
480             =item * Hugo
481              
482             Multi-line comments begin with C and end with C<\!>. Single-line
483             comments are not implemented due to their similarity with multi-line
484             comments.
485              
486             =item * Icon
487              
488             Single-line comments use C<#>.
489              
490             =item * Intercal
491              
492             Single-line comments are marked with C and may optionally
493             be preceded by a line number in the following syntax:
494             C<(23) DO NOTE THAT>.
495              
496             =item * Java
497              
498             Java multi-line style uses C and C<*/>. Single-line uses C.
499              
500             =item * Joy
501              
502             Multi-line comments use C<(*> and C<*)>.
503              
504             =item * LaTeX
505              
506             Single-line comments use C<%>.
507              
508             =item * LISP
509              
510             LISP single-line comments begin with C<;>.
511              
512             =item * Orthogonal
513              
514             Orthogonal single-line comments begin with C<;>.
515              
516             =item * Parrot
517              
518             Single-line comments use C<#>.
519              
520             =item * Pascal
521              
522             Multi-line comments use C<(*> and C<*)>.
523              
524             =item * Perl
525              
526             Single-line comments use C<#>.
527              
528             =item * PHP
529              
530             PHP multi-line style uses C and C<*/>. Single-line uses C.
531              
532             =item * Pilot
533              
534             Single-line comments in the syntax C<\/\/> are supported.
535              
536             =item * PL/I
537              
538             Multi-line comments use C and C<*/>.
539              
540             =item * PostScript
541              
542             Single-line comments use C<%>.
543              
544             =item * Python
545              
546             Single-line comments use C<#>.
547              
548             =item * Ruby
549              
550             Ruby multi-line comments begin with C<=begin> and end with
551             C<=end>. Single-line comments use C<#>.
552              
553             =item * Scheme
554              
555             Scheme single-line comments begin with C<;>.
556              
557             =item * Unlambda
558              
559             Single-line comments use C<#>.
560              
561             =item * Var'aq
562              
563             Multi-line comments use C<(*> and C<*)>.
564              
565             =back
566              
567             =head1 CAVEATS
568              
569             Because of the way source filters work, it is not possible to eval
570             code containing comments and have them correctly removed.
571              
572             =head1 NOTE
573              
574             Some of these programming languages may be spelled incorrectly, or
575             may have the wrong quote characters noted. The majority of this
576             information was found by searches for language specifications.
577              
578             So please report errors, as well as obscure commenting syntax you
579             know of.
580              
581             =head1 Acknowledgements
582              
583             Thanks to Abigail and Glenn Maciag for their suggestions.
584              
585             =head1 BUG REPORTS
586              
587             Please report bugs or other issues to Ebug-acme-comment@rt.cpan.orgE.
588              
589             =head1 AUTHOR
590              
591             This module by Jos Boumans Ekane@cpan.orgE.
592              
593             =head1 COPYRIGHT
594              
595             This library is free software; you may redistribute and/or modify it
596             under the same terms as Perl itself.
597              
598             =cut