blob: eda5dd535fd51dd3506fc1c03530f025d080ec50 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/usr/bin/perl
# Given a filename on the command line or on stdin this script returns
# the (single) interpreter that is required to run the executable. We
# need this information to pick the best dependency parser for this
# file.
# Usually this is extracted from the #! line of the file
# but we also handle the various 'exec' tricks that people use to
# start the interpreter via an intermediate shell.
# These have all been seen on our system or are "recommended" in
# various man pages.
# Examples:
# #!/bin/sh
# # the next line restarts using wish \
# exec wish "$0" "$@"
# #!/bin/sh -- # -*- perl -*- -p
# eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
# if $running_under_some_shell;
# #!/bin/sh -- # -*- perl -*- -p
# eval '(exit $?0)' && eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
# #!/bin/sh -- # -*- perl -*- -p
# & eval 'exec /usr/bin/perl -wS $0 $argv:q'
# if $running_under_some_shell;
# #! /usr/bin/env python
use File::Basename;
if ("@ARGV") {
foreach (@ARGV) {
process_file($_);
}
} else {
# notice we are passed a list of filenames NOT as common in unix the
# contents of the file.
foreach (<>) {
process_file($_);
}
}
foreach $prog (sort keys %require) {
$prog=basename($prog);
# ignore variable interpolation and any program whose name is made
# up only of non word characters ('<', '&&', etc).
( ( $prog != /\$/ ) || ( $prog =~ /^\W+$/ ) ) &&
next;
print "exectuable($prog)\n";
}
exit 0;
sub process_file {
my ($file) = @_;
chomp $file;
my ($version, $magic) = ();
(-f $file) || return ;
open(FILE, "<$file")||
die("$0: Could not open file: '$file' : $!\n");
my $rc = sysread(FILE,$line,1000);
$rc =~ s/\#.*\n//g;
# Ignore all parameter substitution.
# I have no hope of parsing something like:
# exec ${SHELL:-/bin/sh}
$rc =~ s/\$\{.*\}//g;
$rc =~ s/echo\s+.*[\n;]//g;
if ( ($rc > 1) && ($line =~ m/^\#\!\s*/) ) {
if ($line =~ m/\b(exec|env)\s+([\'\"\`\\]+)?([^ \t\n\r]+)/) {
$require{$3} = 1;
last;
}
# strip off extra lines and any arguments
if ($line =~ m/^\#\!\s*([^ \t\n\r]+)/) {
$require{$1} = 1;
last;
}
}
close(FILE) ||
die("$0: Could not close file: '$file' : $!\n");
return ;
}
|