summaryrefslogtreecommitdiff
path: root/support/splint/scripts/brack.pl
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/scripts/brack.pl')
-rwxr-xr-xsupport/splint/scripts/brack.pl145
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