diff options
Diffstat (limited to 'support/splint/scripts/brack.pl')
-rwxr-xr-x | support/splint/scripts/brack.pl | 145 |
1 files changed, 120 insertions, 25 deletions
diff --git a/support/splint/scripts/brack.pl b/support/splint/scripts/brack.pl index 6e110e5cf3..887c6324f0 100755 --- a/support/splint/scripts/brack.pl +++ b/support/splint/scripts/brack.pl @@ -1,15 +1,51 @@ #!/usr/bin/perl +# Copyright 2012-2020, Alexander Shibakov +# This file is part of SPLinT +# +# SPLinT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPLinT is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPLinT. If not, see <http://www.gnu.org/licenses/>. + # a simple script to replace all @G ... @`other' regions with # @= ... @>@; lines # comments are allowed at the end of the lines. # only one style of comments is accepted: /* ... */. note that these are not # output +use Getopt::Long; +use Pod::Usage; + +my $man = 0; +my $help = 0; +my $elang_start = "\@t}\\lsectionbegin{\%s}\\vb{\@>\n"; +my $elang_finish = "\@t}\\vb{\\yyendgame}\\vb{}\\endparse\\postparse{\@>\n"; + +#Getopt::Long::Configure ("bundling"); # to allow -abc to set a, b, and c + +GetOptions ("help|?" => \$help, + man => \$man, + "startol=s" => \$elang_start, # the string that starts an `other language' region + "finishol=s" => \$elang_finish # the string that ends an `other language' region + ) or pod2usage(2); + +pod2usage(-exitval => 0, -verbose => 1) if $help; +pod2usage(-exitval => 0, -verbose => 2) if $man; + open FILE, "$ARGV[0]" or die "Cannot open input file $ARGV[0]\n"; open FILEOUT, ">$ARGV[1]" or die "Cannot open output file $ARGV[1]\n"; $state = 0; +$paused_state = 0; while (<FILE>) { $inline = $_; @@ -17,20 +53,22 @@ while (<FILE>) { if ( $inline =~ m/^\@G(.*)$/ ) { # @G detected, this line is part of the `other language' region - $inline = $1; $state = 1; - if ( $inline =~ m/^\(([^)]*)\).*/ ) { - printf FILEOUT "\@q Start generic language section\@>\n\@t}\\begingsec{%s}{\@>\n", "$1"; # a parser switcher - } else { - $inline = " Start \@\@G (generic) language section"; - printf FILEOUT "\@q%s\@>\n\@t}\\begingsec{b}{\@>\n", "$inline"; # a parser switcher - } + $inline = $1; $state = 1; + + if ( $inline =~ m/^\(([^)]*)\).*/ ) { # language specifier present + $inline = $1; + } else { + $inline = "b"; + } + + printf FILEOUT "\@q Start generic language section\@>\n" . $elang_start, "$inline"; # a parser switcher - } elsif ( $inline =~ m/^\@[\scp].*$/ ) { # @`other' detected, so `other language' region is over + } elsif ( $inline =~ m/^\@[\scp\*0-9].*$/ ) { # @`other' detected, so `other language' region is over if ($state == 1) { - printf FILEOUT "\@q%s\@>\n\@t}\\endgsec{\@>\n", - "End of generic language section"; # a parser switcher - } + printf FILEOUT "\@q%s\@>\n" . $elang_finish, "End of generic language section"; # a parser switcher + } + $state = 0; printf FILEOUT "%s", "$inline"; @@ -38,35 +76,33 @@ while (<FILE>) { printf FILEOUT "%s", "$inline"; - } elsif ( $inline =~ m/^\@g(.*)$/ ) { # @`other' detected, so `other language' region is over + } elsif ( $inline =~ m/^\@g(.*)$/ ) { # explicit end of other languge region detected - if ($state == 1) { - printf FILEOUT "\@q%s\@>\n\@t}\\endgsec{\@>\n", - "End of generic language section"; # a parser switcher - } + $inline = $1; - $inline = $1; $state = 0; + if ($state == 1) { + printf FILEOUT "\@q%s\@>\n" . $elang_finish, "End of generic language section"; # a parser switcher + } - if ( not $inline ) { $inline = "End generic language section"; } - printf FILEOUT "\@q%s\@>\n", "$inline"; + $state = 0; } elsif ( $inline =~ m/^\@O(.*)$/ ) { # @O detected, so `other language' region is paused - $inline = $1; $state = 0; + $inline = $1; $paused_state = $state; $state = 0; if ( not $inline ) { $inline = "End generic language section"; } printf FILEOUT "\@q%s\@>\n", "$inline"; } elsif ( $inline =~ m/^\@o(.*)$/ ) { # @o detected, so `other language' region is resumed - $inline = $1; $state = 1; + $inline = $1; $state = $paused_state; $paused_state = 0; if ( not $inline ) { $inline = "End generic language section"; } printf FILEOUT "\@q%s\@>\n", "$inline"; - } elsif ( $state == 1 ) { + } elsif ( $state != 0 ) { - if ( $inline =~ m/\/\*.*\*\/\s*$/ ) { + if ( $inline =~ m/\/\*.*\*\/\s*$/ ) { # the line contains a comment at the end $inline =~ m/^(.*\S|)\s*(\/\*.*\*\/)\s*$/; $string = $1; $comment = $2; @@ -80,11 +116,11 @@ while (<FILE>) { if ( $string ) { - printf FILEOUT "\@=%s\@>\@;", "$string"; + printf FILEOUT "\@=%s\@>\@t}\\vb{\\n}{\@>\@;", "$string"; } else { - printf FILEOUT "\@=%s\@>\@;", " "; + printf FILEOUT "\@=%s\@>\@t}\\vb{\\n}{\@>\@;", " "; # to keep \CWEB\ happy } @@ -103,3 +139,62 @@ while (<FILE>) { } } + +__END__ + +=head1 BRACK + +brack.pl - Preprocess a CWEB file to allow language extensions + +=head1 SYNOPSIS + +brack.pl [options] input_file output_file + + + Options: + --help|-h|-? brief help message + --man|-m full documentation + --startol|-s string to begin a language region + --finishol|-f string to end a language region + +=head1 OPTIONS + +=over 8 + +=item B<--help> + +Print a brief help message and exit. + +=item B<--man> + +Print the manual page and exit. + +=item B<--startol>=I<CWEB string> + +The string to print at the beginning of an other language region + +=item B<--finishol>=I<CWEB string> + +The string to print at the end of an other language region + +=back + +=head1 DESCRIPTION + +B<brack.pl> will read the given <input_file>, and the format @G(...) sections +appropriately to be read by CWEAVE and output the result in the <output_file>. + +The processing mechanism is very primitive and makes use of some assumptions +on the appearance of the B<CWEB> file. Unlike the 'standard' B<CWEB> input, the +new 'generic language' section markers (the @G(...) construct) are +I<case sensitive> and I<must> appear at the beginning of the line. The +'other language' markers (the @O... sections) follow the same restrictions as +the @G sections above, and I<do not nest>. + +A comment at the very end of the line is moved to the B<C> portion of the input. +To put the comment inside the verbatim blocks, one may surround it by [@>@=] and +[@>@= ] (the square brackets are not part of the input and are here to draw attention +to the spacing, see next). Note the space at the end of the closing construct: this +is necessary to pacify B<CWEAVE>. + +=cut |