#!/usr/bin/env perl # This script generates licence.h (containing the PuTTY licence in the # form of macros expanding to C string literals) from the LICENCE # master file. It also regenerates the licence-related Halibut input # files. use warnings; use File::Basename; use Getopt::Long; my $usage = "usage: licence.pl (--header|--licencedoc|--copyrightdoc) " . "[-o OUTFILE]\n"; my $mode = undef; my $output = undef; GetOptions("--header" => sub {$mode = "header"}, "--licencedoc" => sub {$mode = "licencedoc"}, "--copyrightdoc" => sub {$mode = "copyrightdoc"}, "o|output=s" => \$output) and defined $mode or die $usage; # Read the input file. We expect to find that alongside this script. my $infile = (dirname __FILE__) . "/LICENCE"; open my $in, $infile or die "$infile: open: $!\n"; my @lines = (); while (<$in>) { y/\r//d; chomp; push @lines, $_; } close $in; # Format into paragraphs. my @paras = (); my $para = undef; for my $line (@lines) { if ($line eq "") { $para = undef; } elsif (!defined $para) { push @paras, $line; $para = \$paras[$#paras]; } else { $$para .= " " . $line; } } # Get the copyright years and short form of copyright holder. die "bad format of first paragraph\n" unless $paras[0] =~ m!copyright ([^\.]*)\.!i; $shortdetails = $1; my $out = ""; if ($mode eq "header") { $out .= "/*\n"; $out .= " * licence.h - macro definitions for the PuTTY licence.\n"; $out .= " *\n"; $out .= " * Generated by @{[basename __FILE__]} from $infile.\n"; $out .= " * You should edit those files rather than editing this one.\n"; $out .= " */\n"; $out .= "\n"; $out .= "#define LICENCE_TEXT(parsep) \\\n"; for my $i (0..$#paras) { my $lit = &stringlit($paras[$i]); $out .= " parsep \\\n" if $i > 0; $out .= " \"$lit\""; $out .= " \\" if $i < $#paras; $out .= "\n"; } $out .= "\n"; $out .= sprintf "#define SHORT_COPYRIGHT_DETAILS \"%s\"\n", &stringlit($shortdetails); } elsif ($mode eq "licencedoc") { # Write out doc/licence.but. $out .= "\\# Generated by @{[basename __FILE__]} from $infile.\n"; $out .= "\\# You should edit those files rather than editing this one.\n\n"; $out .= "\\A{licence} PuTTY \\ii{Licence}\n\n"; for my $i (0..$#paras) { my $para = &halibutescape($paras[$i]); if ($i == 0) { $para =~ s!copyright!\\i{copyright}!; # index term in paragraph 1 } $out .= "$para\n\n"; } } elsif ($mode eq "copyrightdoc") { # Write out doc/copy.but, which defines a macro used in the manual # preamble blurb. $out .= "\\# Generated by @{[basename __FILE__]} from $infile.\n"; $out .= "\\# You should edit those files rather than editing this one.\n\n"; $out .= sprintf "\\define{shortcopyrightdetails} %s\n\n", &halibutescape($shortdetails); } my $outfile; my $opened = (defined $output) ? (open $outfile, ">", $output) : (open $outfile, ">-"); $opened or die "$output: open: $!\n"; print $outfile $out; close $outfile; sub stringlit { my ($lit) = @_; $lit =~ s!\\!\\\\!g; $lit =~ s!"!\\"!g; return $lit; } sub halibutescape { my ($text) = @_; $text =~ s![\\{}]!\\$&!g; # Halibut escaping $text =~ s!"([^"]*)"!\\q{$1}!g; # convert quoted strings to \q{} return $text; } sub write { my ($filename, $newcontents) = @_; if (open my $fh, "<", $filename) { my $oldcontents = ""; $oldcontents .= $_ while <$fh>; close $fh; return if $oldcontents eq $newcontents; } open my $fh, ">", $filename or die "$filename: open: $!\n"; print $fh $newcontents; close $fh; }