Solved

Perl for Wamp: How to Run Scripts that Require Unix Diff?

Posted on 2006-11-02
47
786 Views
Last Modified: 2012-05-05
I have a working installation of WAMP on XP Pro. I installed the Wamp add-on of ActiveState Perl and it is working fine for simple scripts, but it does not include Diff. I need to use a Perl script that relies on the Unix Diff pod.  Is there a Wamp-compatible replacement for the Unix Diff?  If I install and run Cygwin (http://www.cygwin.com) on Windows, can Wamp's Perl use the Unix-like Diff module in Cygwin?
0
Comment
Question by:Randall-B
  • 24
  • 22
47 Comments
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17857963
0
 

Author Comment

by:Randall-B
ID: 17858102
manav_mathur,
    From the description, it looks like that module does not include all the functionality of the Unix diff, but it's worth a try.
    How would I install the .pm module in Wamp's Perl add-on? Do I just copy the .pm file to the C:\wamp\perl\lib folder, or do I have to adjust something to make Perl aware of it?
  How would I adjust a script that currently uses calls to the Unix diff?  For example, my current Unix Perl script has:
        open(DIFF,"diff -f $DiffArgs $OldFile $NewFile |");
(you can see the whole script at http://www.foyastar.com/htmldiff_pl-3.htm).
   Thanks.
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17860830
Do you have a C:\wamp\perl\bin folder?? If yes, is there an executable by the name of ppm??
0
 

Author Comment

by:Randall-B
ID: 17860941
manav_mathur,
   Yes, I have ppm.bat .  Is that the one?

Also, I noticed that the "manifest" in the text::diff download file shows some paths including a directory I don't have ( t\ ) and it has a make file. Do I have to compile it?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17861306
No. Since you are on windows, you can simply download the zip file corresponding to the module from
http://ppm.activestate.com/PPMPackages/

and follow the instructions in the readme file.
0
 

Author Comment

by:Randall-B
ID: 17861448
I'm a bit confused by their readme instructions.  It says: "To install this ActiveState PPM package, run the following command in the current directory:  ppm install Text-Diff.ppd ."
    But I don't know which directory they mean by "the current directory."
And I don't know which command line it refers to (the Windows explorer "run" command, the DOS prompt, or some kind of Perl command)?  Please explain. Thanks.
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17861498
ok
go to the directory where you unxipped the file and issue this command
c:/perl/bin/ppm install Text-Diff.ppd
0
 

Author Comment

by:Randall-B
ID: 17861524
Do you mean I should open a DOS shell prompt and type that command at the DOS prompt?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17861582
yes.
0
 

Author Comment

by:Randall-B
ID: 17861811
OK. From the zip, I copied the following files into c:\wamp\perl\bin where the ppm.bat file is:

1) Text-Diff.ppd
2) MSWin32-x86-multi-thread-5.8
   Then I went to that directory in DOS and issued the command:
C:\wamp\perl\bin>ppm install Text-Diff.ppd
   But these error messages came up:

Bad name after privlibexp' at C:/wamp/perl/lib/Config.pm line 1219.
Compilation failed in require at C:/wamp/perl/lib/DynaLoader.pm line 25.
BEGIN failed--compilation aborted at C:/wamp/perl/lib/DynaLoader.pm line 25.
Compilation failed in require at C:/wamp/perl/site/lib/Win32API/Registry.pm li
 10.
Compilation failed in require at C:/wamp/perl/site/lib/Win32/TieRegistry.pm li
 26.
BEGIN failed--compilation aborted at C:/wamp/perl/site/lib/Win32/TieRegistry.p
line 26.
Compilation failed in require at ppm.bat line 15.
BEGIN failed--compilation aborted at ppm.bat line 15.

I noticed that Algorithm-Diff is mentioned as a dependency in the Text-Diff.ppd file, so I download Algorithm-Diff and tried to install that, but the same errors come up. What could be wrong?
0
 

Author Comment

by:Randall-B
ID: 17862025
By the way, here is what some of the failed lines say:

Line 1219 of Config.pm says:
    'privlibexp' => 'c:\wamp\perl\\lib',    

Line 25 of C:/wamp/perl/lib/DynaLoader.pm says:  
    Use config;

Line 10 of C:/wamp/perl/site/lib/Win32API/Registry.pm  says:
    require DynaLoader;

Line 26 of  C:/wamp/perl/site/lib/Win32/TieRegistry.pm  says:
    use Win32API::Registry 0.12 qw( :KEY_ :HKEY_ :REG_ );

Line 15 of  bin\ppm.bat  says:
    use Win32::TieRegistry;

Do you see why those would fail?  Thanks.
0
 
LVL 16

Accepted Solution

by:
manav_mathur earned 500 total points
ID: 17862269
the correct path should be 'c:\wamp\perl\lib', so why the double quotes are coming I do not understand.
The others erros are because of this. Since the perl library path is not setup correctly, it would not recognize other modules.

Although changing Config.pm is an option, Im not sure I should suggest that to you.

On the other hand, I was searching the net and came across this
http://gnuwin32.sourceforge.net/packages/diffutils.htm
0
 

Author Comment

by:Randall-B
ID: 17862338
That double slashes caught my attention, too, but then I noticed the Config.pm file has them all throughout, before the last directory name. So maybe it's supposed to be that way, but I don't know why.

Maybe I'll try gnuWin32 package.  If I can get it installed, do you think my Perl script will need any modifications in order to use it? Thanks.
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17862548
It doesnt need them as long as its enclosed in single quotes. Atleast thats what I know.
You should try out the functionality of the gnuWin32 diff tool. AFAIK, it should be similar to the GNU diff, although I have never used it.
0
 

Author Comment

by:Randall-B
ID: 17862932
I got the gnuWin32 installed.  It installs a diff.exe file in C:\Program Files\GnuWin32\bin .  It seems to run OK from the DOS command prompt, like:
       C:\Program Files\GnuWin32\bin> diff C:\wamp\www\old.htm C:\wamp\www\new.htm
   However, I can't get it to run from my Perl script.  I changed this line:
               open(DIFF,"diff -f $DiffArgs $OldFile $NewFile |");
to this:
               open(DIFF,"C:\Program Files\GnuWin32\bin\diff.exe -f $DiffArgs
               $OldFile $NewFile |");
but that did not work.
    Any ideas on how to get this diff to run from Perl?  Thanks.
0
 
LVL 84

Expert Comment

by:ozo
ID: 17862983
how about "C:\\Program Files\\GnuWin32\\bin\\diff.exe
0
 

Author Comment

by:Randall-B
ID: 17863030
No, that doesn't work either.  I'm not getting an error message; but it seems like Perl is ignoring that part of the script (I can tell that it is going past those lines and is just printing the output from lines 262 - 269 (which is supposed to print after the diff output):

262 print $FH "<i>How to read this comparison:</i>
263 <ul>
264  <li>removed old parts are marked as $Style{StartOld}this one$Style{EndOld}
265    <li>new parts are marked as $Style{StartNew}this one$Style{EndOld}
266  </ul>";
267 print $FH "HTML Mode is experimental." unless($TM);
268 print $FH "  <hr>
269 ";

It's strange. The script worked perfectly on a commercial Unix host. What could be wrong here on Wamp?
0
 

Author Comment

by:Randall-B
ID: 17863227
I just noticed I had commented out the line:
   use Pod::Usage;
when I first tried to run the script on Perl, because that line caused a 500 server error on Wamp (but not on Unix).  I guess the Usage pod is not included with ActiveState Perl on Wamp.
   I wonder if the lack of that "use Pod::Usage" line could be one problem (although it still seems like the diff is not getting called properly from the script, either).  How would I add the Usage pod?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17865780
Do you have pod::Usage installed??
you should include

use CGI::Carp qw(fatalsToBrowser warningsToBrowser) ;
warningsToBrowser(1) ;

somewhere at the top of the script, to see the actual errors in your script on the web page instead of the standard 500 error.
0
 

Author Comment

by:Randall-B
ID: 17865838
No, I didn't have Usage.pm installed.  (I copied the Usage.pm file into the lib directory a few minutes ago and tested with you error handler, and here is the result:

Bad name after privlibexp' at C:/wamp/perl/lib/Config.pm line 1219.

Compilation failed in require at C:/wamp/perl/lib/Pod/Usage.pm line 403.

BEGIN failed--compilation aborted at C:/wamp/perl/lib/Pod/Usage.pm line 403.

Compilation failed in require at C:/wamp/www/cgi-bin/htmldiff-5.cgi line 11 (*that is the line with the "Use Pod::Usage;" statement*) .

BEGIN failed--compilation aborted at C:/wamp/www/cgi-bin/htmldiff-5.cgi line 11.)

I probably didn't install the Usage.pm properly. But the installation package is like the ones that failed yesterday, so I guess I'm stuck.

     By the way, when I comment out line 11 (so I'm not asking it to use the Usage pod), the script does not give any error messages; it runs, but it fails to show the diff results. (Instead of showing the diff results, it simply prints some html that is supposed to print after displaying the diff results.)
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17865968
Did you simply copy the file, or did you install it using the ppm utility??
The file should be located as
C:/wamp/perl/lib/Pod/Usage.pm
0
 

Author Comment

by:Randall-B
ID: 17866011
   Oh, I just discovered something:  I had been looking in lib instead of lib/Pod.  When I looked in lib/Pod, I see that it already has Usage.pm installed there as part of the ActiveState package.
   So why would the Use Pod::Usage statement cause an error? Maybe because of the "bad name" error in Config.pm at 1219?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17866169
put
use Diagnostics;
at the top of your script....
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:Randall-B
ID: 17866300
   Another discovery:  I don't think the script really requires the Usage pod.  I tried removing that line and ran it on a Unix server, and it works fine without it.  I think that line is a vestigage of part of the script that I had deleted (it was used for a "verbose" switch; I removed it because it didn't seem to make any difference). So I think we can ignore the Usage problem and just comment it out.

   When I put "use Diagnostics;", I get a 500 error.  
Here's the error:
Bad name after privlibexp' at C:/wamp/perl/lib/Config.pm line 1219.
Compilation failed in require at C:/wamp/perl/lib/Diagnostics.pm line 176.
BEGIN failed--compilation aborted at C:/wamp/perl/lib/Diagnostics.pm line 176.
Compilation failed in require at C:/wamp/www/cgi-bin/htmldiff-5.cgi line 6.
BEGIN failed--compilation aborted at C:/wamp/www/cgi-bin/htmldiff-5.cgi line 6.
   It all seems to be caused by line 1219 in Config.pm.  
That line says:   1219   'privlibexp' => 'c:\wamp\perl\\lib',
   As a brave soul, I edited that line to have only one backslash, but the script still gives the same error, pointing to the same line.  So it's not the slash, and I went ahead and put it back in.
    At this point, I think the best thing to do is:  comment out the "Use Pod::Usage" line, and then try to get it to use the diff.  I think the real problem is that it is not running diff.  My script line 1209 says:

open(DIFF,"C:\Program Files\GnuWin32\bin\diff.exe -f $DiffArgs $OldFile $NewFile |");

We have tried different variations on that line, and nothing works.  So I'm stumped. Maybe it's just not compatible, although the documentation makes it look like the Unix diff and this win32 diff are almost the same.



0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17866414
- Are you sure some condition is making the opn statement not run??
- Just run a simple
open "echo 'abcde' |"

to see if the problem is in the script or something to do with diff??

0
 

Author Comment

by:Randall-B
ID: 17866785
The script runs without error messages when I use this line (although it does not show the diffs):

      open(DIFF,"C:\Program Files\GnuWin32\bin\diff.exe -f $DiffArgs $OldFile $NewFile |");

But when I comment out that line, and this this line instead,

        open "echo 'abcde' |"
then I get this error referring to the next line:

syntax error at C:/wamp/www/cgi-bin/htmldiff-5.cgi line 212, near "open"
Execution of C:/wamp/www/cgi-bin/htmldiff-5.cgi aborted due to compilation errors.
    The Line 212 mentioned in the error message is:

open(FH,$OldFile);

But that error is only when I comment out the original line and use the test line. Also, it is important to note that the whole script works perfectly on a Unix server.
0
 

Author Comment

by:Randall-B
ID: 17866830
Correction:
   I just noticed I had forgotten to put the semicolon at the end of the open "echo 'abcde' |";  .  
   When I added the  ;  the script runs without any error messages, but it does not print out the "abcde".
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17867257
my mistake, try
open(DIFF,"echo 'abcde' |");
0
 

Author Comment

by:Randall-B
ID: 17867365
OK. I did this, and it printed  'abcde' :

open(DIFF,"echo 'abcde' |");
  while(<DIFF>){
     print;
  }
  print "";
So it is paying attention to that part of the script, at least.  But nothing is printed for "DIFF" when I do this:
      open(DIFF,"C:\Program Files\GnuWin32\bin\diff $OldFile $NewFile |");
        while(<DIFF>){
            print;
         }
        print "";
  I tried different variations, like   \diff.exe  ,  \diff ,  diff.exe -f $DiffArgs , etc.  Nothing works.  Any ideas?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17867480
- Does running diff on the command line work on the same 2 files that you are testing against??
- Do $OldFile, $NewFile refer to the sone sample file. AFAIK, diff gives no output if it doesnt find a difference betweent he 2 files.
0
 

Author Comment

by:Randall-B
ID: 17867696
Yes, it works on the command line. I copied the the two files into the GnuWin32\bin folder, and here is the DOS command line output:

C:\Program Files\GnuWin32\bin>diff old.htm new.htm
4c4
< <TITLE>OLD</TITLE>
---
> <TITLE>NEW</TITLE>
8,9c8,9
< <P ALIGN="CENTER"><B>OLD TEST</B></P>
< <P>This is the old file.</P>
---
> <P ALIGN="CENTER"><B>NEW TEST</B></P>
> <P>This is the new file.</P>

I tried setting the script to call the files from that folder, and still no Diff output from the script.
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17868481
Does this output on STDOUT or STDERR??
0
 

Author Comment

by:Randall-B
ID: 17868583
The only thing I see is in lines 236-238, which appears to be STDOUT:
    my $FH;
    $FH=\*STDOUT;
    print $FH "\n" ;

By the way, I also tried a very short script just to test the diff, and it doesn't work either:

#!c:/wamp/perl/bin/perl
    print "Content-type: text/html\n\n";
open(DIFF,"C:\Program Files\GnuWin32\bin\diff.exe C:\wamp\www\old.htm C:\wamp\www\new.htm |");
      while(<DIFF>){
       print;
      }
     print "";

I was just trying to print the direct results of the command line. There is no error message; just a blank white page. Is there a better way to test printing the direct output of diff?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17868628
#!c:/wamp/perl/bin/perl
print "Content-type: text/html\n\n";
open(DIFF,"C:\Program Files\GnuWin32\bin\diff.exe C:\wamp\www\old.htm C:\wamp\www\new.htm 2>&1 |") or die "$!" ;
while(<DIFF>){
  print;
}
print "End of command";
close(DIFF) ;
0
 

Author Comment

by:Randall-B
ID: 17868669
OK. That printed "End of command," but nothing else.  I wonder why diff works on the command line but is not working from Perl?
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17868769
Wierd!! Can you try

#!c:/wamp/perl/bin/perl
print "Content-type: text/html\n\n";
open(DIFF,"C:\\Program Files\\GnuWin32\\bin\\diff.exe C:\\wamp\\www\\old.htm C:\\wamp\\www\\new.htm 2>&1 |") or die "$!" ;
while(<DIFF>){
  print;
}
print "End of command";
close(DIFF) ;


0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17868775
and this too, just to see


#!c:/wamp/perl/bin/perl
print "Content-type: text/html\n\n";
my $oput = `C:\Program Files\GnuWin32\bin\diff.exe C:\wamp\www\old.htm C:\wamp\www\new.htm 2>&1` ;
print $oput;
print "End of command";
close(DIFF) ;
0
 

Author Comment

by:Randall-B
ID: 17868951
The last test only prints "End of command."  But maybe you're on to something with the first of those two tests, which outputs this:  

'C:\Program' is not recognized as an internal or external command, operable program or batch file. End of command

It looked like it was having a problem with the space between Program  Files, so I copied the GnuWin32 folder to the wamp folder and tried this:

#!c:/wamp/perl/bin/perl
print "Content-type: text/html\n\n";
open(DIFF,"C:\\wamp\\GnuWin32\\bin\\diff.exe C:\\wamp\\www\\old.htm C:\\wamp\\www\\new.htm 2>&1 |") or die "$!" ;
while(<DIFF>){
  print;
}
print "End of command";
close(DIFF) ;

and it printed the diff output!  Now I need to work that into the main script and see what happens.
0
 
LVL 16

Assisted Solution

by:manav_mathur
manav_mathur earned 500 total points
ID: 17868987
try

#!c:/wamp/perl/bin/perl
print "Content-type: text/html\n\n";
open(DIFF,"C:\\Progra~1\\GnuWin32\\bin\\diff.exe C:\\wamp\\www\\old.htm C:\\wamp\\www\\new.htm 2>&1 |") or die "$!" ;
while(<DIFF>){
  print;
}
print "End of command";
close(DIFF) ;
0
 

Author Comment

by:Randall-B
ID: 17869211
Great! C:\\Progra~1\\  . . . works
   How should be work this in to the main script?
 
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17869253
wherever you want to place it....
0
 

Author Comment

by:Randall-B
ID: 17869341
I placed this line where the old open( ) statement use to be in the main file, but the script still does not process to show the diff:

open(DIFF,"C:\\Progra~1\\GnuWin32\\bin\\diff.exe C:\\wamp\\www\\old.htm C:\\wamp\\www\\new.htm 2>&1 |") or die "$!" ;

(But when I added a debug print like  while(<DIFF>){  print; }, then it does manually show it.)
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17869421
You must be doing something with the DIFF filehandle??
0
 

Author Comment

by:Randall-B
ID: 17869445
I just added the -f switch after diff.exe, and it is finally showing something (although not at all the same as when run on Unix). Maybe a different switch is required on GnuWin32. I'll check the documentation, because I know GnuWin32 uses switches for different effects than the Unix diff.  Maybe that's the only problem now.  
    But here is what the script does with DIFF after it opens it:

open(FH,$OldFile);
push(@OldLines,'');
push(@NewLines,'');
while(<FH>){
  chomp;
  push(@OldLines,$_);
  push(@NewLines,$_);
  warn"unclosed or unopened tag detected, malfunction warning: $_" if(/<[^>]*$|^[^<]*>/);
}
close(FH);
$iii=0;

# no strict 'ref';
my $TmpFile="$ENV{HOME}/.HtmlDiff";
my $FH;
$FH=\*STDOUT;
print $FH "\n" ;

#
while(<DIFF>){
  if(/^d(\d+)(\s+(\d+))?$/){
    $iiii= defined $2 ? $2 : $1;
    for($ii=$iii;$ii<$1;$ii++){PrintLine('Equal',$NewLines[$ii])}
    for($ii=$1;$ii<=$iiii;$ii++){PrintLine('Old',$NewLines[$ii])}
    $iii=$iiii+1;
  }
  elsif(/^c(\d+)(\s+(\d+))?$/){
    $iiii= defined $2 ? $2 : $1;
    for($ii=$iii;$ii<$1;$ii++){PrintLine('Equal',$NewLines[$ii])}
    for($ii=$1;$ii<=$iiii;$ii++){PrintLine('Old',$NewLines[$ii])}
    while(defined($is=<DIFF>)){
      chomp;
      if($is=~/^\.$/){last}
      else{PrintLine('New',$is)}
    }
    $iii=$iiii+1;
  }
  elsif(/^a(\d+)$/){
    $iiii=$1;
    for($ii=$iii;$ii<=$1;$ii++){PrintLine('Equal',$NewLines[$ii])}
    while(defined($is=<DIFF>)){
      if($is=~/^\.$/){last}
      else{PrintLine('New',$is)}
    }
    $iii=$1+1;
  }
}
for($ii=$iii;$ii<=$#NewLines;$ii++){PrintLine('Equal',$NewLines[$ii])}
unlink($OldFile,$NewFile);
print $FH "<hr>";
# close($FH);

0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17869476
Yes, you need to check the documentation.
0
 

Author Comment

by:Randall-B
ID: 17869573
Thanks manav_mathur,
   I'll see if I can figure it out from here, based on the documentation. You have been very patient and helpful. I think you've answered my original question, so I'm accepting your answer.  I really appreciate all the time you spent on this, so I'm increasing the points. Thanks again.
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 17869645
You're welcome.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now