#!/usr/bin/perl -w

# transmaps -- Generate transmaps.h for tn5250.
#
# Copyright (C) 1997  Michael Madore
# Copyright (C) 1999,2000  Carey Evans
#
#   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 2 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, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# This program uses recode's --header function to generate conversion
# tables between AS/400 EBCDIC CCSIDs and appropriate Unix encodings.

use strict;

# Check the version of the recode program.
open RECODE, "recode --version|"
  or die "transmaps: open recode --version failed: $!\n";
my $recode_ver = <RECODE>;
close RECODE
  or die
  $! ? "transmaps: close recode --version failed: $!\n"
    : "transmaps: recode --version returned $?\n";

if ($recode_ver =~ m/recode (\d+\.\d+)$/) {
  if ($1 < 3.5) {
    die "transmaps: recode is too old ($1 < 3.5).\n";
  }
} else {
  die "transmaps: couldn't work out version of recode.\n";
}

# Set up the table of conversions to generate.
#
# Notes:
#
# IBM256: Netherlands.  This is not quite the same as the other
#   character sets mapping to ISO-8859-1, but I don't know of any
#   better Unix encodings.
#
# IBM420: Arabic.  The ISO-8859 encoding doesn't include all the
#   characters in the IBM encoding.  In addition, it needs to be
#   written right-to-left.
#
# IBM424: Hebrew.  This needs to be written right-to-left too.
#
# Euro character: how should this be supported?
#
# Other single-byte EBCDIC character sets are either not available on
# the AS/400, or not known to recode.

my @conv = ( [ 'ISO-8859-1', 37, 256, 273, 277, 278, 280, 284, 285,
	       297, 500, 871 ],       # West European
	     [ 'ISO-8859-2', 870 ],   # East European
	     [ 'ISO-8859-3', 905 ],   # Turkey Latin3
	     [ 'ISO-8859-5', 880 ],   # Cyrillic
	     [ 'ISO-8859-6', 420 ],   # Arabic
	     [ 'ISO-8859-7', 875 ],   # Greek
	     [ 'ISO-8859-8', 424 ],   # Hebrew
	     [ 'ISO-8859-9', 1026 ],  # Turkey Latin5
	     [ 'JIS_X0201',  290 ] ); # Katakana Extended

# Convert the table above to a simple list of translation maps needed.
my @sets = ();
foreach (@conv) {
  my $unix_enc = shift @$_;
  foreach (@$_) {
    push @sets, [$_, $unix_enc, sprintf('IBM%03d', $_)];
  }
}

# Start writing transmaps.h.
print <<__EOT__;
/* transmaps.h was automagically generated by transmaps and GNU recode.
   Any changes should be made in transmaps or utility.c and NOT in this file!
 */

__EOT__

# Subroutine to copy recode's header output to transmaps.h.
sub recode {
  my ($from, $to) = @_;
  my $hdrname = lc("${from}_to_${to}");
  $hdrname =~ tr/-/_/;

  open RECODE, "recode --header=$hdrname $from..$to|"
    or die "transmaps: open recode --header failed: $!\n";

  while (<RECODE>) {
    print $_;
  }

  close RECODE
    or die
      $! ? "transmaps: close recode --header failed: $!\n"
	: "transmaps: recode --header returned $?\n";

  print "\n";
  return $hdrname;
}

# Write out each of the translations.
my @hdrs;
foreach (@sets) {
  my @s = @$_;
  my @h = ($s[0]);
  $h[1] = recode($s[1], $s[2]);
  $h[2] = recode($s[2], $s[1]);
  push @hdrs, \@h;
}

# Write out the table of translation maps.
print <<__EOT__;
/* This is the translation-map index which is scanned in utility.c
 */

Tn5250CharMap tn5250_transmaps [] = {
__EOT__

foreach (@hdrs) {
  printf "    {\"%d\", %s, %s},\n", @$_;
}

print "    {NULL, NULL, NULL}};\n";
