92 lines
2.0 KiB
Plaintext
92 lines
2.0 KiB
Plaintext
|
#!/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|\.z[io]$||;
|
||
|
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);
|
||
|
if ($target_name =~ m/(.*)\.cmo$/ && -r ($source_name . "i")) {
|
||
|
push(@deps, "$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$/.cmi/;
|
||
|
push(@deps, $dep);
|
||
|
}
|
||
|
elsif ($dep = do find_path ("$modl.ml")) {
|
||
|
$dep =~ s/\.ml$/.cmo/;
|
||
|
push(@deps, $dep);
|
||
|
}
|
||
|
}
|
||
|
if ($#deps >= 0) {
|
||
|
print "$target_name: ";
|
||
|
$col = length($target_name) + 2;
|
||
|
foreach $dep (@deps) {
|
||
|
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;
|
||
|
}
|