2007-08-29 18:23:50 +02:00
|
|
|
/* @(#) Guess a value for install prefix. Pass in argv[0] (or NULL) as a clue,
|
|
|
|
* @(#) plus the name of the controlling environment variable (eg. VIPSHOME).
|
|
|
|
* @(#)
|
|
|
|
* @(#) const char *
|
|
|
|
* @(#) im_guess_prefix( const char *argv0, const char *env_name )
|
|
|
|
* @(#)
|
|
|
|
* @(#) Don't free the string you get back (treat as result of g_getenv()).
|
|
|
|
* @(#) The function returns NULL on error.
|
|
|
|
*
|
|
|
|
* Written on: 5/2/01
|
|
|
|
* Modified on:
|
|
|
|
* 3/3/01 JC
|
|
|
|
* - better behaviour for relative paths in argv0
|
|
|
|
* 22/9/01 JC
|
|
|
|
* - oops, SEGV in some cases for argv0 contains relative path
|
|
|
|
* 26/9/01 JC
|
|
|
|
* - reworked for new prefix scheme
|
|
|
|
* 9/11/01 JC
|
|
|
|
* - grr! added strdup() on putenv() for newer linuxes
|
|
|
|
* 14/12/01 JC
|
|
|
|
* - now uses realpath() for better relative pathname guessing
|
|
|
|
* 21/10/02 JC
|
|
|
|
* - turn off realpath() if not available
|
|
|
|
* - path_is_absolute() from glib
|
|
|
|
* - append ".exe" to name on w32
|
|
|
|
* - prefix cwd() to path on w32
|
|
|
|
* 31/7/03 JC
|
|
|
|
* - better relative path handling
|
|
|
|
* 23/12/04
|
|
|
|
* - use g_setenv()/g_getenv()
|
|
|
|
* 29/4/05
|
|
|
|
* - gah, back to plain setenv() so we work with glib-2.2
|
|
|
|
* 5/10/05
|
|
|
|
* - phew, now we can use g_setenv() again
|
|
|
|
* 18/8/06
|
|
|
|
* - use IM_EXEEXT
|
|
|
|
* 6/2/07 CB
|
|
|
|
* - move trailing '\0' too in extract_prefix
|
|
|
|
* 21/7/07
|
|
|
|
* - fall back to configure-time prefix rather than returning an error
|
|
|
|
* (thanks Jay)
|
2008-08-05 17:46:16 +02:00
|
|
|
* 5/8/08
|
|
|
|
* - added im_guess_libdir()
|
2007-08-29 18:23:50 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
This file is part of VIPS.
|
|
|
|
|
|
|
|
VIPS is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
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 Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
#define DEBUG
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif /*HAVE_CONFIG_H*/
|
|
|
|
#include <vips/intl.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#ifdef HAVE_SYS_PARAM_H
|
|
|
|
#include <sys/param.h>
|
|
|
|
#endif /*HAVE_SYS_PARAM_H*/
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif /*HAVE_UNISTD_H*/
|
|
|
|
#ifdef HAVE_DIRECT_H
|
|
|
|
#include <direct.h>
|
|
|
|
#endif /*HAVE_DIRECT_H*/
|
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include <vips/vips.h>
|
|
|
|
|
|
|
|
#ifdef WITH_DMALLOC
|
|
|
|
#include <dmalloc.h>
|
|
|
|
#endif /*WITH_DMALLOC*/
|
|
|
|
|
|
|
|
/* Strip off any of a set of old suffixes (eg. [".v", ".jpg"]), add a single
|
|
|
|
* new suffix (eg. ".tif").
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
im__change_suffix( const char *name, char *out, int mx,
|
|
|
|
const char *new, const char **olds, int nolds )
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
int i;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
/* Copy start string.
|
|
|
|
*/
|
|
|
|
im_strncpy( out, name, mx );
|
|
|
|
|
|
|
|
/* Drop all matching suffixes.
|
|
|
|
*/
|
|
|
|
while( (p = strrchr( out, '.' )) ) {
|
|
|
|
/* Found suffix - test against list of alternatives. Ignore
|
|
|
|
* case.
|
|
|
|
*/
|
|
|
|
for( i = 0; i < nolds; i++ )
|
|
|
|
if( g_ascii_strcasecmp( p, olds[i] ) == 0 ) {
|
|
|
|
*p = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Found match? If not, break from loop.
|
|
|
|
*/
|
|
|
|
if( *p )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add new suffix.
|
|
|
|
*/
|
|
|
|
len = strlen( out );
|
|
|
|
im_strncpy( out + len, new, mx - len );
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
get_current_dir( void )
|
|
|
|
{
|
|
|
|
static char buffer[PATH_MAX];
|
|
|
|
char *dir;
|
|
|
|
|
|
|
|
/* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
|
|
|
|
* and, if that wasn't bad enough, hangs in doing so.
|
|
|
|
*/
|
|
|
|
#if defined( sun ) && !defined( __SVR4 )
|
|
|
|
dir = getwd( buffer );
|
|
|
|
#else /* !sun */
|
|
|
|
dir = getcwd( buffer, PATH_MAX );
|
|
|
|
#endif /* !sun */
|
|
|
|
|
|
|
|
if( !dir ) {
|
|
|
|
buffer[0] = G_DIR_SEPARATOR;
|
|
|
|
buffer[1] = '\0';
|
|
|
|
dir = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
return( dir );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the prefix part of a dir ... name is the name of this prog from argv0.
|
|
|
|
*
|
|
|
|
* dir name guess prefix
|
|
|
|
*
|
|
|
|
* /home/john/vips-7.6.4/bin/vips-7.6 vips-7.6 /home/john/vips-7.6.4
|
|
|
|
* /usr/local/bin/ip ip /usr/local
|
|
|
|
*
|
|
|
|
* all other forms ... return NULL.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
extract_prefix( const char *dir, const char *name )
|
|
|
|
{
|
|
|
|
char edir[PATH_MAX];
|
|
|
|
char vname[PATH_MAX];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "extract_prefix: trying for dir = \"%s\", name = \"%s\"\n",
|
|
|
|
dir, name );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
/* Is dir relative? Prefix with cwd.
|
|
|
|
*/
|
|
|
|
if( !g_path_is_absolute( dir ) ) {
|
|
|
|
im_snprintf( edir, PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s",
|
|
|
|
get_current_dir(), dir );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
im_strncpy( edir, dir, PATH_MAX );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Chop off the trailing prog name, plus the trailing
|
|
|
|
* G_DIR_SEPARATOR_S.
|
|
|
|
*/
|
|
|
|
if( !im_ispostfix( edir, name ) )
|
|
|
|
return( NULL );
|
|
|
|
im_strncpy( vname, edir, PATH_MAX );
|
|
|
|
vname[strlen( edir ) - strlen( name ) - 1] = '\0';
|
|
|
|
|
|
|
|
/* Remove any "/./", any trailing "/.", any trailing "/".
|
|
|
|
*/
|
|
|
|
for( i = 0; i < (int) strlen( vname ); i++ )
|
|
|
|
if( im_isprefix( G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S,
|
|
|
|
vname + i ) )
|
|
|
|
memcpy( vname + i, vname + i + 2,
|
|
|
|
strlen( vname + i + 2 ) + 1 );
|
|
|
|
if( im_ispostfix( vname, G_DIR_SEPARATOR_S "." ) )
|
|
|
|
vname[strlen( vname ) - 2] = '\0';
|
|
|
|
if( im_ispostfix( vname, G_DIR_SEPARATOR_S ) )
|
|
|
|
vname[strlen( vname ) - 1] = '\0';
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "extract_prefix: canonicalised path = \"%s\"\n", vname );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
/* Ought to be a "/bin" at the end now.
|
|
|
|
*/
|
|
|
|
if( !im_ispostfix( vname, G_DIR_SEPARATOR_S "bin" ) )
|
|
|
|
return( NULL );
|
|
|
|
vname[strlen( vname ) - strlen( G_DIR_SEPARATOR_S "bin" )] = '\0';
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "extract_prefix: found \"%s\"\n", vname );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
return( im_strdup( NULL, vname ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Search a path for a file ... we overwrite the PATH string passed in.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
scan_path( char *path, const char *name )
|
|
|
|
{
|
|
|
|
char *p, *q;
|
|
|
|
char *prefix;
|
|
|
|
|
|
|
|
for( p = path;
|
|
|
|
(q = im_break_token( p, G_SEARCHPATH_SEPARATOR_S )); p = q ) {
|
|
|
|
char str[PATH_MAX];
|
|
|
|
|
|
|
|
/* Form complete path.
|
|
|
|
*/
|
|
|
|
im_snprintf( str, PATH_MAX,
|
|
|
|
"%s" G_DIR_SEPARATOR_S "%s", p, name );
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "scan_path: looking in \"%s\" for \"%s\"\n",
|
|
|
|
p, name );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
if( im_existsf( "%s", str ) &&
|
|
|
|
(prefix = extract_prefix( str, name )) ) {
|
|
|
|
return( prefix );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return( NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Look for a file along PATH. If we find it, look for an enclosing prefix.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
find_file( const char *name )
|
|
|
|
{
|
|
|
|
const char *path = g_getenv( "PATH" );
|
|
|
|
char *prefix;
|
|
|
|
char full_path[PATH_MAX];
|
|
|
|
|
|
|
|
if( !path )
|
|
|
|
return( NULL );
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: g_getenv( \"PATH\" ) == \"%s\"\n", path );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
#ifdef OS_WIN32
|
|
|
|
/* Windows always searches '.' first, so prepend cwd to path.
|
|
|
|
*/
|
|
|
|
im_snprintf( full_path, PATH_MAX, "%s" G_SEARCHPATH_SEPARATOR_S "%s",
|
|
|
|
get_current_dir(), path );
|
|
|
|
#else /*!OS_WIN32*/
|
|
|
|
im_strncpy( full_path, path, PATH_MAX );
|
|
|
|
#endif /*OS_WIN32*/
|
|
|
|
|
|
|
|
if( (prefix = scan_path( full_path, name )) )
|
|
|
|
return( prefix );
|
|
|
|
|
|
|
|
return( NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Guess a value for the install PREFIX.
|
|
|
|
*/
|
|
|
|
static const char *
|
|
|
|
guess_prefix( const char *argv0, const char *name )
|
|
|
|
{
|
|
|
|
char *prefix;
|
|
|
|
|
|
|
|
/* Try to guess from argv0.
|
|
|
|
*/
|
|
|
|
if( argv0 ) {
|
|
|
|
if( g_path_is_absolute( argv0 ) ) {
|
|
|
|
/* Must point to our executable.
|
|
|
|
*/
|
|
|
|
if( (prefix = extract_prefix( argv0, name )) ) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: found \"%s\" from "
|
|
|
|
"argv0\n", prefix );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
return( prefix );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Look along path for name.
|
|
|
|
*/
|
|
|
|
if( (prefix = find_file( name )) ) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: found \"%s\" from "
|
|
|
|
"PATH\n", prefix );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
return( prefix );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_REALPATH
|
|
|
|
/* Try to guess from cwd. Only if this is a relative path, though. No
|
|
|
|
* realpath on winders, but fortunately it seems to always generate
|
|
|
|
* a full path in argv[0].
|
|
|
|
*/
|
|
|
|
if( !g_path_is_absolute( argv0 ) ) {
|
|
|
|
char full_path[PATH_MAX];
|
|
|
|
char resolved[PATH_MAX];
|
|
|
|
|
|
|
|
im_snprintf( full_path, PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s",
|
|
|
|
get_current_dir(), argv0 );
|
|
|
|
|
|
|
|
if( realpath( full_path, resolved ) ) {
|
|
|
|
if( (prefix = extract_prefix( resolved, name )) ) {
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: found \"%s\" "
|
|
|
|
"from cwd\n", prefix );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
return( prefix );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /*HAVE_REALPATH*/
|
|
|
|
|
|
|
|
/* Fall back to the configure-time prefix.
|
|
|
|
*/
|
|
|
|
return( IM_PREFIX );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Guess a value for the install PREFIX.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
im_guess_prefix( const char *argv0, const char *env_name )
|
|
|
|
{
|
|
|
|
const char *prefix;
|
|
|
|
const char *p;
|
|
|
|
char name[PATH_MAX];
|
|
|
|
|
|
|
|
/* Already set?
|
|
|
|
*/
|
|
|
|
if( (prefix = g_getenv( env_name )) ) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: found \"%s\" in environment\n",
|
|
|
|
prefix );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
return( prefix );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the program name from argv0.
|
|
|
|
*/
|
|
|
|
p = im_skip_dir( argv0 );
|
|
|
|
|
|
|
|
/* Add the exe suffix, if it's missing.
|
|
|
|
*/
|
|
|
|
if( strlen( IM_EXEEXT ) > 0 ) {
|
|
|
|
const char *olds[] = { IM_EXEEXT };
|
|
|
|
|
|
|
|
im__change_suffix( p, name, PATH_MAX, IM_EXEEXT, olds, 1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
im_strncpy( name, p, PATH_MAX );
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_prefix: argv0 = %s\n", argv0 );
|
|
|
|
printf( "im_guess_prefix: name = %s\n", name );
|
|
|
|
printf( "im_guess_prefix: cwd = %s\n", get_current_dir() );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
prefix = guess_prefix( argv0, name );
|
|
|
|
g_setenv( env_name, prefix, TRUE );
|
|
|
|
|
|
|
|
return( prefix );
|
|
|
|
}
|
2008-08-05 17:46:16 +02:00
|
|
|
|
|
|
|
const char *
|
|
|
|
im_guess_libdir( const char *argv0, const char *env_name )
|
|
|
|
{
|
|
|
|
const char *prefix = im_guess_prefix( argv0, env_name );
|
|
|
|
static char *libdir = NULL;
|
|
|
|
|
|
|
|
if( libdir )
|
|
|
|
return( libdir );
|
|
|
|
|
|
|
|
/* Have we been moved since configure? If not, use the configure-time
|
|
|
|
* libdir.
|
|
|
|
*/
|
|
|
|
if( strcmp( prefix, IM_PREFIX ) == 0 )
|
|
|
|
libdir = IM_LIBDIR;
|
|
|
|
else
|
|
|
|
libdir = g_strdup_printf( "%s/lib", prefix );
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf( "im_guess_libdir: IM_PREFIX = %s\n", IM_PREFIX );
|
|
|
|
printf( "im_guess_libdir: IM_LIBDIR = %s\n", IM_LIBDIR );
|
|
|
|
printf( "im_guess_libdir: prefix = %s\n", prefix );
|
|
|
|
printf( "im_guess_libdir: libdir = %s\n", libdir );
|
|
|
|
#endif /*DEBUG*/
|
|
|
|
|
|
|
|
return( libdir );
|
|
|
|
}
|
|
|
|
|