Skip to content

Instantly share code, notes, and snippets.

@evincarofautumn
Last active December 23, 2015 13:49
Show Gist options
  • Save evincarofautumn/6644840 to your computer and use it in GitHub Desktop.
Save evincarofautumn/6644840 to your computer and use it in GitHub Desktop.
A simple decoder like `c++filt` for z-encoding–mangled names.
#!/usr/bin/perl
# Originally written and placed in the public domain by Ashley Yakeley, 2003.
use warnings;
use strict;
use Pod::Usage;
use Getopt::Long;
my $help = 0;
GetOptions("help|h|?" => \$help);
pod2usage(2) if $help;
sub commas($) {
my $i = shift;
return '' if $i == 0;
return ' ' if $i == 1;
return ',' x ($i - 1);
}
my %table =
(Z =>
{
C => ':',
L => '(',
M => '[',
N => ']',
R => ')',
Z => 'Z',
},
z =>
{
a => '&',
b => '|',
c => '^',
d => '$',
e => '=',
g => '>',
h => '#',
i => '.',
l => '<',
m => '-',
n => '!',
p => '+',
q => '\'',
r => '\\',
s => '/',
t => '*',
u => '_',
v => '%',
z => 'z',
}
);
sub decode($) {
my $rest = shift;
my $acc = '';
while ($rest =~ /([^Zz]*)([Zz].*)/) {
$acc .= $1;
if ($2 =~ /^([Zz])([A-Za-z])(.*)/) {
$acc .= $table{$1}->{$2} // '<?>';
$rest = $3;
} elsif ($2 =~/^Z([0-9]+)T(.*)/) {
$acc .= "(".commas($1).")";
$rest = $2;
} elsif ($2 =~/^Z([0-9]+)H(.*)/) {
$acc .= "(#".commas($1)."#)";
$rest = $2;
} elsif ($2 =~/^Z([0-9]+)U(.*)/) {
$acc .= chr $1;
$rest = $2;
} else {
$acc .= "<?>$2";
$rest = '';
}
}
return "$acc$rest";
}
if (@ARGV) {
for (@ARGV) {
s/(\w+)/decode($1)/eg;
print "$_\n";
}
} else {
while (<>) {
s/(\w+)/decode($1)/eg;
print;
}
}
__END__
=head1 NAME
ghcfilt - A simple decoder like c++filt for z-encoding-mangled names.
=head1 SYNOPSIS
ghcfilt NAMES...
ghcfilt --help
ghcfilt
=head1 OPTIONS
=over 4
=item B<--help>, B<-h>, B<-?>
Print a help synopsis and exit.
=back
=head1 DESCRIPTION
B<ghcfilt> decodes names that have been mangled with GHC's z-encoding.
You can pass names as command line options, or on standard input if no
names are specified.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment