#! perl -w

=head1 NAME

CFX5::DefaultConfig - Default settings for configuration records

=head1 SYNOPSIS

This module contains the default configuration for CFX-5.x, and should
not be edited by the user. (It should, however, be edited by
script-writers).

It includes some of the functionality of cfx5rc and some of cfx5setup;
see also ParseConfig.pm.

The configuration storage is accessed by functions getconf(string) and
setconf(string, value). There is no reason why this shouldn't be done
with a tied hash, I just happen to fancy doing it this way. '

COPYRIGHT ANSYS, ALL RIGHTS RESERVED

=cut

package CFX5::DefaultConfig;

use strict;

use vars qw($CVSVersion);
$CVSVersion='$Id$ ';

use CFX5::Output qw(:all);
use CFX5::PathManip qw(:all);
use CFX5::CurrentConfig qw(:std %Config query_conf);
use CFX5::Commands qw();
use CFX5::FileOps qw(find_executable);
use CFX5::PkgLoader qw(cfx5_require);
use CFX5::Attr;
use CFX5::Config::Component qw(:all);
use CFX5::Config::Environment qw(:all);
use CFX5::Config::Version qw(:all);


# this is only replaced in the header when we split
use vars qw($DefaultVersion);
$DefaultVersion="5";

{
  _trace("Initialising CFX5::DefaultConfig");

  # make functions for the following directory variables, which follow
  # a set pattern. This happens at compile time, and so when we're an
  # executable, it wastes no time.
  my $verb=(exists $ENV{CFX_OUTPUT} and $ENV{CFX_OUTPUT} =~ m/compileperl/);
  print STDERR "Creating directory name functions ...\n"
    if $verb;
  my %nd = (
	    CFX_DATA_DIR => 'etc',
	    CFX_CONFIG_DIR => 'config',
	    CFX_EG_DIR => 'examples',
	    CFX_EXTERNALS_DIR => 'externals',
	    CFX_ICON_DIR => 'icons',
	    CFX_INCLUDE_DIR => 'include',
	    CFX5_LIB_ROOT => 'lib',
	    );
  my $d;
  for $d (keys %nd) {
    eval "sub $d { return get_std_dir(\"$nd{$d}\"); };";
  }
  %nd = (
	 CFX5OBJDIR => 'obj',
	);
  for $d (keys %nd) {
    eval "sub $d { return get_std_arch_dir(\"$nd{$d}\"); };";
  }
}

=head2 %calcfunction

The C<%calcfunction> contains a list of variables which are calculated
by a non-default function, and the name of that function. It is
initialised in a BEGIN block, so hopefully the compiler will not have
to fill this in at runtime.

=cut

use vars qw(%calcfunction);
{
  # read this file, and look for 'scu' calls. Parse them to work out
  # which functions define which variables, and create the
  # calcfunction hash.
  #
  # this relies on the current behaviour of the split leaving the file
  # here, but after the __END__.
  my $myname="CFX5/DefaultConfig.pm";
  my $me=undef;
 ITER: {
    my $prefix;
    foreach $prefix (@INC) {
      my $realfilename = "$prefix/$myname";
      if (-f $realfilename) {
	$me = $realfilename;
	last ITER;
      }
    }
    die "Can't find $myname in \@INC";
  }

  my %invcf;

  open INPUT, $me or die "Cannot read $me";
  my $subname;
  while (<INPUT>) {
    if (m/^sub\s+([A-Za-z0-9_]+)\s/) {
      $subname=$1;
    } elsif (m{
	       ^		# beginning of the list
	       \s+		# followed by some whitespace
	       scu\s+		# the command "scu" and more whitespace
	       [\"\']		# open quotes
	       (		# save this in $1
		[^\"\']+	# the variable name
	       )
	       [\"\']		# close quotes
	      }x) {		# extend re over >1 line
      $calcfunction{$1}=$subname;
      #print STDERR "  $subname defines $1\n";
    }
  }
  close INPUT or die "Cannot stop reading myself";
}

=head2 getconf_or_*

  getconf_or_interr("RECORD")
  getconf_or_interr("RECORD","message");

  getconf_or_abort(...)

Use C<getconf> to find the value of configuration record I<RECORD>,
and check whether we managed to get one or not. If we failed, fall
over, either with an internal error or a standard abort.

If the message is not specified, the default is

  Unable to work out a value for RECORD

=cut

sub getconf_or_interr {
  # get the value of a configuration variable, or signal an internal
  # error if we can't.
  my $record=shift;
  my $val=getconf($record);
  return $val if defined $val;

  internal_error(scalar(@_)>0 ? @_ : "Unable to work out a value for $record");
}

sub getconf_or_abort {
  # get the value of a configuration variable, or abort if we can't.
  my $record=shift;
  my $val=getconf($record);
  return $val if defined $val;

  _abort(scalar(@_)>0 ? @_ : "Unable to work out a value for $record");
}

######################################################################
# Basic branding information
######################################################################

sub CFX_PRODUCT_NAME {
  my $basename=basename($Config{CFX5ROOT});
  if ($basename =~ m!turbogrid|tg!i) {
    return 'TurboGrid';
  } else {
    return 'CFX';
  }
}

sub CFX_PRODUCT_FULLNAME {
  if ($Config{CFX_PRODUCT_NAME} =~ m!^CFX-[0-9]*$!) {
    return "CFX $Config{CFXREVISION}";
  } elsif ($Config{CFX_PRODUCT_NAME} =~ m!-!) {
    return "$Config{CFX_PRODUCT_NAME} $Config{CFXREVISION}";
  } else {
    return "$Config{CFX_PRODUCT_NAME} $Config{CFXREVISION}";
  }
}

######################################################################
# Architecture strings of various sorts
######################################################################

sub CFX5OS {
  my $perlos=getconf_or_interr("perl_arch");
  # Treat windows differently
  # $Config{windows_64} will cause Win32API to be loaded
  # (or not found on unix).
  if($perlos=~/^MSWin32/){
    return $Config{windows_64} ? "winnt-amd64" : "winnt";
  } else {
    my %lu=(
	  'sun4-solaris' => 'solaris',
	  'sun4-solaris-64' => 'solaris',
	  'i86pc-solaris-64int' => 'solaris-amd64',
	  'i86pc-solaris' => 'solaris-amd64',
	  'irix'    => 'irix',
	  'IP30-irix'    => 'irix',
	  'IP30-irix-64'    => 'irix',
	  'dec_osf' => 'osf',
	  'alpha-dec_osf' => 'osf',
	  'aix'     => 'aix',
	  'aix-64all'  => 'aix',
          'hpux' => 'hpux',
          'PA-RISC1.1' => 'hpux',
	  'PA-RISC2.0-LP64'    => 'hpux',
	  'i686-linux'   => 'linux',
	  'ia64-linux'   => 'linux-ia64',
	  'x86_64-linux-thread-multi'   => 'linux-amd64',
	  'x86_64-linux'   => 'linux-amd64',
	  'x86_64-linux-ld'   => 'linux-amd64',
	  'IA64.ARCHREV_0-LP64' => 'hpux-ia64',
          'darwin-thread-multi-2level' => 'darwin',
          'ppc-linux-thread-multi' => 'linux-ppc64',
          'ppc64-linux' => 'linux-ppc64',
	  );
    #use Data::Dumper;
    #warn Dumper(\%lu, $perlos);

    if (exists $lu{$perlos}) {
      return $lu{$perlos};
    } else {
      internal_error("Unrecognised PERL OS string $perlos");
    }
  }
}

sub perl_arch {
  # $^O isn't enough to distinguish here
  require Config;
  return $Config::Config{archname};
}

sub windows_nt {
  my $os=$Config{"CFX5OS"};
  if($os eq "winnt" || $os eq "winnt-amd64") {
    return 1;
  } else {
    return 0;
  }
}

sub windows_64 {
 return $Config{perl_arch} =~ m/MSWin32-x64/;
}

sub windows_nt_version {
  # Return undefined if not Windows or registry access unavailable
  return undef unless ($Config{windows_nt});
  cfx5_require('CFX5::Win32::Registry') or return undef;

  # Use CurrentMajorVersionNumber/CurrentMinorVersionNumber if defined, otherwise use CurrentVersion
  my $version = CFX5::Win32::Registry::registry_get("Software/Microsoft/Windows NT/CurrentVersion/CurrentVersion");
  my $majorversion = CFX5::Win32::Registry::registry_get("Software/Microsoft/Windows NT/CurrentVersion/CurrentMajorVersionNumber");
  my $minorversion = CFX5::Win32::Registry::registry_get("Software/Microsoft/Windows NT/CurrentVersion/CurrentMinorVersionNumber");

  if (defined $majorversion and defined $minorversion) {
    $version = join '.', $majorversion, $minorversion;
  }

  # Return undefined if malformed (expect <majorversion>.<minorversion>)
  return undef unless ($version =~ m/\d+\.\d+/);

  return $version;
}

sub CFX5_HOST_ARCH {
  # on NT, don't bother with the cfx5arch script, and do it ourselves.
  if ($Config{"windows_nt"}) {
    # Always use the 32bit version on windows
    # x86info uses inline assembly
    my $execdir=getconf_or_interr('CFX5BINDIR');
    my $cmd=join_file($execdir, 'winnt', 'x86info.exe');
    my $cpu=CFX5::Commands::get_cmd_output($cmd) || '';
    # remove any whitespace (including newlines)
    $cpu=~s/\s*$//;
    # default, just in case (Pentium 5 anybody?)
    if ($cpu eq '') {
      require Config;
      my $os=$Config::Config{archname};
      if($os=~m/MSWin32-x86/){
	 $cpu='ia32';
      } else {
	 $cpu='xeon64';
      }
    }

    my $ntver;
    if($Config{"windows_nt"}){
      $ntver='winnt';
    }
    else {
      cfx5_require('Win32::API');

      # the the NT version
      my $GetVersionEx = new Win32::API("kernel32", "GetVersionEx", [qw(P)], 'V');
      if ($GetVersionEx) {
        # OK, we should be able to call this now
        my $buffer = pack("L",148)." " x 1024;
        my ( $major, $minor, $buildnum, $platform, $verstr );

        $GetVersionEx->Call($buffer);
        (
         undef,
         $major,
         $minor,
         $buildnum,
         $platform,
         $verstr
        ) = unpack("LLLLLA*", $buffer);

        # 0 => Windows 3.1 with win32s
        # 1 => Windows 95
        # 2 => Windows NT
        my %plat=( 0 => "win",
                   1 => "win",
                   2 => "winnt"
                 );

        $ntver = $plat{$platform} || 'windows';
        $ntver .= "$major.$minor";
      } else {
        _warn("Error loading GetVersionEx from kernel32.dll, unable to work out operating system version");
        $ntver="windows";
      }
    }

    my $vendor;
    cfx5_require('CFX5::Win32::Registry');
    if (defined (my $path=CFX5::Win32::Registry::registry_get("/HARDWARE/DESCRIPTION/System/CentralProcessor/0/VendorIdentifier"))) {
      if($path eq "AuthenticAMD"){
        return "amd_${cpu}_${ntver}";
      } else {
        return "intel_${cpu}_${ntver}";
      }
    } 
    return "intel_${cpu}_${ntver}";
  }

  # we have no other option ATM; use cfx5arch
  my $bindir=getconf_or_interr("CFX5BINDIR");

  my $cmd=join_file($bindir, "cfx5arch");
  my $arch=CFX5::Commands::get_cmd_output($cmd);
  #TODO: error checking?

  # remove any whitespace (including newlines)
  $arch=~s/\s*$//;

  return $arch;
}

sub CFX_OS {
  # on most systems, CFX_OS is simply the output of `uname`, but we
  # hardwire it here for some platforms which don't have consistent
  # output (such as Windows or IRIX).
  my $perlos=getconf_or_interr("CFX5OS");
  my %lu=(
	  'winnt' => 'CYGWIN32_NT',
	  'winnt-amd64' => 'CYGWIN64_NT',
	  'irix'    => 'IRIX',
	  'osf' => 'OSF1',
	  );

  if (exists $lu{$perlos}) {
    return $lu{$perlos};
  } else {
    my $os=CFX5::Commands::get_cmd_output("uname");
    #TODO: error checking?

    # remove any whitespace (including newlines)
    $os =~ s/\s*$//;

    return $os;
  }
}

sub arch_name {
  # a descriptive name for the architecture
  my $perlos=getconf_or_interr("CFX5OS");
  my %lu=(
	  'solaris' => 'Solaris',
          'solaris-amd64' => 'Solaris x64',
	  'winnt' => 'Microsoft Windows',
	  'winnt-amd64' => 'Microsoft Windows x64',
	  'irix'    => 'IRIX',
	  'osf' => 'DEC OSF/1',
	  'aix'     => 'IBM AIX',
	  'hpux'    => 'HP-UX',
	  'hpux-ia64'    => 'HP-UX/IA64',
	  'linux'   => 'Linux',
	  'linux-ia64'   => 'Linux/IA64',
	  'linux-amd64'   => 'Linux/X86_64',
          darwin => 'Apple Darwin',
	  );
  my %dlu=(
	   '' => '',
	   'debug' => ' (Debugging version)',
	  );

  return (exists $lu{$perlos} ? $lu{$perlos} : $perlos)
    .(exists $dlu{$Config{CFX5DEBUG}} ? $dlu{$Config{CFX5DEBUG}} : '');
}

sub CFX5_ARCH_ATTRS {
  my $a=CFX5::Attr::from_config();
  $a->to_config();
  undef;
}

sub CFX5_ARCH_TYPE {
  my $a=CFX5::Attr::from_config();
  $a->to_config();
  undef;
}

######################################################################
# other information which depends on the platform type
######################################################################

sub gui_support {
  my %oses=(
            'winnt' => 1,
            'winnt-amd64' => 1,
            'linux' => 1,
            'linux-amd64' => 1,
            'solaris' => 1,
            'aix'=> 1,
            );
  return defined $oses{$Config{CFX5OS}}
}

sub dir_sep {

  if ($Config{windows_nt}) {
    return "\\";
  } else {
    return "/";
  }
}

sub path_sep {
  if ($Config{windows_nt}) {
    return ";";
  } else {
    return ":";
  }
}

sub ld_path_var {
  my %lu=(
	  'aix' => "LIBPATH",
	  'hpux' => "SHLIB_PATH",
	  'hpux-ia64' => "SHLIB_PATH",
	  'irix' => "LD_LIBRARY64_PATH",
	  'osf' => "LD_LIBRARY_PATH",
	  'solaris' => "LD_LIBRARY_PATH_64",
	  'solaris-amd64' => "LD_LIBRARY_PATH_64",
	  'linux' => 'LD_LIBRARY_PATH',
	  'linux-ia64' => 'LD_LIBRARY_PATH',
	  'linux-amd64' => 'LD_LIBRARY_PATH',
	  'itlinux' => 'LD_LIBRARY_PATH',
	  'winnt' => "PATH",
	  'winnt-amd64' => "PATH",
	 );
  return $lu{$Config{'CFX5OS'}};
}


######################################################################
# information about the current host
######################################################################

sub CFX_HOST {
  if ($Config{'windows_nt'}) {
    if (exists $ENV{COMPUTERNAME}) {
      return $ENV{COMPUTERNAME};
    }
  }
  my $host=CFX5::Commands::get_cmd_output("hostname");

  # remove any whitespace (including newlines)
  $host =~ s/\s*$//;

  return $host;
}

sub CFX_FULLHOST {
  return $Config{CFX_HOST};
}

sub CFX_USER {
  if ($Config{'windows_nt'} and exists $ENV{USERNAME}) {
    return getlogin || $ENV{USERNAME};
  }

  # This will fail on windows
  return scalar getpwuid($<) || $ENV{USER} || $ENV{LOGNAME};
}

sub CFX_WIN32_DRIVE_LIST {
  return undef;
}

# On Windows systems, find if command shell supports UNC paths
sub unc_shell_support {
  if ($Config{windows_nt})
  {
    cfx5_require('CFX5::Win32::Registry');
    my $value = CFX5::Win32::Registry::registry_get("/Software/Microsoft/Command Processor/DisableUNCCheck");
    return 1 if (defined $value and $value == 1)
  }

  return 0;
}

sub CFX_AWP_ROOT {
    return get_environment_variable(
        "AWP_ROOT",
        join_file($Config{INSTALLROOT},"v".$Config{ANSYSCFXRELEASE})
    );
}

sub CFX_AWP_LOCALE {
    return get_environment_variable("AWP_LOCALE");
}

sub CFX_ICEMCFD_ROOT {
    return get_environment_variable("ICEMCFD_ROOT");
}

######################################################################
# directories
######################################################################

sub CFX5RELEASE {
  return $Config{CFXBUILDID};
}

#Ansys style release number
sub ANSYSCFXRELEASE {
  return $Config{CFXBUILDID_NOSEP};

}

# Current directory in which CFX is installed 
#   i.e. the .../Ansys Inc or ..../ansys_inc directory
#
sub INSTALLROOT {
  my $root5=getconf_or_interr("CFX5ROOT");
  return dirname(dirname($root5));
}


# Current ansys install root
#
# Note: This is actually the base base installation root not the mechanical
# module installation directory, although this is checked for existance.
#
# e.g. .../ansys_inc/vXXX is returned not .../ansys_inc/vXXX/ansys
# 
#
sub ANSYSINSTALLROOT {
  my $root = get_component("ansys");
  return dirname($root) if defined $root;
  return undef;
}

sub THIRDPARTYROOT {
  return get_component("tp");
}

# Current common files install root
#
# e.g. .../ansys_inc/vXXX/commonfiles is returned
# 
#
sub AWP_COMMON_FILES_ROOT {
  return get_component("commonfiles");
}

# Current workbench install root.
#
# Note: This is actually the workbench module directory
#
# e.g. .../ansys_inc/vXXX/aisol is returned
#
sub WORKBENCHINSTALLROOT {
  return get_component('aisol');
}

sub FRAMEWORKINSTALLROOT {
    return get_component('Framework');
}


sub APIP_INSTALL_ROOT {
    my $fwdir = getconf('FRAMEWORKINSTALLROOT');
    my $fwos = getconf('FRAMEWORKOS');
    return join_file($fwdir, 'bin', $fwos);
}

sub AFDINSTALLROOT {
    return get_component('AFD');
}

sub AFDSTARTSCRIPT {
    my $script = 'afd';
    my $ansysos = $Config{ANSYSOS};
    if (defined $ansysos and $ansysos eq 'winx64') {
        $script .= '.bat';
    }
    return $script;
}

sub AFDSTART {
    my $afddir = getconf('AFDINSTALLROOT');
    my $afdscript = getconf('AFDSTARTSCRIPT');
    if (defined $afddir and defined $afdscript) {
        return join_file($afddir, 'bin', $afdscript);
    }
    return undef;
}

sub CFX_7ZIP_EXE {

    my $zip_dir="7zip";
    my ($zip_version, $zip_name);
    if ( $Config{CFX5OS} eq 'winnt-amd64' ) {
        $zip_version="16.0.4";
        $zip_name="7z.exe";
    } else {
        $zip_version="16.0.2";
        $zip_name="7za";
    }

    return join_file( $Config{THIRDPARTYROOT},
                      $zip_dir,
                      $zip_version,
                      $Config{ANSYSOS},
                      $zip_name );
}


# ICEM install root.
#
# Note: This is actually the ICEM module executable directory
#
# e.g. .../ansys_inc/vXXX/icemcfd/<platform> is returned.
#
sub ICEMINSTALLROOT {
    my %osmap=(
        'winnt' => "win",
        'winnt-amd64' => "win64_amd",
        'linux-amd64' => "linux64_amd",
    );

    my $icemos = $osmap{$Config{'CFX5OS'}};
    my $file = join_file('icemcfd', $icemos);
    
    return get_component($file, 'ICEM_ACN');
}

sub CFXBUILDID {
    if (exists $ENV{CFXBUILDID}) {
        return $ENV{CFXBUILDID};
    }
    return undef;
}

sub CFXBUILDID_MAJOR_MINOR {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{MINOR}, \$ACCUMULATE{TRUE}, \$SEPARATOR{DOT});
}

sub CFXBUILDID_MAJOR {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{MAJOR}, \$ACCUMULATE{FALSE}, \$SEPARATOR{DOT});
}

sub CFXBUILDID_MINOR {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{MINOR}, \$ACCUMULATE{FALSE}, \$SEPARATOR{DOT});
}

