#!/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 .
# 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 () {
$inline = $_;
if ( $inline =~ m/^\@G(.*)$/ ) { # @G detected, this line is part of the `other language' region
$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\*0-9].*$/ ) { # @`other' detected, so `other language' region is over
if ($state == 1) {
printf FILEOUT "\@q%s\@>\n" . $elang_finish, "End of generic language section"; # a parser switcher
}
$state = 0;
printf FILEOUT "%s", "$inline";
} elsif ( $inline =~ m/^\s*\@[=t].*$/ ) { # @= detected, just copy the line
printf FILEOUT "%s", "$inline";
} elsif ( $inline =~ m/^\@g(.*)$/ ) { # explicit end of other languge region detected
$inline = $1;
if ($state == 1) {
printf FILEOUT "\@q%s\@>\n" . $elang_finish, "End of generic language section"; # a parser switcher
}
$state = 0;
} elsif ( $inline =~ m/^\@O(.*)$/ ) { # @O detected, so `other language' region is paused
$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 = $paused_state; $paused_state = 0;
if ( not $inline ) { $inline = "End generic language section"; }
printf FILEOUT "\@q%s\@>\n", "$inline";
} elsif ( $state != 0 ) {
if ( $inline =~ m/\/\*.*\*\/\s*$/ ) { # the line contains a comment at the end
$inline =~ m/^(.*\S|)\s*(\/\*.*\*\/)\s*$/;
$string = $1; $comment = $2;
} else {
$inline =~ m/^(.*)$/;
$string = $1; $comment = "";
}
if ( $string ) {
printf FILEOUT "\@=%s\@>\@t}\\vb{\\n}{\@>\@;", "$string";
} else {
printf FILEOUT "\@=%s\@>\@t}\\vb{\\n}{\@>\@;", " "; # to keep \CWEB\ happy
}
if ( $comment ) {
printf FILEOUT "%s", "$comment";
}
printf FILEOUT "%s", "\n";
} else {
printf FILEOUT "%s", "$inline";
}
}
__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
The string to print at the beginning of an other language region
=item B<--finishol>=I
The string to print at the end of an other language region
=back
=head1 DESCRIPTION
B will read the given , and the format @G(...) sections
appropriately to be read by CWEAVE and output the result in the .
The processing mechanism is very primitive and makes use of some assumptions
on the appearance of the B file. Unlike the 'standard' B input, the
new 'generic language' section markers (the @G(...) construct) are
I and I 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.
A comment at the very end of the line is moved to the B 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.
=cut