Monday, June 29, 2009

Error Checking

I was reading the book Mastering Regular Expressions by O'Reilly (BTW a great book and one I'd like to eventually do a review on), one of the initial topics the author spoke about was using regular expressions to check a file for errors. I liked the idea, but typically again we had to open the command prompt to run it and it was just not as "friendly" as I like things to be.

Onward we look to my context menu "hack". Basically what we'll do is write a perl script that will take whatever file was passed to it check it for errors and then when you want you can close it.

Lets look at our order of events here:
  1. Discuss the script
  2. Point you to the how to add to your context menu (we'll need to use the registry editor since windows doesn't seem to like perl scripts in the file types box)
  3. Try it out!
Script:
if (scalar(@ARGV)>0)
{


$file = @ARGV[0];
print "Testing $
file \n";
}
else

{
print "Please drag the file you would like to see errors in onto the screen\n";
$file = <>;

}

open DATAFILE, "$file" or die "Missing $file file.\n";
open (DATAFILE, $file);
@getData = <DATAFILE>;
close (DATAFILE);
$errors = 0;
$lineNumber = 1;

foreach $inputLine (@
getData)
{
if ($inputLine =~ m/\berror[(s]?\b/i)
{
print "$lineNumber ) $inputLine \n";

$errors++;
}
$lineNumber++;
}

print "Complete!\n$errors Errors found!";
$asdf = <>;


Breaking it down:
if (scalar(@ARGV)>0)
{


$file = @ARGV[0];
print "Testing $file \n";
}

else
{
print "Please drag the file you would like to see errors in onto the
screen\n";
$file = <>;

}


What this line does, is checks to make sure you at least have one argument, if you don't then it waits for you to type a file in that you want to check (or as stated you can drag the file onto the window). If you use an argument we'll print the file (in case you didn't actually type the filename in)

Next,
open DATAFILE, "$file" or die "Missing $file file.\n";
open (DATAFILE,
$file);
@getData = ;
close (DATAFILE);

$errors = 0;
$lineNumber = 1;

Open our file get the contents set our error and linenumber variables to zero.

Almost done:
foreach $inputLine (@getData)
{
if ($inputLine =~ m/\berror[(s]?\b/i)
{
print "$lineNumber ) $inputLine \n";
$errors++;
}

$lineNumber++;
}


This rolls through each line of the file (each line is a different item in the array), checks for words that are error OR errors OR error(, prints that line and then increments our error counter as well as we increment our linenumber variable everytime we move through the array.

Lets look at our Regular Expression:
$inputLine =~ m/\berror[(s]?\b/i


Breaking it down it literally means
match the beginning of a word, if it matches error error( or errors and ends the word and any variation of capitalization we can find we will return a positive match.

This can be modified to work with any kind of error or even any kind of other word you might want to look for in a particular file.

The last 2 lines basically keep the window from closing immediately if you haven't setup your system to keep the window open after running.

Next comes updating our registry to handle this!!! Check out this page, it contains a detailed how to modify our registry to add a command to the context menu.
What we'll be looking for is the txtfile entry.
if there isn't a key for shell add one, then add Check_For_Errors (or insert whatever you want to call it), then add one more key for command. This is the command I stuck in for the REG_SZ:
cmd.exe /k "C:\batch\checkErrors.pl %1"

So what that's going to do is open a command prompt and run the following which happens to be our perl script. just substitute the location where you saved your perl script at.

Lets check it out, I tried the above script on a text file containing this text:
This line contains an error.
if I knew any better there would be no errors in this file.
But unfortunately I will always make some kind of Error.
Now I know this line doesn't contain one.
But this one contains one with a ( like this error(
the only problem we'll run into is if we get errors(
Good luck let me know how well it works out for you.