sub CFXBUILDID_PATCH {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{PATCH}, \$ACCUMULATE{FALSE}, \$SEPARATOR{DOT});
}

sub CFXBUILDID_NOSEP {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{PATCH}, \$ACCUMULATE{TRUE}, \$SEPARATOR{NONE});
}

sub CFXBUILDID_NOSEP_MAJOR_MINOR {
    return get_version(\$VERSION_TYPE{BUILD_ID}, \$SEMVER{MINOR}, \$ACCUMULATE{TRUE}, \$SEPARATOR{NONE});
}

sub CFXREVISION {
    return get_version(\$VERSION_TYPE{REVISION});
}

sub CFXBASERELEASE {
    return get_version(\$VERSION_TYPE{BASE_RELEASE});
}

sub CFX5ROOT {
    return site_cfx()
}

sub CFX_DIR_STYLE {
  # what sort of installation is this?
  #return 'complete';
  return 'product';
}

sub CFX_ROOT {
  getconf_or_abort('CFX5ROOT',
		   "Failed to calculate a value for CFX5ROOT. Please ensure that the software\nis installed correctly.");
}

sub CFX_INSTALL_ROOT {
  # in the complete installation style, the install root is the same
  # as the normal root.  In the product-based style, it is one level
  # above. 
  my $root=getconf_or_interr('CFX5ROOT');
  if ($Config{CFX_DIR_STYLE} eq 'complete') {
    return $root;
  } elsif ($Config{CFX_DIR_STYLE} eq 'product') {
    return dirname($root);
  } else {
    internal_error("Unrecognised installation style $Config{CFX_DIR_STYLE}");
  }
}

sub debug_suff {
  return defined $Config{CFX5DEBUG} ? "_".$Config{CFX5DEBUG} : '';
}

sub CFX5BINDIR {
  # we don't need to worry about picking this up from the environment
  # or anything, since that's done before we get here
  my $bindir=get_std_dir("bin");
  _abort("ANSYS CFX binary directory\n\t$bindir\ndoes not exist. Please check that ANSYS CFX is installed correctly.")
    unless -d $bindir;

  return $bindir;
}

sub CFX5EXECDIR {
  my $bindir=getconf_or_interr("CFX5BINDIR");
  my $debug=getconf("CFX5DEBUG");
  my $os=getconf_or_interr("CFX5OS");

  if (defined $debug and $debug ne "") {
    $os  .="_debug";
  }

  if (-d join_file($bindir, $os)) {
    return join_file($bindir, $os);
  }

  unless ($Config{CFX_RUN_UNINSTALLED_PLATFORMS}) {
    # if we can't find it, something's fishy.
    _abort("$Config{CFX_PRODUCT_FULLNAME} for the $os operating system does not\n".
           "appear to be installed. Please check whether it has been\n".
           "loaded from CD.");
  }
  return undef;
}

sub CFX_CMD_DIR {
  return getconf_or_abort("CFX5BINDIR");
}

sub CFX5LIBDIR {
  my $libdir=getconf_or_interr("CFX5_LIB_ROOT");
  my $debug=getconf("CFX5DEBUG");
  my $os=getconf_or_interr("CFX5OS");

  if ($debug) {
    $os .= $debug;
  }

  return join_file($libdir, $os);
}

