Perl question relating to pattern substitution
Tom Christiansen
tchrist at convex.COM
Sun Jan 6 02:52:12 AEST 1991
>From the keyboard of frechett at horton.Colorado.EDU.Colorado.EDU:
:I am having some problems with the following perl script. It is supposed to
:take a file with strings like A2448932B3F233490 which starts with
:%%HP and the string itsself starts with " and has a newline
:every sixty characters and a " terminats it, and convert this mess into
:a binary file that can be downloaded to the hp48sx calculator. This script
:was posted, with the statement that it works fine on the poster's system.
:Unfortunately, I don't know what that was. Here is the script and
:my comments after the @s.
:#!/usr/local/bin/perl
:# unasc
:# A perl program to extract a HP-48 binary from a text file containing a
:# ->ASC program.
:#
:# Usage: unasc file > binfile
:#
:# Written by Wayne Scott 1990
:
:while (<>) {
: next if (!(/%%HP/../"$/)); # Skip everything but program
: chop;
: $file .= $_;
:}
:@ I added the following two lines and commented out the one after that
:@ as my perl had no idea what to make of \w.
:$file =~ s/"//g;
:$file =~ s/%%HP//g;
:# $file =~ s/.*"(\w*)\w\w\w\w".*/\1/; # strip newlines, ", and CRC
Well, that's awfully strange. I don't know that there's ever been
a perl that didn't know what to make of \w. Your replacement won't
do the same thing, as the original code is stripping off the 4 or
more "word" ([a-zA-Z0-9_] characters between the quotes. That
expression could be more efficiently written:
$file ~= s/"(\w*)\w{4}"/$1/;
but it should still work.
:@ This is the line that I am having problems with.. Simply, it replaces every
:@ two characters with the string "pack(C,hex(\1.\2)" whis is totally useless
:@ as it is supposed to be converting ascii to binary.
:$file =~ s/(.)(.)/pack(C,hex(\1.\2))/eg; # convert ascii to bin
:
:print $file;
:The problem is that my perl doesn't recognize pack as being a function
:which is understandable as I can't find reference to pack in
:TFM for ed, ex, sed, awk, perl, or C. Anyone know how I might be able to
:work around this little bug and get this to work.. Remember, this works on
:some machine somewhere... Any help would be appreciated.
I suspect that you're running on an OLD version of perl. Pack has
been around since perl, version 3. Maybe you're running perl 2.
Pack is a function that takes a template and converts some text data
into binary format, which is what you want.
It may be that you have pack() and it's just choking on the unadorned
C where it would really prefer "C". Newer patchlevels accept unquoted
literal strings, but older ones don't. I guess I'd probably write
the conversion this way:
$file =~ s/(..)/pack("C",hex($1))/eg; # convert ascii to bin
Note that the following obfuscation is actually around 30% faster -- which
is unfortunately still pretty slow by my standards:
print pack("C" x ((length($file))/2),
grep($_ ne '' && (($_ = hex) || 1), split(/(..)/, $file)));
You could also save time if you wouldn't put the whole thing in
one big string before you translate it, but rather do it at line at
a time.
Does that fix up your program?
--tom
--
Tom Christiansen tchrist at convex.com convex!tchrist
"EMACS belongs in <sys/errno.h>: Editor Too Big!" -me
More information about the Comp.unix.questions
mailing list