Blame msggen.pl

Packit 8a864e
#! /usr/bin/perl
Packit 8a864e
# Copyright (c) 1994 James Clark
Packit 8a864e
# Copyright (c) 2000 Peter Nilsson
Packit 8a864e
# See the file COPYING for copying permission.
Packit 8a864e
Packit 8a864e
use POSIX;
Packit 8a864e
Packit 8a864e
# Package and version.
Packit 8a864e
$package = 'OpenSP';
Packit 8a864e
$version = '1.5.2';
Packit 8a864e
$package = $package; $version = $version; # be quiet, -w
Packit 8a864e
Packit 8a864e
$prog = $0;
Packit 8a864e
$prog =~ s@.*/@@;
Packit 8a864e
Packit 8a864e
$gen_c = 0;
Packit 8a864e
Packit 8a864e
undef $opt_l;
Packit 8a864e
undef $opt_p;
Packit 8a864e
undef $opt_t;
Packit 8a864e
do 'getopts.pl';
Packit 8a864e
&Getopts('l:p:t:');
Packit 8a864e
$module = $opt_l;
Packit 8a864e
$pot_file = $opt_p;
Packit 8a864e
Packit 8a864e
if (defined($opt_t)) {
Packit 8a864e
  # don't try to read translations for English
Packit 8a864e
  $opt_t =~ /.*en.*/ || &read_po_translations($opt_t);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
$num = 0; 
Packit 8a864e
Packit 8a864e
foreach $def_file (@ARGV) {
Packit 8a864e
Packit 8a864e
@tag_used = ();
Packit 8a864e
Packit 8a864e
open(DEF, $def_file) || die "can't open \`$def_file': $!\n";
Packit 8a864e
Packit 8a864e
while (<DEF>) {
Packit 8a864e
    chop;
Packit 8a864e
    if (/^!cxx$/) {
Packit 8a864e
	$gen_c = 1;
Packit 8a864e
	next;
Packit 8a864e
    }
Packit 8a864e
    if (/^=/) {
Packit 8a864e
        if (!defined($opt_p)) {
Packit 8a864e
	    $n = substr($_, 1);
Packit 8a864e
	    &error("= directive must increase message num") if ($n < $num);
Packit 8a864e
	    $num = $n;
Packit 8a864e
        }
Packit 8a864e
	next;
Packit 8a864e
    }
Packit 8a864e
    if (/^-/) {
Packit 8a864e
	# a deleted message
Packit 8a864e
	$num++;
Packit 8a864e
	next;
Packit 8a864e
    }
Packit 8a864e
	
Packit 8a864e
    next if /^[ 	]*#/;
Packit 8a864e
    next if /^[ 	]*$/;
Packit 8a864e
    @field = split('\+', $_, 5);
Packit 8a864e
    &error("too few fields") if $#field < 3;
Packit 8a864e
    if ($#field == 4 && $field[4] =~ /^%J/) {
Packit 8a864e
	$field[3] .= '+';
Packit 8a864e
	$field[3] .= substr($field[4], 2);
Packit 8a864e
	$#field = 3;
Packit 8a864e
    }
Packit 8a864e
    if ($field[0] eq "") {
Packit 8a864e
	$type[$num] = "";
Packit 8a864e
	$argc = 0;
Packit 8a864e
    }
Packit 8a864e
    else {
Packit 8a864e
	$field[0] =~ /^[IWQXE][0-9]$/ || &error("invalid first field");;
Packit 8a864e
	$type[$num] = substr($field[0], 0, 1);
Packit 8a864e
	$argc = int(substr($field[0], 1, 1));
Packit 8a864e
    }
Packit 8a864e
    $nargs[$num] = $argc;
Packit 8a864e
    $field[1] =~ /^[a-zA-Z_][a-zA-Z0-9_]+$/ || &error("invalid tag");
Packit 8a864e
    $tag[$num] = $field[1];
Packit 8a864e
    &error("duplicate tag $field[1]") 
Packit 8a864e
      if (!defined($opt_p) && defined($tag_used{$field[1]}));
Packit 8a864e
    $tag_used{$field[1]} = 1;
Packit 8a864e
    $field[2] =~ /^((ISO(\/IEC)? [0-9]+:[0-9]+ )?[A-Z]?[0-9]+(\.[0-9]+)*(p[0-9]+)?( (ISO(\/IEC)? [0-9]+:[0-9]+ )?[A-Z]?[0-9]+(\.[0-9]+)*(p[0-9]+)?)*)?$/
Packit 8a864e
	|| &error("invalid clauses field");
Packit 8a864e
    # push @clauses, $field[2];
Packit 8a864e
    $clauses[$num] = $field[2];
Packit 8a864e
    if ($argc == 0) {
Packit 8a864e
	if ($field[0] ne "") {
Packit 8a864e
	    $field[3] =~ /^([^%]|%%)*$/ || &error("invalid character after %");
Packit 8a864e
	}
Packit 8a864e
    }
Packit 8a864e
    else {
Packit 8a864e
	$field[3] =~ /^([^%]|%[%1-$argc])*$/ || &error("invalid character after %");
Packit 8a864e
    }
Packit 8a864e
    $auxloc[$num] = ($#field == 4 ? "L" : "");
Packit 8a864e
    $message[$num] = $field[3];
Packit 8a864e
    $num++;
Packit 8a864e
    if ($#field == 4) {
Packit 8a864e
	$message2[$num] = $field[4];
Packit 8a864e
	$num++;
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
close(DEF);
Packit 8a864e
Packit 8a864e
if (!defined($opt_p)) {
Packit 8a864e
Packit 8a864e
$file_base = $ARGV[0];
Packit 8a864e
$file_base =~ s/\.[^.]*$//;
Packit 8a864e
Packit 8a864e
$class = $file_base;
Packit 8a864e
$class =~ s|.*[\\/]||;
Packit 8a864e
Packit 8a864e
# this is needed on Windows NT
Packit 8a864e
chmod 0666, "$file_base.h";
Packit 8a864e
unlink("$file_base.h");
Packit 8a864e
open(OUT, ">$file_base.h");
Packit 8a864e
chmod 0444, "$file_base.h";
Packit 8a864e
select(OUT);
Packit 8a864e
Packit 8a864e
print <
Packit 8a864e
// This file was automatically generated from $def_file by $prog.
Packit 8a864e
END
Packit 8a864e
print <
Packit 8a864e
#ifndef ${class}_INCLUDED
Packit 8a864e
#define ${class}_INCLUDED 1
Packit 8a864e
Packit 8a864e
#ifdef __GNUG__
Packit 8a864e
#pragma interface
Packit 8a864e
#endif
Packit 8a864e
END
Packit 8a864e
Packit 8a864e
print <
Packit 8a864e
#include "Message.h"
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
namespace SP_NAMESPACE {
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
struct $class {
Packit 8a864e
END
Packit 8a864e
Packit 8a864e
foreach $i (0 .. $#message) {
Packit 8a864e
    if (defined($message[$i])) {
Packit 8a864e
	print "  // $i\n";
Packit 8a864e
	print "  static const Message";
Packit 8a864e
	if ($type[$i] eq "") {
Packit 8a864e
	    print "Fragment";
Packit 8a864e
	}
Packit 8a864e
	else {
Packit 8a864e
	    print "Type$nargs[$i]$auxloc[$i]";
Packit 8a864e
	}
Packit 8a864e
	print " $tag[$i];\n";
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
print "};\n";
Packit 8a864e
Packit 8a864e
Packit 8a864e
print <
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
}
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
#endif /* not ${class}_INCLUDED */
Packit 8a864e
END
Packit 8a864e
Packit 8a864e
if ($gen_c) {
Packit 8a864e
    close(OUT);
Packit 8a864e
    # this is needed on Windows NT
Packit 8a864e
    chmod 0666, "$file_base.cxx";
Packit 8a864e
    unlink("$file_base.cxx");
Packit 8a864e
    open(OUT, ">$file_base.cxx");
Packit 8a864e
    chmod 0444, "$file_base.cxx";
Packit 8a864e
    select(OUT);
Packit 8a864e
Packit 8a864e
    print <
Packit 8a864e
// This file was automatically generated from $def_file by $prog.
Packit 8a864e
Packit 8a864e
#ifdef __GNUG__
Packit 8a864e
#pragma implementation
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
#include "splib.h"
Packit 8a864e
#include "$class.h"
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
namespace SP_NAMESPACE {
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
END
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
# The declaration is already included through Message.h
Packit 8a864e
#
Packit 8a864e
# if (defined($opt_l)) {
Packit 8a864e
#     print "extern MessageModule $module;\n\n";
Packit 8a864e
# }
Packit 8a864e
Packit 8a864e
foreach $i (0 .. $#message) {
Packit 8a864e
    if (defined($message[$i])) {
Packit 8a864e
	if ($type[$i] eq "") {
Packit 8a864e
	    print "const MessageFragment ${class}::$tag[$i](\n";
Packit 8a864e
	}
Packit 8a864e
	else {
Packit 8a864e
	    print "const MessageType$nargs[$i]$auxloc[$i] ${class}::$tag[$i](\n";
Packit 8a864e
	    print "MessageType::";
Packit 8a864e
	    if ($type[$i] eq 'I') {
Packit 8a864e
		print 'info';
Packit 8a864e
	    }
Packit 8a864e
	    elsif ($type[$i] eq 'W') {
Packit 8a864e
		print 'warning';
Packit 8a864e
	    }
Packit 8a864e
	    elsif ($type[$i] eq 'Q') {
Packit 8a864e
		print 'quantityError';
Packit 8a864e
	    }
Packit 8a864e
	    elsif ($type[$i] eq 'X') {
Packit 8a864e
		print 'idrefError';
Packit 8a864e
	    }
Packit 8a864e
	    else {
Packit 8a864e
		print 'error';
Packit 8a864e
	    }
Packit 8a864e
	    print ",\n";
Packit 8a864e
	}
Packit 8a864e
	if (defined($opt_l)) {
Packit 8a864e
	    print "&$module,\n";
Packit 8a864e
	} else {
Packit 8a864e
	    print "0,\n";
Packit 8a864e
	}
Packit 8a864e
	print "$i\n";
Packit 8a864e
	print "#ifndef SP_NO_MESSAGE_TEXT\n";
Packit 8a864e
	$str = $message[$i];
Packit 8a864e
	$str =~ s|\\|\\\\|g;
Packit 8a864e
	$str =~ s|"|\\"|g;
Packit 8a864e
	printf ",\"%s\"", $str; 
Packit 8a864e
	if ($clauses[$i]) {
Packit 8a864e
	  $str = $clauses[$i];
Packit 8a864e
	  $str =~ s|\\|\\\\|g;
Packit 8a864e
	  $str =~ s|"|\\"|g;
Packit 8a864e
	  printf "\n,\"%s\"", $str; 
Packit 8a864e
        }
Packit 8a864e
	if ($auxloc[$i]) {
Packit 8a864e
            if ($clauses[$i] eq "") {
Packit 8a864e
              print "\n,0";
Packit 8a864e
            }
Packit 8a864e
	    $str = $message2[$i + 1];
Packit 8a864e
	    $str =~ s|\\|\\\\|g;
Packit 8a864e
	    $str =~ s|"|\\"|g;
Packit 8a864e
	    printf "\n,\"%s\"", $str;
Packit 8a864e
	}
Packit 8a864e
	print "\n#endif\n";
Packit 8a864e
	print ");\n";
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
print <
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
}
Packit 8a864e
#endif
Packit 8a864e
END
Packit 8a864e
Packit 8a864e
close(OUT);
Packit 8a864e
Packit 8a864e
# this is needed on Windows NT
Packit 8a864e
chmod 0666, "$file_base.rc";
Packit 8a864e
unlink("$file_base.rc");
Packit 8a864e
open(OUT, ">$file_base.rc");
Packit 8a864e
chmod 0444, "$file_base.rc";
Packit 8a864e
select(OUT);
Packit 8a864e
Packit 8a864e
print "STRINGTABLE\nBEGIN\n";
Packit 8a864e
Packit 8a864e
foreach $i (0 .. $#message) {
Packit 8a864e
    if (defined($message[$i])) {
Packit 8a864e
	$str = $message[$i];
Packit 8a864e
	if ($translation{$str}) {
Packit 8a864e
	    $str = $translation{$str};
Packit 8a864e
	}
Packit 8a864e
	$str =~ s/"/""/g;
Packit 8a864e
	printf "  %d, \"%s\"\n", $i, $str;
Packit 8a864e
    }
Packit 8a864e
    elsif (defined($message2[$i])) {
Packit 8a864e
	$str = $message2[$i];
Packit 8a864e
	$str =~ s/"/""/g;
Packit 8a864e
	printf "  %d, \"%s\"\n", $i, $str;
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
print "END\n";
Packit 8a864e
close(OUT);
Packit 8a864e
Packit 8a864e
} # !opt_p
Packit 8a864e
Packit 8a864e
} # foreach def_file
Packit 8a864e
Packit 8a864e
if (defined($opt_p)) {
Packit 8a864e
Packit 8a864e
  # this is needed for GNU gettext 
Packit 8a864e
  chmod 0666, "$pot_file";
Packit 8a864e
  unlink("$pot_file");
Packit 8a864e
  open(OUT, ">$pot_file");
Packit 8a864e
  chmod 0444, "$pot_file";
Packit 8a864e
  select(OUT);
Packit 8a864e
Packit 8a864e
  $crdate = POSIX::strftime "%Y-%m-%d %H:%M+0000", gmtime;
Packit 8a864e
  print <
Packit 8a864e
# SOME DESCRIPTIVE TITLE.
Packit 8a864e
# Copyright (C) YEAR HOLDER
Packit 8a864e
# FIRST AUTHOR <EMAIL\@ADDRESS>, YEAR.
Packit 8a864e
#
Packit 8a864e
#, fuzzy
Packit 8a864e
msgid ""
Packit 8a864e
msgstr ""
Packit 8a864e
"Project-Id-Version: PACKAGE VERSION\\n"
Packit 8a864e
"POT-Creation-Date: $crdate\\n"
Packit 8a864e
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
Packit 8a864e
"Last-Translator: FULL NAME <EMAIL\@ADDRESS>\\n"
Packit 8a864e
"Language-Team: LANGUAGE <LL\@li.org>\\n"
Packit 8a864e
"MIME-Version:: 1.0\\n"
Packit 8a864e
"Content-Type: text/plain; charset=CHARSET\\n"
Packit 8a864e
"Content-Transfer-Encoding: ENCODING\\n"
Packit 8a864e
Packit 8a864e
END
Packit 8a864e
Packit 8a864e
  foreach $i (0 .. $#message) {
Packit 8a864e
    if (defined($message[$i]) && !defined($written{$message[$i]})) {
Packit 8a864e
	next if $message[$i] eq "";
Packit 8a864e
	$written{$message[$i]} = 1;
Packit 8a864e
	$str = $message[$i];
Packit 8a864e
	$str =~ s/"/\\"/g;
Packit 8a864e
	printf "msgid \"%s\"\nmsgstr \"\"\n\n", $str;
Packit 8a864e
    }
Packit 8a864e
    elsif (defined($message2[$i]) && ! defined($written{$message2[$i]})) {
Packit 8a864e
	$written{$message2[$i]} = 1;
Packit 8a864e
	$str = $message2[$i];
Packit 8a864e
	$str =~ s/"/\\"/g;
Packit 8a864e
	printf "msgid \"%s\"\nmsgstr \"\"\n\n", $str;
Packit 8a864e
    }
Packit 8a864e
 }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
close(OUT);
Packit 8a864e
Packit 8a864e
sub error {
Packit 8a864e
    die "$def_file:$.: $_[0]\n";
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
# Read a PO file with message translations.
Packit 8a864e
# This doesn't accept every valid PO file, but it seems to work reasonably.
Packit 8a864e
sub read_po_translations {
Packit 8a864e
    my $po_in = $_[0];
Packit 8a864e
    open(PO_IN, "<$po_in") || die "Can't open file $po_in.";
Packit 8a864e
    my $id = "";
Packit 8a864e
    my $str = "";
Packit 8a864e
    my $catching_string = 0;
Packit 8a864e
Packit 8a864e
    while(<PO_IN>) {
Packit 8a864e
	if (/^\s*msgid/) {
Packit 8a864e
	    if ($catching_string) {
Packit 8a864e
		&po_flush($id, $str);
Packit 8a864e
		$id = "";
Packit 8a864e
		$str = "";
Packit 8a864e
	    }
Packit 8a864e
	    $_ = $';
Packit 8a864e
	    $catching_string = 1;
Packit 8a864e
	}
Packit 8a864e
	elsif (/^\s*msgstr/) {
Packit 8a864e
	    die "No msgid." if !$catching_string or $id;
Packit 8a864e
	    $id = $str;
Packit 8a864e
	    $str = "";
Packit 8a864e
	    $_ = $';
Packit 8a864e
	}
Packit 8a864e
	
Packit 8a864e
	if ($catching_string) {
Packit 8a864e
	    my $in_string = 0;
Packit 8a864e
	    s/\s*//;
Packit 8a864e
	    while ($_) {
Packit 8a864e
		if (s/^\"//) {
Packit 8a864e
		    $in_string = !$in_string;
Packit 8a864e
		}
Packit 8a864e
		if ($in_string) {
Packit 8a864e
		    if (s/^[^\"\\]+//) {
Packit 8a864e
			$str .= $&;
Packit 8a864e
		    }
Packit 8a864e
		    elsif (s/^\\([ntbrf\\\"])//) {
Packit 8a864e
			$str .= "\n" if $1 eq "n";
Packit 8a864e
			$str .= "\t" if $1 eq "t";
Packit 8a864e
			$str .= "\b" if $1 eq "b";
Packit 8a864e
			$str .= "\r" if $1 eq "r";
Packit 8a864e
			$str .= "\f" if $1 eq "f";
Packit 8a864e
			$str .= "\\" if $1 eq "\\";
Packit 8a864e
			$str .= "\"" if $1 eq "\"";
Packit 8a864e
		    }
Packit 8a864e
		    elsif (s/\\([0-9]+)//) {
Packit 8a864e
			$str .= chr(oct($1));
Packit 8a864e
		    }
Packit 8a864e
		    elsif (s/\\[xX]([0-9a-fA-F]+)//) {
Packit 8a864e
			$str .= chr(hex($1));
Packit 8a864e
		    }
Packit 8a864e
		    else {
Packit 8a864e
			die "Invalid control sequence." if /^\\/;
Packit 8a864e
		    }
Packit 8a864e
		}
Packit 8a864e
		else {
Packit 8a864e
		    s/\s*//;
Packit 8a864e
		    last if /^[^"]/;
Packit 8a864e
	        }
Packit 8a864e
            }
Packit 8a864e
        }
Packit 8a864e
    }
Packit 8a864e
    if ($catching_string) {
Packit 8a864e
        &po_flush($id, $str);
Packit 8a864e
Packit 8a864e
    }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
sub po_flush {
Packit 8a864e
    my $id = $_[0];
Packit 8a864e
    my $str = $_[1];
Packit 8a864e
    # We use a translation only if $id is non-empty (we don't include the
Packit 8a864e
    # PO file header) and if $str is non-empty (the message is translated).
Packit 8a864e
    if ($id && $str) {
Packit 8a864e
	$translation{$id} = $str;
Packit 8a864e
    }
Packit 8a864e
    $id = "";
Packit 8a864e
    $str = "";
Packit 8a864e
}
Packit 8a864e
Packit 8a864e