sub ANSYS_COMMON_ROOT {
    return get_component("commonfiles");
}

sub ANSYS_COMMON_IMAGES_DIR {
    
    return get_component( join_file("commonfiles", "images") );
}

sub ANSYSOS {
  my %lu=(
          'winnt' => "win32",
          'winnt-amd64' => "winx64",
          'linux' => "linia32",
          'linux-amd64' => "linx64",
          'linux-ia64' => "linia64",
         );
  return $lu{$Config{'CFX5OS'}};
}

sub FLUENTOS {
  my %lu=(
          'winnt-amd64' => 'win64',
          'linux-amd64' => 'lnamd64',
         );
  return $lu{$Config{'CFX5OS'}};
}

sub FRAMEWORKOS {
  my %lu=(
          'winnt-amd64' => 'Win64',
          'linux-amd64' => 'Linux64',
         );
  return $lu{$Config{'CFX5OS'}};
}


sub CFX_TOOLS_ROOT {
  if ($Config{CFX_DIR_STYLE} eq 'product') {
    # if there's a tools directory in the product, that beats Shared.
    # Otherwise, we use Shared if it's there.  If neither are there,
    # we don't have a solution, but for clarity of errors we have to
    # return one or the other; currently, we return tools.
    my $d;
    if (-d ($d=join_file($Config{CFX5ROOT}, 'tools'))) {
      return $d;
    } elsif (-d ($d=join_file($Config{CFX_INSTALL_ROOT}, 'Shared'))) {
      return $d;
    } elsif (-d ($d=join_file(dirname($Config{CFX_INSTALL_ROOT}), 'Shared'))) {
      return $d;
    } else {
      _debug("Unable to find tools directory, returning what it should be");
      return join_file($Config{CFX5ROOT}, 'tools');
    }
  } elsif ($Config{CFX_DIR_STYLE} eq 'complete') {
    return join_file($Config{CFX_INSTALL_ROOT}, 'tools');
  } else {
    internal_error("Unrecognised installation style $Config{CFX_DIR_STYLE}");
  }
}

sub MULTIPORT_ROOT {
  return $Config{'CFX_TOOLS_ROOT'};
}

# CFX_PERL_LIBDIR is the location of the perl*.dll, ie actually points
# to the bin directory ...
sub CFX_PERL_LIBDIR {
  return undef unless $Config{windows_nt};
  if (defined $Config{PERL_VERSION} and $Config{PERL_VERSION} ne 'none') {
    # new-style, have a version number
    if( $Config{CFX5OS} eq "winnt-amd64" ){
      return join_file($Config{CFX_TOOLS_ROOT}, "perl-$Config{PERL_VERSION}", 'bin', 'MSWin32-x64-perlio');
    }
    else {
      return join_file($Config{CFX_TOOLS_ROOT}, "perl-$Config{PERL_VERSION}", 'bin', 'MSWin32-x64-perlio');
    }
  } else {
    # old-style
    return join_file($Config{CFX_TOOLS_ROOT},$Config{CFX_OS},'perl','bin','MSWin32-x86');
  }
}

#
# This section only applies when the test suite is available.
# If a user has set CFX5TESTDIR we use that. If not we check
# whether they or we have set CFX_TEST_ROOT and use that.
#
sub CFX5TESTDIR {
  my $testroot=getconf("CFX_TEST_ROOT");
  return $testroot if defined $testroot and -d $testroot;

  my $root=getconf_or_interr("CFX5ROOT");
  my $d=join_file($root, "test");
  return $d if -d $d;

  return undef;
}

#
# iff the LIST module is loaded, we can do this
#
sub CFX_LICENSE_ROOT {
  # this will fail, and return undef, if this module is not loaded.
  local $@;
  eval { CFX5::LIST::license_dir(); }
}

sub CFX_ANSYSLIC_DIR {
  # our default for ANSYSLIC_DIR, only used if that variable is unset;
  # we just look in a couple of known places for the installation.
  #
  # this is mostly UNIX-focused, as we shouldn't need this on NT as
  # the install sets the variable up.  Does no harm to handle that
  # too, though.

  my $root5=getconf_or_interr("CFX5ROOT");
  $root5=dirname($root5);

  for my $root ($root5, dirname($root5), '/ansys_inc', 'C:\Program Files\Ansys Inc') {
    next unless -d $root;
    if (-d (my $dir=join_file($root, 'shared_files', 'licensing'))) {
      return $dir;
    }
    if (-d (my $dir=join_file($root, 'Shared Files', 'Licensing'))) {
      return $dir;
    }
  }

  # no luck
  undef;
}

sub ANSYSLIC_DIR {
  return $Config{CFX_ANSYSLIC_DIR};
}

sub HOME {
  # if we've got here, then the HOME environment variable is unset.
  # On Windows, we can synthesise this from HOMEDRIVE and HOMEPATH in
  # many cases, but if these are unset we usually need to give an
  # error.

  if ($Config{'windows_nt'}) {
    if (exists $ENV{HOMEDRIVE}) {
      # allow HOMEPATH to default to \ for Netware installs
      my $homepath=$ENV{HOMEPATH};
      $homepath='\\' unless defined $homepath;
      # cool, sorted
      return $ENV{HOMEDRIVE}.$homepath;
    }
    if ( exists $ENV{USERPROFILE} ) {
      return $ENV{USERPROFILE};
    }
    _abort("Please ensure that either HOMEDRIVE and HOMEPATH or the USERPROFILE environment variable is set before running CFX-5.")
      unless $Config{allow_unset_home};
  }

  _abort("Please ensure that the HOME environment variable is set before running CFX-5.")
    unless $Config{allow_unset_home};

  _trace("HOME not set, assuming stupid default");
  # if we just used '/', it would make a UNC share on NT ...
  '/.';
}

sub CFX_STL_LIBDIR {
  join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, 'stlprt40','lib');
}

sub CFX_STLPORT_LIBDIR {
  my %oses=(
            hpux => 'HP-UX',
            'hpux-ia64' => 'HP-UX-ia64',
            );
  my $STLPORT_OS = $oses{$Config{CFX5OS}} || $Config{CFX_OS};

  join_file($Config{CFX_TOOLS_ROOT},  'STLport-4.6.2','lib',  $STLPORT_OS);
}

sub CFX_MESA_LIBDIR {
  unless($Config{CFX5OS} eq "linux" or $Config{CFX5OS} eq "linux-amd64"){
    return undef;
  }
  join_file($Config{CFX_TOOLS_ROOT}, 'Mesa-7.1', 'lib', $Config{CFX5OS});
}

sub CFX_SUBSETS_ROOT {
  return get_std_dir('subsets');
}

sub CFX_SUBSETS_ROOT_TARGZ {
  return join_file($Config{CFX_SUBSETS_ROOT},"targz");
}
sub CFX_SUBSETS_DIR_TARGZ {
  return join_file($Config{CFX_SUBSETS_ROOT_TARGZ},"all");
}

sub CFX5_REACTIONS_DIR {
  if( defined $Config{CFX_CUSTOM_DATA_DIR} ){
    return join_file($Config{CFX_CUSTOM_DATA_DIR}, 'reactions-extra') if -d join_file($Config{CFX_CUSTOM_DATA_DIR}, 'reactions-extra');
  }
  return join_file($Config{CFX_DATA_DIR}, 'reactions-extra');
}
sub CFX5_MATERIALS_DIR {
  if( defined $Config{CFX_CUSTOM_DATA_DIR} ){
    return join_file($Config{CFX_CUSTOM_DATA_DIR}, 'materials-extra') if -d join_file($Config{CFX_CUSTOM_DATA_DIR}, 'materials-extra');
  }
  return join_file($Config{CFX_DATA_DIR}, 'materials-extra');
}
sub CFX5_TT_FILE {
  if( defined $Config{CFX_CUSTOM_DATA_DIR} ){
    return join_file($Config{CFX_CUSTOM_DATA_DIR}, 'tt.txt') if -f join_file($Config{CFX_CUSTOM_DATA_DIR}, 'tt.txt');
  }
  undef;
}

