#!/usr/bin/perl -w

use strict;
use English;

my $progname = $PROGRAM_NAME;
$progname =~ s,.*/,,;

### Subroutinen ###

sub get_libdirs {
  if ($OSNAME =~ /linux/) {
    if (open LDCONFIG, '/sbin/ldconfig -Nv|') {
      my @libdirs = ();
      while (<LDCONFIG>) {
        push (@libdirs, $1) if m/^(\/.*):$/;
      }
      close LDCONFIG;
      return @libdirs;
    }
  } elsif ($OSNAME =~ /freebsd/) {
    if (open LDCONFIG, '/sbin/ldconfig -r|') {
      while (<LDCONFIG>) {
        if (/search directories: (.*)/) {
          close LDCONFIG;
          return split ':', $1;
        }
      }
      close LDCONFIG;
    }
  }
  return ('/usr/lib',
          '/usr/local/lib',
          '/usr/X11R6/lib');
}

sub get_libs {
  my @libs = ();
  foreach my $libdir (get_libdirs) {
    if (opendir LIBDIR, $libdir) {
      foreach (grep /lib.+\.a$/, readdir LIBDIR) {
        push @libs, $libdir . '/' . $ARG;
      }
      closedir LIBDIR;
    } else {
      print STDERR "$progname: Warnung: " .
        "opendir `$libdir': $OS_ERROR\n";
    }
  }
  return @libs;
}

### Hauptprogramm ###

my $nm_cmd = 'nm -AP --defined-only --no-sort ' .
        join (' ', get_libs);

foreach my $symbol (@ARGV) {
  if (open NM, "$nm_cmd |") {
    while (<NM>) {
      next unless m{
        ^         # Anker am Zeilenanfang.
        (.*)\/lib # Alles vor /lib ist $1.
        (.*)\.a   # Alles bis zum .a ist $2.
        \[        # Gefolgt von [.
        \S+\s     # >=1 nicht-Leerz. + ein Leerz.
        _?$symbol # $symbol optional ein _ davor.
        \s+       # Ein oder mehrere Leerzeichen.
        [A-Z]     # Ein Großbuchstabe.
      }x;
      print "$symbol ist in $1/lib$2.a enthalten\n";
      print "Linken mit -L$1 -l$2\n";
    }
    close NM;
  } else {
    print STDERR "$progname: Warnung: " .
      "konnte nm nicht starten: $OS_ERROR\n";
  }
}