#!/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