108 lines
2.3 KiB
Perl
Executable File
108 lines
2.3 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
|
|
# To scan a Caml Light source file, find all references to external modules
|
|
# (open Foo or Foo.bar), and output the dependencies on standard output.
|
|
#
|
|
# Usage: camldep [-I path] <file> ...
|
|
|
|
while ($#ARGV >= 0) {
|
|
$_ = shift(@ARGV);
|
|
if (/^-I(.*)$/) {
|
|
$dir = $1 ? $1 : shift(@ARGV);
|
|
$dir =~ s|/$||;
|
|
unshift(@path, $dir);
|
|
}
|
|
elsif (/(.*)\.mli$/ || /(.*)\.cmi$/) {
|
|
do scan_source ($_, "$1.cmi");
|
|
}
|
|
elsif (/(.*)\.ml$/ || /(.*)\.cmo$/) {
|
|
do scan_source ($_, "$1.cmo");
|
|
}
|
|
else {
|
|
die "Don't know what to do with $_";
|
|
}
|
|
}
|
|
|
|
sub scan_source {
|
|
local ($source_name, $target_name) = @_;
|
|
$modname = $target_name;
|
|
$modname =~ s|^.*/||;
|
|
$modname =~ s|\.cm[iox]$||;
|
|
undef(%imports);
|
|
open(SRC, $source_name) || return;
|
|
while(<SRC>) {
|
|
if (m/\bopen\s*([A-Z][a-zA-Z0-9_]*)\b/) {
|
|
$imports{$1} = 1;
|
|
}
|
|
while(m/\b([A-Z][a-zA-Z0-9_]*)\./) {
|
|
$imports{$1} = 1;
|
|
$_ = $';
|
|
}
|
|
}
|
|
close(SRC);
|
|
undef(@deps);
|
|
undef(@optdeps);
|
|
if ($target_name =~ m/(.*)\.cmo$/ && -r ($source_name . "i")) {
|
|
push(@deps, "$1.cmi");
|
|
push(@optdeps, "$1.cmi");
|
|
}
|
|
foreach $modl (keys(%imports)) {
|
|
$modl = do lowercase($modl);
|
|
next if ($modl eq $modname);
|
|
if ($dep = do find_path ("$modl.mli")) {
|
|
$dep =~ s/\.mli$//;
|
|
push(@deps, "$dep.cmi");
|
|
if (-f "$dep.ml") {
|
|
push(@optdeps, "$dep.cmx");
|
|
} else {
|
|
push(@optdeps, "$dep.cmi");
|
|
}
|
|
}
|
|
elsif ($dep = do find_path ("$modl.ml")) {
|
|
$dep =~ s/\.ml$//;
|
|
push(@deps, "$dep.cmo");
|
|
push(@optdeps, "$dep.cmx");
|
|
}
|
|
}
|
|
if ($#deps >= 0) {
|
|
print "$target_name: ";
|
|
do print_deps(@deps);
|
|
}
|
|
if ($target_name =~ /^(.*)\.cmo$/ && $#optdeps >= 0) {
|
|
print "$1.cmx: ";
|
|
do print_deps(@optdeps);
|
|
}
|
|
}
|
|
|
|
sub print_deps {
|
|
$col = length($target_name) + 3;
|
|
foreach $dep (@_) {
|
|
next if $dep eq $target_name;
|
|
$col += length($dep) + 1;
|
|
if ($col >= 77) {
|
|
print "\\\n ";
|
|
$col = length($dep) + 5;
|
|
}
|
|
print $dep, " ";
|
|
}
|
|
print "\n";
|
|
}
|
|
|
|
sub find_path {
|
|
local ($filename) = @_;
|
|
return $filename if (-r $filename);
|
|
foreach $dir (@path) {
|
|
return "$dir/$filename" if (-r "$dir/$filename");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub lowercase {
|
|
local ($_) = @_;
|
|
m/^(.)(.*)$/;
|
|
$hd = $1;
|
|
$tl = $2;
|
|
$hd =~ tr/A-Z/a-z/;
|
|
return $hd . $tl;
|
|
}
|