perl -MO=Deparse wc.c > deparse.pl
####
gcc wc.c -E > wc.txt
##
##
# note the comma. This will unshift the first command line
# argument onto @ARGV and set $_
unshift @ARGV, $_ = $ARGV[0];
# clear $_ if its length is not 2
$_ = '' if length $_ != 2;
# if the first argument is -p or -P, print The Perl Journal
if (/-p/i)
{
# \cH is a backspace
printf "*\cHThe Perl Journal\n";
exit 0;
}
# set $i[11] to the length of @ARGV (remember, this is one greater
# than the number of arguments) and set $i[10] to the original length
# (number of files on the command line
$i[10] = ($i[11] = scalar @ARGV) - 1;
# check the while{} at the end
# this will execute once for each file
do
{
# if we had no command line arguments, we need to set $i[10] to 1 to ensure
# the loop will exit and we need to read our arguments from STDIN.
if ($i[11] < 2)
{
$i[10] = 1;
*F = *STDIN;
}
# if we had arguments, we want to open each file in turn. Note that O_RDONLY
# is a filehandle, not a constant. Also note that with the while at the end
# of this loop, $i[10] is being decremented, so we can loop through the
# files this way.
else
{
open O_RDONLY, $ARGV[$i[11] - $i[10]];
*F = *O_RDONLY;
}
# read one byte at a time from the file, until EOF.
while (read(F, $i, 1) > 0)
{
# increment $i[4] by one (thus, this will be the file size)
++$i[4];
# set $_ to whatever byte we read
$_ = $i;
# if $_ is a newline, then the match will return 1, thus setting $i[3] to
# the number of lines in the file. ( *pp^0x0A) is superfluous in the
# Perl program
# But it is used in the C program. My C is pretty rusty, but here goes:
# i[3] += m = ( *pp^0x0A ) ? 0 : 1;
# pp has been set to i, the last character read. Here, we do an XOR
# with 0x0A (a newline character). If any bits are set, we know it's
# not a newline, so m is set to 0, else m is set to 1. i[3] is
# incremented by m.
# The /* in the regex appears to be an artifact left over from an
# embedded comment
# in the obfu: $i[3]+=m=( *pp^0x0A)?/*\n=;#*/0:1;
$i[3] += m[( *pp^0x0A)?/*\n];
#-------------------------------------
# The following section is rather confusing. It is a word count. It works by
# setting $i[1] to a true value when it encounters a white space charater and
# then incrementing $[2] by one when it encounters a non-whitespace character
# (whitespace as defined by the character class in the match)
# Again, we see the /* as an artifact from the original file:
# if(m=/*[ \n\f\r\xB]=#*/q
# Ff we match a space, newline, formfeed, carriage return, or cntl-B(?)
# I believe this is where the embedded tab should be, but on my system,
# it was transformed to a space.
if (m[/*[ \n\f\r\xB]])
{
# if we've set $i[1], then we want to increment $i[2] by one
# and reset $i[1] to 0 (false)
if ($i[1])
{
++$i[$i[1]];
$i[1] = 0;
}
}
# if we didn't match, set $i[1] to 2 (which is the index of the array
# element we wish to increment for counting the above characters). For
# the most part, this means, "set this variable if we have a non-
# whitespace character"
else
{
$i[1] = 2;
}
}
#-------------------------------------
# if we got this far and $i[1] is true (it will be set to 2), then we have
# an extra word that we didn't account for, so we add 1 to the word count
if ($i[1])
{
++$i[$i[1]];
}
# print number of lines, word count, file size, and the name of the file
printf "%7d %7d %7d %s\n", $i[3], $i[2], $i[4], $ARGV[$i[11] - $i[10]];
close F;
# if we had more than one argument, we need to total the results
if ($i[11] > 2)
{
# This is setting $i[6] to $i[8] by adding whatever is in @i[2..4] and
# then resetting that value. When we get to $i[5], it's never been set
# and is evaluated as zero. This causes the entire expression
# '$i[$i[1] + 4] += $i[$i[1]]' to return a zero, evaluating as false and
# thus terminating the loop.
for ($i[1] = 2; $i[$i[1] + 4] += $i[$i[1]]; ++$i[1])
{
$i[$i[1]] = 0;
}
$i[1] = 0;
}
} while --$i[10];
# if we had more than one argument, we need to print the results
if ($i[11] > 2)
{
printf "%7d %7d %7d total\n", $i[7], $i[6], $i[8];
}
##
##
#include
#include
#include
#include
main(int argc, char *argv[])
{
int m=1, i[14];
char * pp;
int p=-1;
int q, F=3;
char * qq = "Hello\, world!\n";
/* red herring? */
i[12]=537463307; i[13]=3085;
if (m+-p?(argc>1&&!strcmp(argv[1],"-p"))?p+i? 1 : 1 : 0 : 0)
{
printf(qq); exit(0);
}
qq="=;#"; argv[0][0]='\0';
memset(i,0,48);
i[10]=(i[11]=(q =0) + argc)-1;
do{
if(i[11]<2)
{
i[10]=1; q =F=0;
}
else
{
open( argv[i[11] - i[10]], 0 ) ;
}
while(read(F, i , 1)>0)
{
++i[4]^(q=0);
pp=i;
i[3] += m=(*pp^0x0A)? 0:1;
for(qq=&i[12];*qq;*pp^*qq++||(q=1));
if(m=q)
{
if(i[1])
{
i[i[1]]++;
i[1]=0;
}
}
else
{
i[1]=2;
}
}
if(i[1])
{
i[i[1]]++;
};
printf("%7d %7d %7d %s\n", i[3], i[2], i[4], argv[i[11]-i[10]]);
close(F);
if(i [11]>2)
{
for( i[1]=2;i[i[1]+4]+=i[i[1]];i[1]++)
{
i[i[1]]=0;
};i [1]=0;
}
} while(-- i [10]);
if(i[11]>2)
{
printf("%7d %7d %7d total\n",i [7],i [6],i [8]);
}
}