# @(#)$Id: Configure.pm,v 2011.2 2012/05/19 19:09:24 jleffler Exp $
#
# Informix ESQL/C Support Routines for DBD::Informix
# (Informix Database Driver for Perl DBI Version 2013.0521 (2013-05-21))
#
# Copyright 1999 Jonathan Leffler
# Copyright 2000 Informix Software Inc
# Copyright 2002 IBM
# Copyright 2003-2012 Jonathan Leffler
#
# You may distribute under the terms of either the GNU General Public
# License or the Artistic License, as specified in the Perl README file.
#TABSTOP=4
# This file defines the following subs, which are used by both
# Makefile.PL and BugReport.
# -- find_informixdir_and_esql
# -- get_esqlc_version
# -- map_informix_lib_names
{
package DBD::Informix::Configure;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(find_informixdir_and_esql get_esqlc_version map_informix_lib_names);
$VERSION = "2013.0521";
$VERSION = "0.97002" if ($VERSION =~ m%[:]VERSION[:]%);
use strict;
use Config;
use DBI;
# Locate $INFORMIXDIR and the ESQL/C compiler
sub find_informixdir_and_esql
{
my ($NTConfiguration) = @_;
my ($esql, $ID);
if ($NTConfiguration)
{
# NT configuration
# Tested for Config: archname='MSWin32' osname='MSWin32' osvers='4.0'
my ($p);
# Trying to find ESQL (and determining INFORMIXDIR too)
foreach $p (split( /;/, $ENV{PATH}))
{
if (-x "$p/ESQL.EXE")
{
# HUMS: \\ needed, because string goes into Makefile (via postamble)
$esql = "$p\\ESQL.EXE";
# HUMS: \\ necessary because string comes from ENV
$p =~ s%[/\\]BIN%%i;
$ID = $p;
last;
}
}
&did_not_read('No executable ESQL/C compiler found in $PATH')
unless defined $esql;
if ($esql =~ /\s/o)
{
warn "Path to ESQL/C compiler ($esql) contains white space";
if (defined($ENV{INFORMIXDIR}))
{
$ID = $ENV{INFORMIXDIR};
die 'Value of %INFORMIXDIR% ', "($ID) also contains spaces"
if ($ID =~ /\s/o);
my $p = "$ID/BIN/";
if (-x "$p/ESQL.EXE")
{
warn 'Also found ESQL/C compiler via %INFORMIXDIR% - without spaces';
$esql = "$p\\ESQL.EXE";
}
}
}
}
else
{
# Unix configuration
$ID = $ENV{INFORMIXDIR};
&did_not_read('$INFORMIXDIR is not set') unless ($ID);
$esql = $ENV{ESQL};
$esql = "esql" unless $esql;
if ($esql =~ m%/%)
{
# ESQL/C program specified with path name
&did_not_read("No executable ESQL/C compiler $esql")
unless (-x $esql);
}
else
{
# ESQL/C program specified without any path name
&did_not_read("No executable ESQL/C compiler $ID/bin/$esql")
unless (-x "$ID/bin/$esql");
}
# Allow for $INFORMIXDIR = "/opt/informix/ids1170+csdk350".
# Without the \Q...\E notation, the metacharacter '+' is active.
# Reported by Julian Bridle <julian.bridle@pacepetroleum.com>
&did_not_read('$INFORMIXDIR/bin is not in $PATH')
unless ($ENV{PATH} =~ m%:\Q$ID\E/bin:% ||
$ENV{PATH} =~ m%^\Q$ID\E/bin:% ||
$ENV{PATH} =~ m%:\Q$ID\E/bin$%);
}
print "Using INFORMIXDIR=$ID and ESQL/C compiler $esql\n";
return $ID, $esql;
}
# --- Find out which version of Informix ESQL/C by running 'esql -V'
# NB: Argument should be name of esql program which can be executed.
# The checks for Unix in find_informixdir_and_esql should be OK.
# Allow for version 10.00 and later -- still hypothetical but...
sub get_esqlc_version
{
my ($esql) = @_;
my ($infv, $vers);
open(ESQL, "$esql -V|") || die;
# Read all the input to avoid Broken Pipe messages, and to avoid
# problems with RedHat 9 wittering about the ESQL/C compiler being
# an "Incorrectly built binary which accesses errno, ...". Last
# version line wins! Jay Hannah <jhannah@omnihotels.com> gets the
# credit for reporting the RedHat 9 problem.
while (<ESQL>)
{
$infv = $_ if (m%Informix.* Version%i);
}
die "Failed to read any Informix version from 'esql -V'\n"
unless defined $infv;
close ESQL;
chomp($infv);
$infv =~ s/\s+$//; # Delete trailing white space
$infv =~ s/\s+/ /g; # Replace white space with single blanks
$vers = $infv;
# JL 2002-11-06:
# CSDK 2.70 and earlier produces:
# INFORMIX-ESQL Version 9.51.UC1
# CSDK 2.80 (and later) produces:
# IBM Informix CSDK Version 2.80, IBM Informix-ESQL Version 9.52.UC1
# I4GL produces (note the extra spaces between Version and the number):
# IBM INFORMIX-4GL Version 7.31.UC3
# (I4GL issue reported by Roderick Schertler <roderick@argon.com>
# on 1999-07-25). The s/// expression below picks up the I4GL or
# ESQL/C version correctly from all three formats, relying on
# case-insensitivity, the '-', and a string of alphanumerics to
# identify the correct codewords prior to Version. Fortunately,
# the ESQL/C support code treats I4GL 7.31 the same as ESQL/C 9.x.
$vers =~ s/.*INFORMIX-\w+ Version\s+(\d+[.]\d+).*/$1/i;
die "Unexpected message from esql script -- $infv\n"
unless ($vers =~ /^\d+[.]\d+$/);
$vers =~ s/^([0-9])\./$1/;
return $infv, $vers;
}
# If DBD_INFORMIX_RELOCATABLE_INFORMIXDIR is set, then leave Informix
# library file specifications alone. If it is not set, then hard-code the
# Informix library path names. This will simplify life on most platforms.
# It also, more or less, follows the ideas espoused in 'Why LD_LIBRARY_PATH
# is bad', by David Barr (http://www.visi.com/~barr/ldpath.html).
#
# This gets tricky. We need to remove any library path arguments which
# refer to $INFORMIXDIR, such as -L$INFORMIXDIR/lib, and map any references
# to -lixlib into $INFORMIXDIR/lib/libixlib.so (unless that's libixlib.sl,
# etc). Further, you can write -L $INFORMIXDIR/lib and -l ixlib, so we
# should be prepared to handle adjacent pairs of arguments on occasion.
# NB: this version does not support spaces between -[lL] and the argument.
# And heaven help us on systems where we are not using this script (eg
# AIX 4.2). Note, too, that this assumes you will use shared libraries
# if they exist. It needs to be rigged to avoid doing the mapping if
# shared libaries are not wanted at all.
sub map_informix_lib_names
{
my @i_libs = @_;
my @o_libs = ();
my $ixd = $ENV{INFORMIXDIR};
my @ixlibdirs = ();
foreach my $arg (@i_libs)
{
if ($arg =~ m%^-L$ixd/%o)
{
push @o_libs, $arg;
$arg =~ s%-L%%;
push @ixlibdirs, $arg;
}
elsif ($arg =~ m%^-l.+%o)
{
push @o_libs, &map_library($arg, @ixlibdirs);
}
else
{
push @o_libs, $arg;
}
}
@o_libs;
}
# Non-exported sub to map a single library name if found in one
# of the (Informix) library directories
sub map_library
{
my ($lib, @libdirs) = @_;
my $ar_ext = $Config{lib_ext}; # Regular, static libraries
my $dl_ext = ".$Config{dlext}"; # Shared, dynamic libraries
my $so_ext = ".$Config{so}"; # Shared, dynamic libraries
my $stub = $lib;
$stub =~ s/-l//;
$stub = "lib$stub";
foreach my $dir (@libdirs)
{
foreach my $ext ($so_ext, $dl_ext, $ar_ext)
{
my $path = "$dir/$stub$ext";
if (-f $path)
{
print "\t$0: map $lib to $path\n" if $ENV{DBD_INFORMIX_DEBUG_LIBMAP};
return $path;
}
}
}
return $lib;
}
# Tell the user that they did not read the README file and why
# we think they didn't read it.
sub did_not_read
{
die "\n*** You didn't read the README file!\n@_\n\n";
}
1;
}
__END__
=head1 NAME
DBD::Informix::Configure - Determining your ESQL/C Configuration
=head1 SYNOPSIS
use DBD::Informix::Configure;
=head1 DESCRIPTION
This module is used by Informix Database Driver for Perl DBI Version 2013.0521 (2013-05-21) in the build and bug reporting code.
You will seldom if ever have cause to use this module directly.
=head2 Using find_informixdir_and_esql
The function find_informixdir_and_esql returns both the value of
$INFORMIXDIR and the pathname of the ESQL/C compiler executable (a
script on Unix, an executable program on Windows NT).
The parameter should be true if the search is being done on Windows
NT; it is false if it is being done on a Unix system.
my ($ixd, $esql) = find_informix_dir_and_esql($nt);
=head2 Using get_esqlc_version
Given the pathname of the ESQL/C compiler, this function returns
the ESQL/C version number as a string (such as 9.21.UC1) and as a
pure integer (such as 921).
my ($infversion, $vernum) = &get_esqlc_version($esqlprog);
=head1 AUTHOR
Jonathan Leffler
=cut