sub CFX_PYTHON_VER {
    return "2_7_13";
}

sub CFX_COMMON_PYTHON {
    return get_component( 
        join_file("commonfiles", "CPython", $Config{CFX_PYTHON_VER}, 
            $Config{ANSYSOS}, "Release", "python") 
    );
}

sub CFX_SOLVE_REMOTE_WORKDIR {
  return $Config{HOME};
}


######################################################################
# config files
######################################################################

sub CFX_RELEASE_FILE {
  return join_file(getconf_or_interr("CFX_DATA_DIR"),'release.sh');
}

sub CFX_SITEFILE {
  my $cfgdir=getconf_or_interr("CFX_CONFIG_DIR");

  for my $suf (qw(CFX_HOST CFX5_HOST_ARCH CFX5OS CFX_OS none)) {
    my $suffix='';
    unless ($suf eq 'none') {
      $suffix='-'.getconf_or_interr($suf);
    }

    # TODO: look in \winnt\profiles\<user>\cfx
    for my $prefix (join_file($cfgdir,"")) {
      my $file=$prefix.'cfx5rc'.$suffix;
      return $file if -r $file;
      return "$file.txt" if -r "$file.txt";
    }
  }

  my $root=getconf_or_interr("CFX_ROOT");

  return join_file($root,"config","cfx5rc-site") if -r join_file($root,"config","cfx5rc-site");

  return undef;
}

sub CFX_PROFILE_DIR {
  #
  # the directory under NT where we should store all our configuration
  # information, eg C:\WINNT\Profiles\cfdasm\Application
  # Data\CFX-5. This is not defined or used under UNIX.
  #
  # Config files will be found in a subdirectory of this.
  #
  return undef unless $Config{windows_nt};
  my $userprofile = $Config{USERPROFILE};
  unless ($userprofile) {
    _abort("The USERPROFILE environment variable is not set, ANSYS CFX is unable to locate your profile directory.  Please ensure this variable is set before running CFX-5.");
  }
  return join_file($userprofile, "Application Data", "CFX-5");
}

sub CFX_USERFILE {
  #
  # we look in first ~/.cfx/$CFXBUILDID_MAJOR_MINOR for cfx5rc files then in ~
  # for .cfx5rc files for compatability with CFX-5.2.
  #
  my $home=getconf_or_interr("HOME");

  my $release=getconf_or_interr("CFXBUILDID_MAJOR_MINOR");

  for my $suf (qw(CFX_HOST CFX5_HOST_ARCH CFX5OS CFX_OS none)) {
    my $suffix='';
    unless ($suf eq 'none') {
      $suffix='-'.getconf_or_interr($suf);
    }

    for my $prefix ((defined $Config{CFX_USER_CONFIG_DIR}
		     ? join_file($Config{CFX_USER_CONFIG_DIR},$release,'')
		     : ()),
		    (defined $Config{CFX_PROFILE_DIR}
		     ? join_file($Config{CFX_PROFILE_DIR},$release,'')
		     : ()),
		    join_file($home,".cfx",$release,""),
		    join_file($home,"CFX",$release,""),
		    join_file($home,".")) {
      my $file=$prefix.'cfx5rc'.$suffix;
      return $file if -r $file;
      return "$file.txt" if -r "$file.txt";
    }
  }

  return undef;
}

sub CFX_USER_CONFIG_DIR {
  #
  # this is a directory to put *new* config files in. See
  # CFX_USERFILE. It is not guaranteed to exist.
  #
  my $home=getconf_or_interr("HOME");

  for my $prefix ((defined $Config{CFX_PROFILE_DIR}
		   ? $Config{CFX_PROFILE_DIR}
		   : ()),
		  join_file($home,".cfx"),
		  join_file($home,"CFX")) {
    return $prefix if -d $prefix;
  }

  #
  # the default: on NT, $USERPROFILE/App Data/cfx, on UNIX ~/.cfx
  #
  if ($Config{windows_nt}) {
    return $Config{CFX_PROFILE_DIR};
  } else {
    return join_file($Config{HOME}, '.cfx');
  }
}

sub CFX_CCS_SUBMIT_SCRIPT {
  #
  # we look first in ~/.cfx/$CFXBUILDID_MAJOR_MINOR for the submit script
  # then in CFX_DATA_DIR
  
  my $release=getconf_or_interr("CFXBUILDID_MAJOR_MINOR");

  for my $prefix ((defined $Config{CFX_USER_CONFIG_DIR}
                     ? join_file($Config{CFX_USER_CONFIG_DIR},$release,'')
                     : ()),
                    (defined $Config{CFX_PROFILE_DIR}
                     ? join_file($Config{CFX_PROFILE_DIR},$release,'')
                     : ()),
                    join_file($Config{CFX_CONFIG_DIR}, ''),
                    join_file($Config{CFX_DATA_DIR},'')) {
    my $file=$prefix.'cfxwinhpc.pl';
    return $file if -r $file;
  }

  return undef;
}

######################################################################
# Information about this release
######################################################################

#V CFX5BUILDNUM
##   This variable contains the number of the most recent rebuild of
##   this version.  It's value is taken from the file buildnum.txt in
##   $CFX_DATA_DIR.  If the file is missing, the return value will be
##   '0'.
sub CFX5BUILDNUM {
  my $dir=getconf_or_abort('CFX_DATA_DIR');
  unless (-f join_file($dir, 'buildnum.txt')) {
    _debug("No buildnum.txt file");
    return 0;
  }
  local *BNFILE;
  unless (open BNFILE, "<".join_file($dir,'buildnum.txt')) {
    _debug("Cannot open buildnum.txt: $!");
    return 0;
  }
  my $l=<BNFILE>;
  close BNFILE;
  chomp $l;
  $l;
}

#V CFX5RELTYPE
##   This variable will be "development", "prerelease" or "release",
##   depending on the release type.  It is usually derived from the
##   version number, but may be overridden.  It can be used to control
##   things like assertions in the code.
sub CFX5RELTYPE {
  my $v=getconf_or_interr('CFXBUILDID');
  my $t;
  if ($v =~ m/(alpha|beta|gamma)[0-9]*$/) {
    # 5.4alpha, 5.4beta3, etc are all prereleases
    $t='prerelease';
  } elsif ($v =~ m/^[0-9.]+$/) {
    # 5.4, 5.3.1, et al are the final release codes
    $t='release';
  } else {
    # anything else is a development code
    $t='development';
  }
  $t;
}

#V CFX5_DEVELOPER
##   Set to a true value if the current user may be assumed to be a
##   ANSYS CFX developer.  This is currently only used to decide whether
##   or not to display the help for internal options.
sub CFX5_DEVELOPER {
  my $root=getconf_or_interr('CFX5ROOT');
  my $rel=getconf_or_interr('CFXBUILDID_MAJOR_MINOR');
  return (-d join_file($root,'src',$rel) ? 'YES' : undef);
}


######################################################################
# commands
######################################################################

sub CFX5LNS {
  my %lu=(
	  'aix' => "ln -s",
	  'hpux' => "ln -s",
	  'irix' => "ln -s",
	  'linux' => "ln -s",
	  'itlinux' => "ln -s",
	  'osf' => "ln -s",
	  'solaris' => "ln -s",
	  'winnt' => "cp",
	  'winnt-amd64' => "cp",
	 );
  return $lu{$Config{'CFX5OS'}};
}

sub CFX5RSH {
  my $os=$Config{'CFX5OS'};
  if ($os eq 'hpux' or $os eq 'hpux-ia64') {
    return 'remsh';
  } else {
    return 'ssh';
  }
}

sub CFX5RSH_PROBE {
  my $rshcmd = $Config{CFX5RSH};
  if ($rshcmd eq 'ssh') {
    return 'ssh -oBatchMode=yes';
  } else {
    return $rshcmd;
  }
}

