Skip to content

Instantly share code, notes, and snippets.

@isao
Created November 2, 2012 19:50
Show Gist options
  • Save isao/4003924 to your computer and use it in GitHub Desktop.
Save isao/4003924 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
# Copyright (c) William Uther ([email protected]) 2001
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the copyright holders nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a script for parsing the errors of a command line application
# and generating an applescript that will display those errors in a
# BBEdit Results Window.
# Expected use is something like the following: (tcsh)
# % jikes +E myFile.java |& BBErr.pl | osascript
# Customization:
# At the moment, this file is set up to read the "emacs format" err output of
# jikes. Search for the comment "match this line of the error" to find the
# regular expression that matches each line of output. It should be fairly easy
# to update for other result formats.
# The applescript generated has the name of the BBEdit app embedded in it.
# If you need to alter this, look for where the variable "$BBEditAppName"
# is set.
# KNOWN ISSUES:
# - There are some details I don't understand about how BBEdit uses the file
# offsets. This leads to the selection being off by one character in some
# cases. sigh.
# - It seems that BBEdit calls perl synchronously, and will not accept appleevents
# while doing so. This means you use this script entirely from within BBEdit.
# BBEdit takes its input in terms of character offset. Jikes' output is in
# terms of laid out output, with tabs being expanded to 8 spaces. This
# function takes that expansion into account for a single line.
sub handleTabs {
my ($line, $offset) = @_;
$tabSize = 8;
#print "\r Handle: '",$line,"', ", $offset, "\r";
#$offset--;
while ($line =~ m/\t/g) {
if (pos $line < $offset) {
$offset -= $tabSize-1;
} else {
last;
}
}
#print " result: ", $offset, "\r";
return $offset;
}
# Jikes outputs the selection as four numbers:
# - The line of the start of the selection
# - The character on that line of the start of the selectio
# - The line of the end of the selection
# - The character on that line of the end of the selection
#
# BBEdit takes just two numbers - the start and end offset in the
# file of the selection.
#
# This function converts from the former format to the latter.
# To do this it opens the file and reads through it. No caching is
# currently performed, so the file will be scanned separately for each error
# message.
#
# This function uses handleTabs.
#
# BUG: There are some details I don't understand about how BBEdit uses the file
# offsets. This leads to the selection being off by one character in some
# cases. sigh.
sub translateSelection {
my ($filename, $startLine, $startChar, $endLine, $endChar) = @_;
#$startPosn = $startChar;
#$endPosn = $endChar;
open(TESTSTREAM, $filename) or die "Couldn't convert selection data";
$chCount = 0;
$startPosn = 0;
# some brief sanity checks on the input selection
if ($startLine == 0) {
$startLine = 1;
$startChar = 0;
}
if ($endLine == 0) {
$endLine = $startLine;
$endChar = $startChar;
}
if ($startLine > $endLine) {
($startLine, $startChar, $endLine, $endChar) = ($endLine, $endChar, $startLine, $startChar);
} elsif ($startLine == $endLine) {
if ($startChar > $endChar) {
($startChar, $endChar) = ($endChar, $startChar);
}
}
$gotEndPosn = 0;
# look through the file for the appropriate lines
while($line = <TESTSTREAM>) {
$lineLength = length($line);
$lineNum = $.;
if ($lineNum == $startLine) {
$startChar = handleTabs($line, $startChar);
if ($startChar > $lineLength) {
$startChar = 0;
}
$startPosn = $chCount+$startChar;
}
if ($lineNum == $endLine) {
$endChar = handleTabs($line, $endChar);
#$endChar--;
if ($endChar > $lineLength) {
$endChar = $lineLength;
}
$endPosn = $chCount+$endChar;
$gotEndPosn = 1;
last;
}
$chCount += $lineLength;
}
close(TESTSTREAM);
if (! $gotEndPosn) {
$endPosn = $startPosn;
}
$line = $startLine;
return ($line, $startPosn, $endPosn);
}
# This is the start of the main script
open(INPUT,"-") or die "Can't get input stream";
open(APPLESCRIPT,">-") or die "Can't get output stream";
# NOTE: these lines fail from within BBEdit.
# it seems BBEdit calls perl synchronously and doesn't accept appleevents in the meantime.
#open(INPUT,"jikes +E DummyApp.java |& cat");
#open(APPLESCRIPT,"| osascript");
$le = "\r";
$BBEditAppName="BBEdit 6.5";
print APPLESCRIPT "tell application \"",$BBEditAppName,"\"", $le;
print APPLESCRIPT "set theData to {";
$needComma = 0;
while (<INPUT>) {
#match this line of the error
#if the regular expression doesn't match then ignore the line
next if !/^([^:]+):([0-9]+):([0-9]+):([0-9]+):([0-9]+): *([^:]+): *(.*)$/;
$filename = $1;
$startLine = $2;
$startChar = $3;
$endLine = $4;
$endChar = $5;
if ($6 eq "Warning") {
$warning = "Warning";
} elsif ($6 eq "Caution") {
$warning = "Note";
} else {
$warning = "Error";
}
$message = $7;
#start generating this property entry
if ($needComma) {
print APPLESCRIPT ", ";
}
$needComma = 1;
print APPLESCRIPT "{";
$unixFileName = $filename;
$quotedUnixFileName = $filename;
$quotedUnixFileName =~ s/\"/\\\"/g;
# add the Error/Warning label
if ($warning eq "Warning") {
print APPLESCRIPT "result_kind:warning_kind";
} elsif ($warning eq "Note") {
print APPLESCRIPT "result_kind:note_kind";
} else {
print APPLESCRIPT "result_kind:error_kind";
}
# set the file name
print APPLESCRIPT ", result_file: POSIX file \"";
print APPLESCRIPT $quotedUnixFileName;
print APPLESCRIPT "\"";
($lineOut, $startOffset, $endOffset) = translateSelection($unixFileName, $startLine, $startChar, $endLine, $endChar);
#set the result line
print APPLESCRIPT ", result_line:";
print APPLESCRIPT $lineOut;
#set the result start char
print APPLESCRIPT ", start_offset:";
print APPLESCRIPT $startOffset;
#set the result end char
print APPLESCRIPT ", end_offset:";
print APPLESCRIPT $endOffset;
#set the error message
#first, quote any quote marks in the message
$message =~ s/\"/\\\"/g;
print APPLESCRIPT ", message:\"";
print APPLESCRIPT $message;
print APPLESCRIPT "\"";
print APPLESCRIPT "}";
}
print APPLESCRIPT "}", $le;
print APPLESCRIPT "make new results browser with data theData with properties {name:\"Results Browser\"}", $le;
print APPLESCRIPT "end tell", $le;
close(APPLESCRIPT);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment