#!/usr/local/bin/perl

use strict;
use warnings;

use Encode;
use Encode::Rad50;

my @cc = map {"<$_>"} qw{nul soh stx etx eot enq ack bel bs ht lf vt ff
    cr so si dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs
    us};
@cc[127 .. 159] = map {"<$_>"} qw{del pad hop bph nbh ind nel ssa esa
    hts htj vts pld plu ri ss2 ss3 dcs pu1 pu2 sts cch mw spa epa sos
    sgci sci csi st osc pm apc};

@ARGV or do {print <<'EOD'; exit};

Re-implementation of the RSX-11 utility cvt, which converted data
among various radices.

usage: cvt data ...

where the data are:
   &xxxx represents a hexadecimal number
   %xxx represents rad50 characters
   "cc represents ASCII characters
   nnnnn. represents a decimal number
   nnnnn represents an octal number.

Copyright 2005-2007, 2011-2012 by Thomas R. Wyant, III
(F<wyant at cpan dot org>). All rights reserved.

PDP-11, RSTS-11, RSTS/E,  RSX-11, RSX-11M+, P/OS and RT-11 are
trademarks of Hewlett-Packard Development Company, L.P.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl 5.10.0. For more details, see the full text
of the licenses in the directory LICENSES.

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.
EOD

foreach (@ARGV) {
    my $value = m/^\d+\.$/ ? $_ + 0 :
	m/^[0-7]+$/ ? oct ($_) :
	m/^&([[:xdigit:]]+)$/ ? oct ("0x$1") :
	m/^'(.)$/ ? ord ($1) :
	m/^"(.{1,2})$/ ? unpack ('n', $1) :
	m/^%(.{1,3})$/ ? unpack ('n', encode ('rad50', sprintf '%3s', $1)) :
	do {warn "Invalid input '$_'\n"; next};
    $value &= 0xffff;
    my $oct = sprintf '%o', $value;
    my $hex = sprintf '%X', $value;
    my $chr = join '', map {$cc[ord $_] || $_} split '', pack ('n', $value);
    my $r5 = decode ('rad50', pack 'n', $value);
    $r5 =~ s/^\s+//;
    print "$oct\t$value.\t&$hex\t\"$chr\t%$r5\n";
}
