Re: НА: CPAN

[email protected] (Karl Williamson)
Newsgroups perl.mvs
Message-ID <[email protected]>
On 03/12/2015 02:56 AM, Yaroslav Kuzmin wrote:
> I needed modules connect manually .
>
> 1 download *.tar.gz
> 2 copy on z/OS
> 3 translate ASCII > EBCDIC

To do this translation you can use either the C program Yaroslav 
created, and which is attached, or the perl script I created, also 
attached.

I believe the iconv system utility can be used to translate simple ASCII 
to EBCDIC, hence my utility will be translated by that.

> 4 perl Makefile.PL
> 5 make
> 6 make test
> 7 make install
>
> ------------------------------------------------------------------------
>   Yaroslav Kuzmin
> Developer C/C++ ,z/OS , Linux
> 3 Zhukovskiy Street · Miass, Chelyabinsk region 456318 · Russia
> Tel:  +7.922.2.38.33.38
> Email: [email protected]
> Web: www.rocketsoftware.com
>
> ________________________________________
> От: Richard Pinion <[email protected]>
> Отправлено: 12 марта 2015 г. 2:21
> Кому: [email protected]
> Тема: CPAN
>
> How does one retrieve packages through CPAN and overcome the
> ASCII/EBCDIC translation problem?
> --
>
> ================================
> Rocket Software, Inc. and subsidiaries ■ 77 Fourth Avenue, Waltham MA 02451 ■ +1 800.966.3270 ■ +1 781.577.4321
> Unsubscribe From Commercial Email – [email protected]
> Manage Your Subscription Preferences - http://info.rocketsoftware.com/GlobalSubscriptionManagementEmailFooter_SubscriptionCenter.html
> Privacy Policy - http://www.rocketsoftware.com/company/legal/privacy-policy
> ================================
>
> This communication and any attachments may contain confidential information of Rocket Software, Inc. All unauthorized use, disclosure or distribution is prohibited. If you are not the intended recipient, please notify Rocket Software immediately and destroy all copies of this communication. Thank you.
>
tue.tar.gz (application/octetstream, 6.8 KB) - not displayed
ebcdic_to_ascii.pl (application/x-perl, 9.5 KB)
#! /usr/bin/perl -w
     eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
         if 0; #$running_under_some_shell


# This program runs only on an ASCII platform.  It reads via <> and outputs
# the translation of the input to STDOUT.  The input file(s) should be in 1047
# UTF-EBCDIC; the translation is to ASCII UTF-8.  If it finds malformed
# UTF-EBCDIC, it outputs extra info at that point to aid you in deciphering.


if (ord("A") != 65) {
    print STDERR "$0 is designed to run only on ASCII platforms";
    exit 1;
}

my @utf8_skip = (
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 0_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 1_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 2_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 3_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 4_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 5_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 6_
1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, # 7_
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, # 8_
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, # 9_
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, # A_
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 3, 3, # B_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, # C_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 4, # D_
1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5, # E_
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 6, 7, 7, 1, # F_
);

my @ebcdic1047_to_ascii = (
# _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F        */
0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,  # 0_ */,
0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F,  # 1_ */,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07,  # 2_ */,
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A,  # 3_ */,
0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,  # 4_ */,
0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,  # 5_ */,
0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,  # 6_ */,
0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,  # 7_ */,
0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1,  # 8_ */,
0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4,  # 9_ */,
0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE,  # A_ */,
0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7,  # B_ */,
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5,  # C_ */,
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF,  # D_ */,
0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5,  # E_ */,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F,  # F_ */
# _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F        */
);

my @utf8_to_I8 = (
# _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F        */
0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, #* 0_ */,
0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, #* 1_ */,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, #* 2_ */,
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, #* 3_ */,
0x20, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, #* 4_ */,
0x26, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, #* 5_ */,
0x2D, 0x2F, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, #* 6_ */,
0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, #* 7_ */,
0xC5, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, #* 8_ */,
0xCC, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, #* 9_ */,
0xD3, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xD4, 0xD5, 0xD6, 0x5B, 0xD7, 0xD8, #* A_ */,
0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0x5D, 0xE6, 0xE7, #* B_ */,
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, #* C_ */,
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, #* D_ */,
0x5C, 0xF4, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, #* E_ */,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x9F, #* F_ */
# _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F        */
);

sub byte_name ($) { # Returns a short name for the input code point [0-255]
    my $ord = $ebcdic1047_to_ascii[shift];
    my $char = chr $ord;
    #print STDERR __LINE__, ": ", ord($char), "\n";
    if ($char =~ /\p{PosixGraph}/) {
        my $quote = $char eq "'" ? '"' : "'";
        $name = $quote . chr($ord) . $quote;
    }
    elsif ($char =~ /\p{XPosixGraph}/) {
        use charnames();
        $name = charnames::viacode($ord);
        $name =~ s/LATIN CAPITAL LETTER //
                or $name =~ s/LATIN SMALL LETTER (.*)/\L$1/
                or $name =~ s/ SIGN\b//
                or $name =~ s/EXCLAMATION MARK/'!'/
                or $name =~ s/QUESTION MARK/'?'/
                or $name =~ s/QUOTATION MARK/QUOTE/
                or $name =~ s/ INDICATOR//;
        $name =~ s/\bWITH\b/\L$&/;
        $name =~ s/\bONE\b/1/;
        $name =~ s/\b(TWO|HALF)\b/2/;
        $name =~ s/\bTHREE\b/3/;
        $name =~ s/\b QUARTER S? \b/4/x;
        $name =~ s/VULGAR FRACTION (.) (.)/$1\/$2/;
        $name =~ s/\bTILDE\b/'~'/i
                or $name =~ s/\bCIRCUMFLEX\b/'^'/i
                or $name =~ s/\bSTROKE\b/'\/'/i
                or $name =~ s/ ABOVE\b//i;
    }
    else {
        use Unicode::UCD qw(prop_invmap);
        my ($list_ref, $map_ref, $format) = prop_invmap("Name_Alias");
        if ($format !~ /^s/) {
            use Carp;
            carp "Unexpected format '$format' for 'Name_Alias";
            last;
        }
        my $which = Unicode::UCD::search_invlist($list_ref, $ord);
        if (! defined $which) {
            use Carp;
            carp "No name found for code pont $ord";
        }
        else {
            my $map = $map_ref->[$which];
            if (! ref $map) {
                $name = $map;
            }
            else {
                # Just pick the first abbreviation if more than one
                my @names = grep { $_ =~ /abbreviation/ } @$map;
                $name = $names[0];
            }
            $name =~ s/:.*//;
        }
    }

    return $name;
}

undef $/;   # causes <> to slurp whole file

binmode STDOUT, ":utf8";
binmode STDIN, ":raw";

while (<>) {
    my $in = $_;
    my $i;
  CHARACTER:
    for ($i = 0; $i < length $in; $i++) { # Examine each byte in this file
        my $byte = ord substr($in, $i, 1);
        my $byte_count = $utf8_skip[$byte];
        #printf STDERR "input ord=%02X, skip=%d\n", $byte, $byte_count;

        # Just translate UTF-8 invariants directly.
      single_byte:
        if ($byte_count == 1) {
            print STDOUT chr $ebcdic1047_to_ascii[$byte];
            next;
        }

        # Otherwise calculate the code point ordinal represented by the
        # sequence beginning with this byte, using the algorithm adapted from
        # utf8.c.  We absorb each byte in the sequence as we go along
        my $ord = $utf8_to_I8[$byte] & (0x1F >> ($byte_count - 2));
        my $bytes_remaining = $byte_count - 1;
        while ($bytes_remaining > 0) {
            my $I8_byte = $utf8_to_I8[ord substr($in, ++$i, 1)];
            unless (($I8_byte & 0xE0) == 0xA0) {
                printf STDERR "byte '%X' is not a valid continuation\n", $I8_byte;
                printf "_MALFORMED_(orig=\"0x%02x=%s\"; I8=0x%02x)", $byte, byte_name($byte), $I8_byte;
                $byte_count=1;
                $i--;
                goto single_byte;
            }
            $ord = $ord << 5 | ($I8_byte & 0x1f);
            $bytes_remaining--;
        }

        my $expected_bytes = $ord < 0xA0          
                                ? 1
                                : $ord < 0x400
                                ? 2
                                : $ord < 0x4000
                                    ? 3
                                    : $ord < 0x40_000
                                    ? 4
                                    : $ord < 0x400_000
                                        ? 5
                                        : $ord < 0x4_000_000
                                          ? 6 : 7;

        # Note if is not an overlong sequence
        if ($byte_count != $expected_bytes) {
            printf STDERR "character U+%X should occupy %d bytes, not %d\n",
                                            $ord, $expected_bytes, $byte_count;
            printf "_MALFORMED_(expected=$expected_bytes; got=$byte_count; orig=0x%02x)", $byte;
        }

        print chr $ord;
    } # End of loop through all the line's bytes
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.