sub P4_RSHCOMMAND {
  return $Config{CFX5RSH};
}

sub MPI_REMSH {
  return $Config{CFX5RSH};
}

sub I_MPI_MPD_RSH {
  return $Config{CFX5RSH};
}

sub CFX5AWK {
  my %lu=(
	  'aix' => "nawk",
	  'hpux' => "awk",
	  'irix' => "nawk",
	  'linux' => "awk",
	  'itlinux' => "awk",
	  'osf' => "nawk",
	  'solaris' => "nawk",
	  'winnt' => "awk",
	  'winnt-amd64' => "awk",
	 );
  return $lu{$Config{'CFX5OS'}};
}

######################################################################
# other products
######################################################################

######################################################################
# other blocks
######################################################################

sub scu {
  my ($r,$v)=@_;
  $Config{$r}=$v unless defined $Config{$r};
}

sub do_build_run_vars {
  scu 'CFX_BUILD_ROOT', get_std_dir('build');
  scu 'CFX_BUILD_DIR', join_file($Config{CFX_BUILD_ROOT}, $Config{CFX5OS}.$Config{'debug_suff'});

  if ($Config{P3_VERSION} eq 'none') {
    return undef;
  }

  #scu 'P3_VERSION', '9.5';

  # we find things in the tools/patran directory if possible;
  # otherwise we look in build/support
  my $rd=join_file($Config{CFX_TOOLS_ROOT}, "patran");
  $rd=join_file($Config{CFX_ROOT},'build','support') unless -d join_file($rd,$Config{P3_VERSION});
  scu 'P3_ROOT', $rd;

  scu 'P3_HOME', join_file($Config{P3_ROOT}, $Config{P3_VERSION}, $Config{CFX5OS});
  scu 'P3_USER_MESSAGES', join_file($Config{CFX_BUILD_DIR}, "user_messages.database");
  scu 'P3_HELP_DIRECTORY', $Config{CFX_HELP_DIR};

  undef;
}

sub P3_VERSION {
  _abort("The MSC.Patran version on which $Config{CFX_PRODUCT_FULLNAME} is based has not been set in the release definition file.  Check that $Config{CFX_PRODUCT_FULLNAME} is correctly installed.");
  undef;
}

sub do_build_pdb_vars {
  if ($Config{P3_VERSION} eq 'none') {
    return undef;
  }

  scu 'P3_ENABLE_NFS_DB_ACCESS', ($Config{windows_nt} ? 'no' : 'yes');

  scu 'PDB_C_CACHE_SIZE', 1_000_000_000;
  scu 'PDF_LOCKING_DISABLED', 'true';

  scu 'P3_INITIAL_PATH', join_file($Config{P3_HOME},'bin');

  scu 'P_SCHEMA', join_file($Config{P3_HOME},'schema');

  scu 'P3UPGRADE2001R1_TEMPLATE', join_file($Config{CFX_BUILD_DIR},'CFXBuild5_template.db');

  undef;
}

sub do_build_comp_vars {
  undef;
}

sub do_cue_general_vars {
  scu 'CFX_CUE_ROOT', get_std_dir('cue');
  my %ost=(winnt => 'Windows_NT', 'winnt-amd64' => 'Windows_NT');
  scu 'CFX_CUE_OSTYPE', $ost{$Config{CFX5OS}} || $Config{CFX5OS};

  undef;
}

sub do_pvm_run_vars {
  scu 'CFX_PVM_VERSION', "3.4.4_11-2";
  scu 'PVM_VERSION', $Config{CFX_PVM_VERSION};

  if (-d join_file($Config{CFX_TOOLS_ROOT},$Config{CFX_OS},'pvm'.$Config{PVM_VERSION})) {
    # windows NT
    scu 'PVM_ROOT', join_file($Config{CFX_TOOLS_ROOT},$Config{CFX_OS},'pvm'.$Config{PVM_VERSION});
  } else {
    # UNIX
    scu 'PVM_ROOT', join_file($Config{'CFX_TOOLS_ROOT'},
			      "pvm".$Config{'PVM_VERSION'});
  }

  # the known OSes are hardwired into CFX5::Arch.
  cfx5_require('CFX5::Arch');
  if (defined CFX5::Arch->pvm_arch($Config{CFX5OS})) {
    scu 'PVM_ARCH', CFX5::Arch->pvm_arch($Config{CFX5OS});
  } elsif (-d join_file($Config{PVM_ROOT}, "lib")
	   and -f join_file($Config{PVM_ROOT}, "lib", "pvmgetarch")) {
    my $pvmarch=join_file($Config{PVM_ROOT}, "lib", "pvmgetarch");
    my $a=qx($pvmarch);
    $a=~s/\s*$//;
    if (defined($a) and $a ne "") {
      scu 'PVM_ARCH', $a;
    }
  }

  undef;
}

sub CFX5_HOSTS_CCL {
  find_config_file('hostinfo.ccl');
}

sub CFX5_START_METHODS_CCL {
  my $file=find_config_file('start-methods.ccl');
  return $file if defined $file;

  # otherwise, we have a central one which should always be there
  return join_file($Config{CFX_DATA_DIR}, 'start-methods.ccl');
}

sub CFX_TCLPROCS {
  my $procs=join_file($Config{CFX5_LIB_ROOT}, "tclprocs");
  if ($Config{windows_nt}) {
    #
    # On Windows NT, Tcl needs us to have forward slashes in environment
    # variables which it uses as paths.
    #
    $procs =~ s{\\}{/}g;
  }
  return $procs;
}

sub do_solver_run_vars {
  #
  # MPI Variables
  #
  if ($Config{windows_nt})
  {
    #
    # Windows default parallel mode is impi
    #
    scu 'CFX5_PARALLEL_MODE', 'impi';
    #
    # Windows - Intel MPI (search order: I_MPI_ROOT > registry > commonfiles)
    #
    my $impi_os = ($Config{'CFX5OS'} eq 'winnt-amd64') ? 'intel64' : 'ia32';

    my $impiver = '5.1.3.180';
    my $impidir = join_file($Config{ANSYS_COMMON_ROOT},'MPI','Intel',$impiver,$Config{ANSYSOS});

    my $impi_root = $Config{I_MPI_ROOT};

    if (defined $impi_root && -d $impi_root)
    {
      $impiver = undef;
      for my $osdir ($impi_os,$Config{ANSYSOS})
      {
        my $impidir_chk = join_file(normalize_filename($impi_root),$osdir);
        if (-d $impidir_chk) {
          $impidir = $impidir_chk;
          last;
        }
      }
    }
    else
    {
      cfx5_require('CFX5::Win32::Registry');

      my $regpath = '/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall';
      if ($Config{CFX5OS} eq "winnt-amd64") {
        $regpath = '/SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall';
      }

      my @keys = sort(CFX5::Win32::Registry::registry_list_subkeys($regpath));
      if (@keys)
      {
        my $impikey;
        for my $key (@keys)
        {
          my $displayname = CFX5::Win32::Registry::registry_get("$regpath/$key/DisplayName");
          next unless ($displayname);
          $impikey = $key if ($displayname =~ m/Intel.+MPI/);
        }

        if ($impikey)
        {
          my $instdir = CFX5::Win32::Registry::registry_get("$regpath/$impikey/InstallLocation");
          my $displayver = CFX5::Win32::Registry::registry_get("$regpath/$impikey/DisplayVersion");
          if (defined $instdir)
          {
            my $impibindir = join_file(normalize_filename($instdir),$impi_os);
            if (-d $impibindir)
            {
              $impidir = $impibindir;
              $impiver = $displayver if (defined $displayver);
            }
          }
        }
      }
    }

    scu 'CFX5_IMPI_VERSION', $impiver;
    scu 'CFX5_IMPI_DIR', $impidir;

    my $winnt_version = $Config{windows_nt_version};
    if (defined $winnt_version) {
      my ($major,$minor) = split(/\s*\.\s*/, $winnt_version);
      scu 'CFX5_IMPI_DISALLOW', '1' if ($major eq '5');
    }
    #
    # Windows - IBM MPI (search order: MPI_ROOT > registry > commonfiles)
    #
    my $ibmmpiver='9.1.4.2';
    my $ibmmpidir=join_file($Config{ANSYS_COMMON_ROOT},'MPI','IBM',$ibmmpiver,$Config{ANSYSOS}); 

    my $mpi_root = $Config{MPI_ROOT};

    if (defined $mpi_root && -d $mpi_root)
    {
      $ibmmpiver = undef;
      $ibmmpidir = $mpi_root;
    }
    else
    {
      cfx5_require('CFX5::Win32::Registry');

      my $regpath='/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall';
      if ($Config{CFX5OS} eq "winnt-amd64") {
        $regpath='/SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall';
      }

      my @keys=sort(CFX5::Win32::Registry::registry_list_subkeys($regpath));
      if(@keys){
        my $ibmmpikey;
        foreach my $k (@keys) {
          $ibmmpikey=$k if $k=~m!^IBM Platform-MPI!;
        }
        if($ibmmpikey){
          $regpath.="/$ibmmpikey";
          my $instdir=CFX5::Win32::Registry::registry_get($regpath.'/InstallLocation');
          my $displayname=CFX5::Win32::Registry::registry_get($regpath.'/DisplayName');
          if($instdir){
            $ibmmpidir=$instdir;
            if($displayname){
              ($ibmmpiver=$displayname)=~s!^Platform-MPI !!g;
            }
          }
        }
      }
    }

    scu 'CFX5_IBMMPI_VERSION', $ibmmpiver;
    scu 'CFX5_IBMMPI_DIR', $ibmmpidir;

  } elsif ($Config{CFX5OS} eq 'linux-amd64') {
    #
    # Linux default parallel mode is impi
    #
    scu 'CFX5_PARALLEL_MODE', 'impi';
    #
    # Linux - IBM MPI & Intel MPI Variables
    #
    scu 'CFX5_IBMMPI_VERSION', '9.1.4.2';
    my $ibmmpidir = join_file($Config{ANSYS_COMMON_ROOT},'MPI','IBM',$Config{CFX5_IBMMPI_VERSION},$Config{ANSYSOS});
    scu 'CFX5_IBMMPI_DIR', $ibmmpidir;
                                      
    scu 'CFX5_IMPI_VERSION', '5.1.3.223';
    my $impidir = join_file($Config{ANSYS_COMMON_ROOT},'MPI','Intel',$Config{CFX5_IMPI_VERSION},$Config{ANSYSOS});
    scu 'CFX5_IMPI_DIR', $impidir;
  }

  # for some runs, we need to increase the default value of this
  # setting, but it can't go above the system limit.  For now, we only
  # set it on Linux, where the limit is higher than on at least some
  # other systems (!).
  if ($Config{CFX5OS}=~m!linux!) {
    scu 'P4_GLOBMEMSIZE', 16777216;
  }

  undef;
}

sub do_refiner_run_vars {
  scu 'CFX5_REFINER_EXEC', join_file($Config{CFX5EXECDIR}, "refiner.exe");
  undef;
}

sub do_interp_old_run_vars {
  scu 'CFX_INTERP_EXEC', join_file($Config{CFX5EXECDIR}, "interp.exe");
  undef;
}

sub do_tcltk_vars {
  scu 'TCL_VERSION', '8.0';
  scu 'TK_VERSION', '8.0';

  my $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "lib", "tcl".$Config{TCL_VERSION});
  if (-d $f) {
    $f =~ s{\\}{/}g if $Config{windows_nt};
    scu 'TCL_LIBRARY', $f;
  }

  $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "lib", "tk".$Config{TK_VERSION});
  if (-d $f) {
    $f =~ s{\\}{/}g if $Config{windows_nt};
    scu 'TK_LIBRARY', $f;
  }

  if ($Config{windows_nt}) {
    my $tkv=$Config{TK_VERSION};
    $tkv =~ s{[^A-Za-z0-9]}{}g;
    $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "bin", "wish".$tkv.".exe");
  } else {
    $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "bin", "wish".$Config{TK_VERSION});
  }
  scu 'CFX_WISH', $f if -f $f;

  if ($Config{windows_nt}) {
    my $tkv=$Config{TCL_VERSION};
    $tkv =~ s{[^A-Za-z0-9]}{}g;
    $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "bin", "tclsh".$tkv.".exe");
  } else {
    $f=join_file($Config{CFX_TOOLS_ROOT}, $Config{CFX_OS}, "bin", "tclsh".$Config{TK_VERSION});
  }
  scu 'CFX_TCLSH', $f if -f $f;

  undef;
}

sub do_help_run_vars {
  $Config{CFX_HELP_DIR}=undef;
  $Config{CFX_HELP_JARDIR}=undef;
  
  my @helpdirs = (
    get_commonfiles_dir(join_file('help', $Config{CFX_AWP_LOCALE}, 'help')),
    get_commonfiles_dir(join_file('help', 'en-us', 'help'))
  );
  
  for my $helpdir (@helpdirs) {
    if ($helpdir && -d $helpdir) {
        scu 'CFX_HELP_DIR', $helpdir;
    }
  }
  
  if (not defined $Config{CFX_HELP_DIR}) {
    my $helpexedir = get_commonfiles_dir(join_file('help', 'HelpViewer'));
    my $helpexe = join_file($helpexedir, 'ANSYSHelpViewer.exe');
    if (-x $helpexe) {
      my $helpdir = join_file( $helpexedir, '..', 'en-us', 'help' );
      scu 'CFX_HELP_DIR', $helpdir;
    }
  }

  scu 'CFX_HELP_JARDIR', join_file( $Config{CFX_HELP_DIR}, "jar" ) if defined $Config{CFX_HELP_DIR};

  undef;
}

sub do_launcher_vars {
  # launcher is always 32bit
  scu 'CFX_LAUNCHER_EXEC_TYPE', '32bit';
  scu 'CFX_LAUNCHER_EXEC', find_executable(CFX_LAUNCHER_EXEC => 'launcher.exe', "ANSYS CFX Launcher Executable");
  undef;
}

sub CFX5PERL {
  return $^X;
}

sub do_qt_vars {
  my %vers=(
           
           "winnt" => "4.4.3",
           "winnt-amd64" => "4.8.4",
           "linux-amd64" => "4.8.4",
            );
  scu 'CFX_QT_VERSION' => ($vers{$Config{CFX5OS}} || '4.8.4');

  if (defined($Config{CFX5DEBUG}) and $Config{CFX5DEBUG} eq 'debug') {
    scu 'CFX_QT_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qt-$Config{CFX_QT_VERSION}_debug");
  } else {
    scu 'CFX_QT_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qt-$Config{CFX_QT_VERSION}");
  }

  my %oses=(
            linux => 'Linux',
            'linux-ia64' => 'Linuxv-ia64',
            'linux-amd64' => 'Linux-amd64',
            irix => 'IRIXv-64',
            hpux => 'HP-UXv-64',
            'hpux-ia64' => 'HP-UXv-ia64',
            solaris => 'SunOS-64',
            aix => 'AIXv-64',
           );
  scu 'CFX_QT_OS' => ($oses{$Config{CFX5OS}} || $Config{CFX_OS});
  scu 'CFX_QT_LIBDIR' => join_file($Config{CFX_QT_DIR},'lib',$Config{CFX_QT_OS});
  scu 'QT_PLUGIN_PATH' => join_file($Config{CFX_QT_DIR},'plugins',$Config{CFX_QT_OS});
  undef;
}

