[SPOILER] Re: [Israel.pm] What does this code do? (No. 3)

Yosef Meller mellerf at netvision.net.il
Sun Jul 11 04:50:11 PDT 2004


Shlomi Fish wrote:
 > Here is the next installment in the "What does this code do?" series of
 > quizzes. You can post solutions to the list, but mark them with a 
[SPOILER]
 > in the title. Other discussions are also welcome.
 >
 > The script in question is:
 >
 > <<<
 > #!/usr/bin/perl -w
 >
 > use strict;
 >
 > my %lines_to_extract;
 >
 > open DECLS, "bash analyze-globals.sh |";
 > while (<DECLS>)
 > {
 >     chomp($_);
 >     my ($file,$line_num,$text) = /^(\w+\.c):(\d+):(.*)$/;
 >     push @{$lines_to_extract{$file}}, +{ 'l' => $line_num, 't' => 
$text, };
 > }
 > close(DECLS);
 >
 > my @lines_to_put = ();
 > foreach my $file (keys(%lines_to_extract))
 > {
 >     my $lines = $lines_to_extract{$file};
 >     my $line_num = 1;
 >     my $extracted_line_idx = 0;
 >     open I, "<$file";
 >     open O, ">$file.new";
 >     while (<I>)
 >     {
 >         if (($extracted_line_idx < @$lines) &&
 >             ($line_num == $lines->[$extracted_line_idx]->{l})
 >            )
 >         {
 >             push @lines_to_put, $_;
 >             $extracted_line_idx++;
 >         }
 >         else
 >         {
 >             print O $_;
 >         }
 >     }
 >     continue
 >     {
 >         $line_num++;
 >     }
 >     close(I);
 >     close(O);
 >     rename("$file.new", "$file");
 > }
 > open GLOBALS, ">globals.c";
 > print GLOBALS @lines_to_put;
 > close(GLOBALS);
 >
 >
 > It makes use of the bash script analyze-globals.sh which is:
 >
 > <<<
 > #!/bin/bash
 > grep -nP '^\S.*;' *.c | grep -v static | grep -vP '^\w+\.c:\d+:}'
 >
 >
 > Regards,
 >
 > 	Shlomi Fish
 >
 >
 >
 >

This time you chose revealing variable names, so it was easy.
The script removes global variables from a bunch of files and puts them
in globals.c, for good order I guess (haven't used C for a while).

The program assumes that the line numberes are sorted, which should be
true, considering the method of generation.

The perl version I suggest:

 >>>>>>>>
#!/path/to/perl -w
open DECLS, "bash analyze-globals.sh |";
while (<DECLS>) {
	/^(\w+\.c):(\d+):(.*)\n$/ and push @{$lines_to_extract{$1}},
	+{ 'l' => $2, 't' => $3 };
}

foreach my $file (keys(%lines_to_extract)) {
     my @lines = @{$lines_to_extract{$file}};
     my $line_num = 1;
     open I, "<$file";
     open O, ">$file.new";
     while (($_ = <I>) && @$lines)
     {
         if ($line_num++ == $lines->[0]->{l}) {
		# We'll use STDOUT for better flexibility, and one less
		# filehandle to worry aboyut
             print;
             shift @$lines;
         } else {
             print O $_;
         }
     }
     close(I);
     close(O);
     rename("$file.new", "$file");
}
<<<<<<

Invoke with:
$ ./thescript.pl > myglobals.c

I'm sure there must be a way to use the -i switch, but I can't think of
it right now.

-- 
perl -e'$b=unpack"b*",pack"H*","59dfce2d6b1664d3b26cd9969503";
for(;$a<length$b;$a+=9){print+pack"b8",substr$b,$a,8;}'
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 256 bytes
Desc: OpenPGP digital signature
Url : http://perl.org.il/pipermail/perl/attachments/20040711/3aad7b9f/attachment.pgp 


More information about the Perl mailing list