diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb
index 2ff8d9fb..eb39a925 100644
--- a/lib/linguist/heuristics.rb
+++ b/lib/linguist/heuristics.rb
@@ -33,7 +33,7 @@ module Linguist
# disambiguate "Perl", "Prolog" do |data|
# if data.include?("use strict")
# Language["Perl"]
- # elsif data.include?(":-")
+ # elsif /^[^#]+:-/.match(data)
# Language["Prolog"]
# end
# end
@@ -94,13 +94,13 @@ module Linguist
Language["Perl6"]
elsif data.match(/use strict|use\s+v?5\./)
Language["Perl"]
- elsif data.include?(":-")
+ elsif /^[^#]+:-/.match(data)
Language["Prolog"]
end
end
disambiguate "ECL", "Prolog" do |data|
- if data.include?(":-")
+ if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?(":=")
Language["ECL"]
@@ -108,7 +108,7 @@ module Linguist
end
disambiguate "IDL", "Prolog", "INI", "QMake" do |data|
- if data.include?(":-")
+ if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?("last_client=")
Language["INI"]
diff --git a/samples/Perl/exception_handler.pl b/samples/Perl/exception_handler.pl
new file mode 100644
index 00000000..14807ced
--- /dev/null
+++ b/samples/Perl/exception_handler.pl
@@ -0,0 +1,117 @@
+package exception_handler;
+use sigtrap qw(die normal-signals);
+use IO::Handle;
+use Carp;
+use File::Spec;
+use File::Basename;
+use Data::Dumper;
+
+use sigtrap 'handler', \&tm_die;
+
+$Carp::CarpLevel = 1; # How many extra package levels to skip on carp.
+
+BEGIN {
+ *CORE::GLOBAL::die = \&tm_die;
+ $main::SIG{__DIE__} = \&tm_die;
+ my $error_fd = $ENV{"TM_ERROR_FD"};
+ open (TM_ERROR_FD, ">&=$error_fd");
+ TM_ERROR_FD->autoflush(1);
+}
+
+sub realwarn { CORE::warn(@_); }
+sub realdie { CORE::die(@_); }
+
+sub longmess {
+ my ($arg, @rest) = shift;
+ {
+ local $@;
+ # XXX fix require to not clear $@?
+ # don't use require unless we need to (for Safe compartments)
+ require Carp::Heavy unless $INC{"Carp/Heavy.pm"};
+ }
+ # Icky backwards compatibility wrapper. :-(
+ my $call_pack = caller();
+ if ($Internal{$call_pack} or $Carp::CarpInternal{$call_pack}) {
+ return longmess_heavy($arg, @rest);
+ }
+ else {
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
+ return longmess_heavy($arg, @rest);
+ }
+}
+
+sub longmess_heavy {
+ return @_ if ref($_[0]); # don't break references as exceptions
+ my $i = Carp::long_error_loc();
+ my ($arg, @rest) = @_;
+ return ret_backtrace($i, $arg, @rest);
+}
+
+sub quote {
+ my $str = shift;
+ $str =~ s/([^A-Za-z0-9\/_.-])/sprintf("%%%02X", ord($1))/seg;
+ return $str;
+}
+
+sub url_and_display_name {
+ my $file = shift;
+ my $url = "";
+ my $display_name = "";
+ $display_name = basename($file);
+ $url = 'url=file://' . quote($file);
+ return ($url, $display_name);
+}
+
+# Returns a full stack backtrace starting from where it is
+# told.
+sub ret_backtrace {
+ my ($i, $arg, @rest) = @_;
+ my $mess;
+ $i++;
+
+ my $tid_msg = '';
+ if (defined &Thread::tid) {
+ my $tid = Thread->self->tid;
+ $tid_msg = " thread $tid" if $tid;
+ }
+
+ my %i = Carp::caller_info($i);
+ $arg =~ s/\n/\
/g;
+ $i{sub} =~ s/tm_die/die/g;
+ $mess .= "
$arg
\n"; + $mess .= "\n"; + my ($url, $display_name) = url_and_display_name($i{file}); + $mess .= "
\n"; + while (my %i = Carp::caller_info(++$i)) { + ($url, $display_name) = url_and_display_name($i{file}); + $mess .= " $i{sub} in $display_name at line $i{line}$tid_msg \n"; + } + $mess .= " $i{sub} in $display_name at line $i{line}$tid_msg