Blame examples/extexi

Packit d6cc65
#! /usr/bin/perl -w
Packit d6cc65
# Extract all examples from the manual source.
Packit d6cc65
Packit d6cc65
# This file is part of GNU Bison
Packit d6cc65
Packit d6cc65
# Copyright (C) 1992, 2000-2001, 2005-2006, 2009-2015 Free Software
Packit d6cc65
# Foundation, Inc.
Packit d6cc65
#
Packit d6cc65
# This program is free software: you can redistribute it and/or modify
Packit d6cc65
# it under the terms of the GNU General Public License as published by
Packit d6cc65
# the Free Software Foundation, either version 3 of the License, or
Packit d6cc65
# (at your option) any later version.
Packit d6cc65
#
Packit d6cc65
# This program is distributed in the hope that it will be useful,
Packit d6cc65
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d6cc65
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d6cc65
# GNU General Public License for more details.
Packit d6cc65
#
Packit d6cc65
# You should have received a copy of the GNU General Public License
Packit d6cc65
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit d6cc65
Packit d6cc65
# Usage: extexi [OPTION...] input-file.texi ... -- [FILES to extract]
Packit d6cc65
Packit d6cc65
# Look for @example environments preceded with lines such as:
Packit d6cc65
#
Packit d6cc65
#      @comment file calc.y
Packit d6cc65
# or
Packit d6cc65
#      @comment file calc.y: 3
Packit d6cc65
#
Packit d6cc65
# and output their content in that file (calc.y).  When numbers are
Packit d6cc65
# provided, use them to decide the output order (block numbered 1 is
Packit d6cc65
# output before block 2, even if the latter appears before).  The same
Packit d6cc65
# number may be used several time, in which case the order of
Packit d6cc65
# appearance is used.
Packit d6cc65
Packit d6cc65
use strict;
Packit d6cc65
Packit d6cc65
# Whether we generate synclines.
Packit d6cc65
my $synclines = 0;
Packit d6cc65
Packit d6cc65
# normalize($block)
Packit d6cc65
# -----------------
Packit d6cc65
# Remove Texinfo mark up.
Packit d6cc65
sub normalize($)
Packit d6cc65
{
Packit d6cc65
  local ($_) = @_;
Packit d6cc65
Packit d6cc65
  s/^\@(c |comment|dots|end (ignore|group)|ignore|group).*//mg;
Packit d6cc65
  s/\@value\{VERSION\}/$ENV{VERSION}/g;
Packit d6cc65
  s/^\@(error|result)\{\}//mg;
Packit d6cc65
  s/\@([{}@])/$1/g;
Packit d6cc65
  s/\@comment.*//;
Packit d6cc65
  $_;
Packit d6cc65
}
Packit d6cc65
Packit d6cc65
# Print messages only once.
Packit d6cc65
my %msg;
Packit d6cc65
sub message($)
Packit d6cc65
{
Packit d6cc65
  my ($msg) = @_;
Packit d6cc65
  if (! $msg{$msg})
Packit d6cc65
    {
Packit d6cc65
      print STDERR "extexi: $msg\n";
Packit d6cc65
      $msg{$msg} = 1;
Packit d6cc65
    }
Packit d6cc65
}
Packit d6cc65
Packit d6cc65
# basename => full file name for files we should extract.
Packit d6cc65
my %file_wanted;
Packit d6cc65
Packit d6cc65
sub process ($)
Packit d6cc65
{
Packit d6cc65
  my ($in) = @_;
Packit d6cc65
  use IO::File;
Packit d6cc65
  my $f = new IO::File($in)
Packit d6cc65
    or die "$in: cannot open: $?";
Packit d6cc65
  # FILE-NAME => { BLOCK-NUM => CODE }
Packit d6cc65
  my %file;
Packit d6cc65
Packit d6cc65
  # The latest "@comment file: FILE [BLOCK-NUM]" arguments.
Packit d6cc65
  my $file;
Packit d6cc65
  my $block;
Packit d6cc65
  # The @example block currently read.
Packit d6cc65
  my $input;
Packit d6cc65
  local $_;
Packit d6cc65
  while (<$f>)
Packit d6cc65
    {
Packit d6cc65
      if (/^\@comment file: ([^:\n]+)(?::\s*(\d+))?$/)
Packit d6cc65
        {
Packit d6cc65
          my $f = $1;
Packit d6cc65
          $block = $2 || 1;
Packit d6cc65
          if ($file_wanted{$f})
Packit d6cc65
            {
Packit d6cc65
              $file = $file_wanted{$f};
Packit d6cc65
              message(" GEN $file");
Packit d6cc65
            }
Packit d6cc65
          else
Packit d6cc65
            {
Packit d6cc65
              message("SKIP $f");
Packit d6cc65
            }
Packit d6cc65
        }
Packit d6cc65
      elsif ($file && /^\@(small)?example$/ .. /^\@end (small)?example$/)
Packit d6cc65
        {
Packit d6cc65
          if (/^\@(small)?example$/)
Packit d6cc65
            {
Packit d6cc65
              # Bison supports synclines, but not Flex.
Packit d6cc65
              $input .= sprintf ("#line %s \"$in\"\n", $. + 1)
Packit d6cc65
                if $synclines && $file =~ /\.[chy]*$/;
Packit d6cc65
              next;
Packit d6cc65
            }
Packit d6cc65
          elsif (/^\@end (small)?example$/)
Packit d6cc65
            {
Packit d6cc65
              die "no contents: $file"
Packit d6cc65
                if $input eq "";
Packit d6cc65
Packit d6cc65
              $file{$file}{$block} .= normalize($input);
Packit d6cc65
              $file = $input = undef;
Packit d6cc65
              ++$block;
Packit d6cc65
            }
Packit d6cc65
          else
Packit d6cc65
            {
Packit d6cc65
              $input .= $_;
Packit d6cc65
            }
Packit d6cc65
        }
Packit d6cc65
    }
Packit d6cc65
Packit d6cc65
  # Output the files.
Packit d6cc65
  for my $file (keys %file)
Packit d6cc65
    {
Packit d6cc65
      # No spurious end of line: use printf.
Packit d6cc65
      my $o = new IO::File(">$file")
Packit d6cc65
        or die "$file: cannot create: $?";
Packit d6cc65
      print $o $file{$file}{$_}
Packit d6cc65
        for sort keys %{$file{$file}};
Packit d6cc65
    }
Packit d6cc65
}
Packit d6cc65
Packit d6cc65
my @input;
Packit d6cc65
my $seen_dash = 0;
Packit d6cc65
for my $arg (@ARGV)
Packit d6cc65
{
Packit d6cc65
  if ($seen_dash)
Packit d6cc65
    {
Packit d6cc65
      use File::Basename;
Packit d6cc65
      $file_wanted{basename($arg)} = $arg;
Packit d6cc65
    }
Packit d6cc65
  elsif ($arg eq '--')
Packit d6cc65
    {
Packit d6cc65
      $seen_dash = 1;
Packit d6cc65
    }
Packit d6cc65
  elsif ($arg eq '--synclines')
Packit d6cc65
    {
Packit d6cc65
      $synclines = 1;
Packit d6cc65
    }
Packit d6cc65
  else
Packit d6cc65
    {
Packit d6cc65
      push @input, $arg;
Packit d6cc65
    }
Packit d6cc65
}
Packit d6cc65
process $_
Packit d6cc65
  foreach @input;
Packit d6cc65
Packit d6cc65
Packit d6cc65
### Setup "GNU" style for perl-mode and cperl-mode.
Packit d6cc65
## Local Variables:
Packit d6cc65
## perl-indent-level: 2
Packit d6cc65
## perl-continued-statement-offset: 2
Packit d6cc65
## perl-continued-brace-offset: 0
Packit d6cc65
## perl-brace-offset: 0
Packit d6cc65
## perl-brace-imaginary-offset: 0
Packit d6cc65
## perl-label-offset: -2
Packit d6cc65
## cperl-indent-level: 2
Packit d6cc65
## cperl-brace-offset: 0
Packit d6cc65
## cperl-continued-brace-offset: 0
Packit d6cc65
## cperl-label-offset: -2
Packit d6cc65
## cperl-extra-newline-before-brace: t
Packit d6cc65
## cperl-merge-trailing-else: nil
Packit d6cc65
## cperl-continued-statement-offset: 2
Packit d6cc65
## End: