#! /usr/bin/perl -w # Extract all examples from the manual source. # This file is part of GNU Bison # Copyright (C) 1992, 2000-2001, 2005-2006, 2009-2012 Free Software # Foundation, Inc. # # This program 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. # # This program 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 this program. If not, see . # Usage: extexi input-file.texi ... -- [FILES to extract] use strict; # normalize($block) # ----------------- # Remove Texinfo mark up. sub normalize($) { local ($_) = @_; s/^\@(c |comment|dots|end (ignore|group)|ignore|group).*//mg; s/\@value\{VERSION\}/$ENV{VERSION}/g; s/^\@(error|result)\{\}//mg; s/\@([{}@])/$1/g; s/\@comment.*//; $_; } # Print messages only once. my %msg; sub message($) { my ($msg) = @_; if (! $msg{$msg}) { print STDERR "extexi: $msg\n"; $msg{$msg} = 1; } } # basename => full file name for files we should extract. my %file_wanted; # Whether we already say that file (in which case, append instead of # create). my %file_output; sub process ($) { my ($in) = @_; use IO::File; my $f = new IO::File($in) or die "$in: cannot open: $?"; # The latest "@comment file: " argument. my $file; # The @example block currently read. my $input; local $_; while (<$f>) { if (/^\@comment file: (.*)/) { my $f = $1; if ($file_wanted{$f}) { $file = $file_wanted{$f}; message(" GEN $file"); } else { message("SKIP $f"); } } elsif ($file && /^\@(small)?example$/ .. /^\@end (small)?example$/) { if (/^\@(small)?example$/) { $input = $file_output{$file} ? "\n" : ""; # Bison supports synclines, but not Flex. $input .= sprintf ("#line %s \"$in\"\n", $. + 1) if $file =~ /\.[chy]*$/; next; } elsif (/^\@end (small)?example$/) { die "no contents: $file" if $input eq ""; $input = normalize($input); # No spurious end of line: use printf. my $o = ($file_output{$file} ? new IO::File(">>$file") : new IO::File(">$file")); print $o $input; $file_output{$file} = 1; $file = $input = undef; } else { $input .= $_; } } } } my @input; my $seen_dash = 0; for my $arg (@ARGV) { if ($arg eq '--') { $seen_dash = 1; } elsif ($seen_dash) { use File::Basename; $file_wanted{basename($arg)} = $arg; } else { push @input, $arg; } } process $_ foreach @input; ### Setup "GNU" style for perl-mode and cperl-mode. ## Local Variables: ## perl-indent-level: 2 ## perl-continued-statement-offset: 2 ## perl-continued-brace-offset: 0 ## perl-brace-offset: 0 ## perl-brace-imaginary-offset: 0 ## perl-label-offset: -2 ## cperl-indent-level: 2 ## cperl-brace-offset: 0 ## cperl-continued-brace-offset: 0 ## cperl-label-offset: -2 ## cperl-extra-newline-before-brace: t ## cperl-merge-trailing-else: nil ## cperl-continued-statement-offset: 2 ## End: