#!/usr/bin/perl -w
# project_bin - Run a program in the project bin directory
# See copyright, etc in below POD section.
######################################################################

use Pod::Usage;

use Dir::Project;
use strict;
use vars qw ($Debug $VERSION);

######################################################################
# configuration

$VERSION = '3.012';

######################################################################
# main

my @params = ();
# read command line
while(defined($_ = shift)) {
    if (/^--?project_bin-debug/) {
	debug(9);
    }
    elsif (/^--?project_bin-help/) {
	usage();
    }
    elsif (/^--?project_bin-version/) {
	print "Version $VERSION\n";
    }
    elsif (/^--?debug/) {
	# Turn on our debug and pass to application too
	debug();
	push @params, $_;
    }
    else {
	push @params, $_;
    }
}

$ENV{DIRPROJECT_PREFIX} or die "%Error: project_bin: DIRPROJECT_PREFIX not in environment\n";
$ENV{DIRPROJECT_PATH}   or die "%Error: project_bin: DIRPROJECT_PATH not in environment\n";

my $program = $0;
$program =~ s/^.*[\\\/]//g;  # Strip path

if ($program eq "project_bin") {
    print STDERR "%Error: project_bin should be symlinked to a program name, not called directly\n";
    die "%Error: Bad usage, try 'project_bin --project_bin-help'\n";
}

Dir::Project::get_set_all();
my @paths = Dir::Project::program_paths(program=>$program);
my $program_wdir = Dir::Project::program_bin(paths=>\@paths);

if (!defined $program_wdir) {
    if (!defined $Project) {
	# If there's no default program, we MUST have a project link!
	print STDERR "project_bin: %Error: Can't determine DIRPROJECT\n";
	print STDERR "\tPerhaps you intended to be inside a checkout,\n\tor in a directory with project link?\n";
	exit (10);
    }
    else {
	print STDERR "%Error: Can't find \"".join(':',@paths),"\": No such file\n";
	print STDERR "(Accessed via project_bin with \$DIRPROJECT='$Project')\n";
	exit (10);
    } # else already found
}

print "project_bin: exec $program_wdir\n" if $Debug;
$ENV{DIRPROJECT_EXE} = $program_wdir;
exec $program_wdir, @params;
# Above should never return, unless error

######################################################################

sub usage {
    print "Version $VERSION\n";
    pod2usage(-verbose=>2, -exitval => 2);
    exit (1);
}

sub debug {
    my $level = shift || 1;
    $Debug = $level;
    $Dir::Project::Debug = $level;
    $ENV{DIRPROJECT_DEBUG} = $level;
    print "project_bin: $0 ", join(' ',@ARGV), "\n";
}

sub parameter {
    my $param = shift;
    push @params, $param;
}

######################################################################
######################################################################
######################################################################

__END__

=pod

=head1 NAME

project_bin - Call a Dir::Project specific program

=head1 SYNOPSIS

    [program] [program_arguments]
    [program] --project_bin-help

=head1 DESCRIPTION

L<project_bin> is used to call another project specific program under the
current project as determined with L<project_dir>.

This program is not usually called directly.  Instead project_bin is
symlinked as the name of the program to be executed.  project_bin then uses
that name to determine the program to be called.

This process enables multiple versions of a program to exist in different
project directories.  The global path only contains a simple non-changing
symlink which everyone can share.

=head1 EXAMPLE

Assume C<prog> is to be executed.  The shell uses the standard PATH
environment variable and finds C<prog> under $DIRPROJECT_PREFIX/bin/prog.
$DIRPROJECT_PREFIX/bin/prog is installed as a simple symlink to
L<project_bin>.  Thus the shell executes project_bin.

Project_bin then determines the current project and sets the DIRPROJECT
environment variable, which has the link to the current project area.  See
L<Dir::Project> program_bin() for more details.

Project_bin then uses the DIRPROJECT directory in combination with the
DIRPROJECT_PATH to search for C<prog>, the name project_bin was invoked
under.  C<prog> is then executed with all of the arguments passed through
project_bin.

If project_bin couldn't determine the project or find the binary using
DIRPROJECT_PATH, it tries to execute
$DIRPROJECT_PREFIX/bin/C<prog>__notfound which is generally a link to a
version of C<prog> that is the default for when outside a project.

=head1 ARGUMENTS

=over 4

=item --debug

The debug flag is passed to the application, and also enables debugging
messages from project_bin itself.

=item --project_bin-debug

Strip this flag before passing to the application, and enable debugging.

=item --project_bin-help

Show this help message and exit.

=item I<...>

All other arguments are passed through to the application.

=back

=head1 ENVIRONMENT

See L<Dir::Project> for the list of relevant environment variables.

=head1 DISTRIBUTION

Dir-Project is part of the L<http://www.veripool.org/> free EDA software
tool suite.  The latest version is available from CPAN and from
L<http://www.veripool.org/>.

Copyright 2001-2008 by Wilson Snyder.  This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License or the Perl Artistic License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

=head1 AUTHORS

Wilson Snyder <wsnyder@wsnyder.org>

=head1 SEE ALSO

L<Dir::Project>, L<project_dir>

=cut

######################################################################