sub do_qwt_vars {
  my %vers=(
           "winnt" => "5.1.1",
           "winnt-amd64" => "5.2.3",
           "linux-amd64" => "5.2.3",
            );
  scu 'CFX_QWT_VERSION' => ($vers{$Config{CFX5OS}} || '5.2.3');

  if (defined($Config{CFX5DEBUG}) and $Config{CFX5DEBUG} eq 'debug') {
    scu 'CFX_QWT_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qwt-$Config{CFX_QWT_VERSION}_debug");
  } else {
    scu 'CFX_QWT_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qwt-$Config{CFX_QWT_VERSION}");
  }

  scu 'CFX_QWT_LIBDIR' => join_file($Config{CFX_QWT_DIR},'lib',$Config{CFX_QT_OS});
  undef;
}

sub do_qwtpolar_vars {
  my %vers=(
           "winnt-amd64" => "0.1.0",
           "linux-amd64" => "0.1.0",
            );
  scu 'CFX_QWTPOLAR_VERSION' => ($vers{$Config{CFX5OS}} || '0.1.0');

  if (defined($Config{CFX5DEBUG}) and $Config{CFX5DEBUG} eq 'debug') {
    scu 'CFX_QWTPOLAR_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qwtpolar-$Config{CFX_QWTPOLAR_VERSION}_debug");
  } else {
    scu 'CFX_QWTPOLAR_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "qwtpolar-$Config{CFX_QWTPOLAR_VERSION}");
  }

  scu 'CFX_QWTPOLAR_LIBDIR' => join_file($Config{CFX_QWTPOLAR_DIR},'lib',$Config{CFX_QT_OS});
  undef;
}

sub do_boost_vars {
  scu 'CFX_BOOST_VERSION' => "1.56.0";
  scu 'CFX_BOOST_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "boost-$Config{CFX_BOOST_VERSION}");
  scu 'CFX_BOOST_LIBDIR' => join_file($Config{CFX_BOOST_DIR},$Config{ANSYSOS},'lib');
  undef;
}

sub COMMON_JAVA {
    return get_commonfiles_dir('jre')
}

sub do_java_vars {
  my $classdir=join_file( join_file($Config{CFX_ROOT},'support'), 'jar');
  my @classes=( 
        "ansyshelp.jar",
        "ohj",
        "ohj/help4-nls.jar",
        "ohj/ohj-jewt.jar",
        "ohj/oracle_ice.jar",
        "ohj/swingall.jar");
  my $classpath="";
  my %platformDir=(
           linux => "linia32",
           winnt => "intel",
           "winnt-amd64" => "winx64",
           "linux-amd64" => "linx64",
           "linux-ia64" => "linia64",
           solaris => "solus64",
           aix => "aix64",
           hpux => "hp64",
           );
  my $javadir=$Config{COMMON_JAVA};

  if( $Config{windows_nt} ){

        foreach my $i (@classes){
          $i=~s!/!\\!g;
          $classpath.="$classdir\\$i;";
        }
  } else {

        my $javaver="1.5";
        my $javadirlocal=join_file($Config{CFX_TOOLS_ROOT}, "java-"."$javaver");
        scu 'CFX_JAVA_VERSION' => "$javaver";
        scu 'CFX_LOCAL_JAVA_DIR' => "$javadirlocal";
        foreach my $i (@classes){
          $classpath.="$classdir/$i:";
        }
  }
  # Only set CFX_CLASSPATH if $classdir exists
  scu 'CFX_CLASSPATH'=>"$classpath" if -d "$classdir";

  if (defined $platformDir{$Config{CFX5OS}}) {
    $javadir=join_file($javadir, $platformDir{$Config{CFX5OS}}, 'bin') if defined $platformDir{$Config{CFX5OS}};
    scu 'CFX_JAVA_DIR' => "$javadir" if -d "$javadir";
  }
  undef;
}

sub CFX5MONO {
  # look for mono install on Linux
  my %monoplatforms=(
      'linux' => "Linux",
      'linux-amd64' => "Linux64"
     );
  if (exists $monoplatforms{$Config{CFX5OS}}) {
      my $monoexe=get_commontools_dir(join_file('mono', $monoplatforms{$Config{CFX5OS}}, 'bin', 'mono'));
      return $monoexe;
  }
  return "";
  undef; 
}

sub do_xerces_vars {
  scu 'CFX_XERCES_VERSION' => "2.5.0";
  scu 'CFX_XERCES_DIR' => join_file($Config{CFX_TOOLS_ROOT}, "xerces-$Config{CFX_XERCES_VERSION}");
  scu 'CFX_XERCES_LIBDIR' => join_file($Config{CFX_XERCES_DIR},'bin',$Config{CFX_OS});
  undef;
}

sub do_cfxcpp_vars {
  scu 'CFXCPP_ROOT' => $Config{CFX5ROOT};

  my $os=getconf_or_interr("CFX5OS").getconf("debug_suff");
  scu 'CFXCPP_LIBDIR' => join_file($Config{CFXCPP_ROOT},'lib',$os);

  undef;
}

sub do_menu_cmds {
  my $os=$Config{'CFX5OS'};
  my %lu=(
	  'aix' => "/usr/dt/bin/dtpad -viewOnly",
	  'hpux' => "/usr/dt/bin/dtpad -viewOnly",
	  'irix' => "/usr/sbin/jot -v",
	  'itlinux' => "/usr/bin/gless",
	  'linux' => "/usr/bin/gless",
	  'osf' => "/usr/dt/bin/dtpad -viewOnly",
	  'solaris' => "/usr/dt/bin/dtpad -viewOnly",
	  'winnt' => 'write',
          'winnt-amd64' => 'write',
	 );
  scu 'CFX5BROWSER', $lu{$os}
    if exists $lu{$os};

  %lu=(
	  'aix' => "/usr/dt/bin/dtpad",
	  'hpux' => "/usr/dt/bin/dtpad",
	  'irix' => "/usr/sbin/jot",
	  'linux' => "/usr/bin/kedit",
	  'itlinux' => "/usr/bin/kedit",
	  'osf' => "/usr/dt/bin/dtpad",
	  'solaris' => "/usr/dt/bin/dtpad",
	  'winnt' => 'write',
	  'winnt-amd64' => 'write',
	 );
  scu 'CFX5EDITOR', $lu{$os}
    if exists $lu{$os};

  %lu=(
       'aix' => "/usr/dt/bin/dtterm -sl 1000 -bg white -fg black",
       'hpux' => "/usr/dt/bin/dtterm -sl 1000 -bg white -fg black",
       'irix' => "/usr/bin/X11/xterm -bg white -fg black -sb -sl 1000",
       'linux' => "/usr/X11R6/bin/xterm -bg white -fg black -sb -sl 1000",
       'itlinux' => "/usr/X11R6/bin/xterm -bg white -fg black -sb -sl 1000",
       'osf' => "/usr/dt/bin/dtterm -sl 1000 -bg white -fg black",
       'solaris' => "/usr/dt/bin/dtterm -sl 1000 -bg white -fg black",
       'winnt' => 'cmd /c start',
       'winnt-amd64' => 'cmd /c start',
     );
  scu 'CFX5XTERM', $lu{$os}
    if exists $lu{$os};

  undef;
}

sub CFX_AVOID_SHELL_COMMANDS {
  return 1;
}

sub CFX_SOLVE_DISABLE_REMOTE_CHECKS {
  if ($Config{windows_nt}) {
    return 1;
  } else {
    return 0;
  }
}

sub CFX_SOLVE_USE_REMOTE_HELPER {
  return -1;
}

sub CFX5_MPEG_ENCODE_EXE {
    my $mpeg;
    if( $Config{CFX5OS} eq "winnt-amd64" ){
        $mpeg = join_file($Config{CFX_TOOLS_ROOT}, 'CYGWIN64_NT', 'bin', 'mpeg_encode.exe');
    }
    else {
        $mpeg = join_file($Config{CFX_TOOLS_ROOT}, 'Linux', 'bin', 'mpeg_encode');
    }
    
    if ( -f $mpeg && -x $mpeg ) {
        return $mpeg;
    }
    
    undef;
}

sub PERL5SHELL {
    if( $Config{CFX5OS} eq "winnt-amd64" ){
        return "cmd /X/D/C";
    }
    
    undef;
}

1;
