1#!/usr/local/bin/perl -w
2
3# vimparse.pl - Reformats the error messages of the Perl interpreter for use
4# with the quickfix mode of Vim
5#
6# Copyright (c) 2001 by Joerg Ziefle <joerg.ziefle@gmx.de>
7# You may use and distribute this software under the same terms as Perl itself.
8#
9# Usage: put one of the two configurations below in your ~/.vimrc (without the
10# description and '# ') and enjoy (be sure to adjust the paths to vimparse.pl
11# before):
12#
13# Program is run interactively with 'perl -w':
14#
15# set makeprg=$HOME/bin/vimparse.pl\ %\ $*
16# set errorformat=%f:%l:%m
17#
18# Program is only compiled with 'perl -wc':
19#
20# set makeprg=$HOME/bin/vimparse.pl\ -c\ %\ $*
21# set errorformat=%f:%l:%m
22#
23# Usage:
24#	vimparse.pl [-c] [-f <errorfile>] <programfile> [programargs]
25#
26#		-c	compile only, don't run (perl -wc)
27#		-f	write errors to <errorfile>
28#
29# Example usages:
30#	* From the command line:
31#		vimparse.pl program.pl
32#
33#		vimparse.pl -c -f errorfile program.pl
34#		Then run vim -q errorfile to edit the errors with Vim.
35#
36#	* From Vim:
37#		Edit in Vim (and save, if you don't have autowrite on), then
38#		type ':mak' or ':mak args' (args being the program arguments)
39#		to error check.
40#
41# Version history:
42#	0.2 (04/12/2001):
43#		* First public version (sent to Bram)
44#		* -c command line option for compiling only
45#		* grammatical fix: 'There was 1 error.'
46#		* bug fix for multiple arguments
47#		* more error checks
48#		* documentation (top of file, &usage)
49#		* minor code clean ups
50#	0.1 (02/02/2001):
51#		* Initial version
52#		* Basic functionality
53#
54# Todo:
55#	* test on more systems
56#	* use portable way to determine the location of perl ('use Config')
57#	* include option that shows perldiag messages for each error
58#	* allow to pass in program by STDIN
59#	* more intuitive behaviour if no error is found (show message)
60#
61# Tested under SunOS 5.7 with Perl 5.6.0.  Let me know if it's not working for
62# you.
63
64use strict;
65use Getopt::Std;
66
67use vars qw/$opt_c $opt_f $opt_h/; # needed for Getopt in combination with use strict 'vars'
68
69use constant VERSION => 0.2;
70
71getopts('cf:h');
72
73&usage if $opt_h; # not necessarily needed, but good for further extension
74
75if (defined $opt_f) {
76
77    open FILE, "> $opt_f" or do {
78	warn "Couldn't open $opt_f: $!.  Using STDOUT instead.\n";
79	undef $opt_f;
80    };
81
82};
83
84my $handle = (defined $opt_f ? \*FILE : \*STDOUT);
85
86(my $file = shift) or &usage; # display usage if no filename is supplied
87my $args = (@ARGV ? ' ' . join ' ', @ARGV : '');
88
89my @lines = `perl @{[defined $opt_c ? '-c ' : '' ]} -w "$file$args" 2>&1`;
90
91my $errors = 0;
92foreach my $line (@lines) {
93
94    chomp($line);
95    my ($file, $lineno, $message, $rest);
96
97    if ($line =~ /^(.*)\sat\s(.*)\sline\s(\d+)(\.|,\snear\s\".*\")$/) {
98
99	($message, $file, $lineno, $rest) = ($1, $2, $3, $4);
100	$errors++;
101	$message .= $rest if ($rest =~ s/^,//);
102	print $handle "$file:$lineno:$message\n";
103
104    } else { next };
105
106}
107
108if (defined $opt_f) {
109
110    my $msg;
111    if ($errors == 1) {
112
113	$msg = "There was 1 error.\n";
114
115    } else {
116
117	$msg = "There were $errors errors.\n";
118
119    };
120
121    print STDOUT $msg;
122    close FILE;
123    unlink $opt_f unless $errors;
124
125};
126
127sub usage {
128
129    (local $0 = $0) =~ s/^.*\/([^\/]+)$/$1/; # remove path from name of program
130    print<<EOT;
131Usage:
132	$0 [-c] [-f <errorfile>] <programfile> [programargs]
133
134		-c	compile only, don't run (executes 'perl -wc')
135		-f	write errors to <errorfile>
136
137Examples:
138	* At the command line:
139		$0 program.pl
140		Displays output on STDOUT.
141
142		$0 -c -f errorfile program.pl
143		Then run 'vim -q errorfile' to edit the errors with Vim.
144
145	* In Vim:
146		Edit in Vim (and save, if you don't have autowrite on), then
147		type ':mak' or ':mak args' (args being the program arguments)
148		to error check.
149EOT
150
151    exit 0;
152
153};
154