#!/bin/sh
#
#  Name:
#     mex    compilation program for MATLAB C language MEX files
#     
#  Usage:
#     mex [ -argcheck -c -Dname[=def] -f optionsfile -fortran -g
#           -Ipathname -llibrary -Ldir -output resultname
#           -O -Uname -V4 -v name=[def] ] sourcefile ... [ objectfile ]
#           ... [ library ] ... 
#
#   Description:
#     "mex" will compile and link MEX source files into a relocatable
#     executable image.  This image is only executable from within
#     MATLAB.  The resulting file will have a ".mex###" extension, where
#     ### will be one of of the following to reflect the architecture of the
#     machine:
#
#       sol2, SunOS 5.x - sol
#       hp700 - hp7
#       ibm_rs - rs6
#       sgi - sg
#       sgi64 - sg64
#       alpha - axp
#       lnx86 - lx
#
#     The first file name given (less any file name extension) will be the
#     name of the resulting MEX file and will specify the source
#     language of the gateway routine.  Knowing this is sometimes
#     important to the script, as MATLAB will load one different entry
#     point symbols for C and Fortran.  Additional source, object, or
#     library files can be given to satisfy external references.  Both C
#     and Fortran source files can be specified when building a MEX file.
#
#     The behavior of this script is affected in two ways: an options file,
#     and command line options.
#
#     The name of the options file ($OPTSFILE_NAME) is currently
#     mexopts.sh.
#
#     The template options file can be found in matlab/bin/$OPTSFILE_NAME.
#     By default, the first occurrence of the file $OPTSFILE_NAME is
#     sourced from the following directory list: . (current),
#     $HOME/matlab, matlab/bin. The options file can be directly
#     specified using the -f optionsfile option, which overrides this 
#     search mechanism.  For more details consult the MATLAB API Guide.
#
#     The options are passed on to the C, Fortran or C++ compiler and
#     linker. The options specified by *OPTIMFLAGS and *DEBUGFLAGS are
#     special, in that they are controlled by the -g command line option;
#     if -g is passed, *DEBUGFLAGS will be passed but not *OPTIMFLAGS;
#     otherwise the reverse occurs.  There are separate such variables
#     for each source code compiler and the linker.
#
#  Options:
#
#     -argcheck
#           Add argument checking.  This will add code such that
#           arguments passed incorrectly to MATLAB API functions will
#           cause assertion failures.  Adds -DARGCHECK to the C
#           compiler flags, and adds $MATLAB/extern/src/mwdebug.c to
#           the list of source files.
#     -c
#           Compile only.  Creates an object file but not a mex file.
#     -Dname=[def]
#           Define a symbol name to the C preprocessor "cpp(1)".  Equivalent
#           to a #define directive in the source.
#     -f optionsfile
#           Options for the mex script can be specified in an options
#           file.  Ordinarily mex looks for a $OPTSFILE_NAME file in . ,
#           $HOME, or $MATLAB.  This option overrides the search
#           mechanism by specifying the options file directly.
#     -fortran
#           Specify that the gateway routine is in Fortran.  This will
#           override what the script normally assumes, which is that
#           the first source file in the list is the gateway routine.
#     -g
#           Create a debuggable MEX-file by including the debugging
#           flags listed in the options file.  There is one variable
#           for each type of source code which specifies compiler
#           flags, and one variable for linker flags.  This also
#           disables the optimization flag variables, unless -O is
#           also passed.
#     -Ipathname
#           Add "pathname" to the list of directories in which to search for
#           #include files with relative filenames (not beginning with slash
#           /).  The preprocessor first searches for #include files in the
#           directory containing "sourcefile", then in directories named
#           with -I options (if any), and finally, in system wide
#           directories such as /usr/include.
#     -llibrary
#           Link with object library "library" (for "ld(1)").
#     -Ldirectory
#           Add "directory" to the list of directories containing
#           object-library routines (for linking using "ld(1)").
#     -output resultname
#           Create MEX-function named <name> (an appropriate
#           MEX-file extension is automatically appended)
#     -O
#           Optimize the object code by including the optimization
#           flags listed in the options file.  There is one variable
#           for each type of source code which specifies compiler
#           flags, and one variable for linker flags.  This is done
#           by default, so this option is really only useful for
#           overriding the behavior of -g.
#     -setup optionsfile
#           Specify the compiler options file to use as default for future
#	    invocations of mex by placing it in $HOME/matlab. When this
#	    option is specified, no other command line input is accepted
#     -Uname
#           Remove any initial definition of the "cpp(1)" symbol "name".
#           (Inverse of the -D option.)
#     -V4
#           Compile a MATLAB 4 MEX-file.  This option is intended as an aid
#           to migration, and is not recommended as a permanent solution.
#     -v
#           Prints the values for important internal variables AFTER
#           $OPTSFILE_NAME is sourced and ALL arguments are considered. Prints
#           each compile step and final link step fully evaluated
#           to see which options and files were used. Very useful for
#           debugging.
#     name=[def]
#           Define a variable. The variable can be a string enclosed in
#           quotes. Be careful that the string cannot contain any interior
#           DOUBLE quotes. It overrides any variable already defined in
#           the script either by a default value, being set in the
#           $OPTSFILE_NAME file, or passed through the environment.
#
#  Examples:
#     The following command will compile "myprog.c" into "myprog.mex4" (when
#     run on a Sun-4):
#
#       mex myprog.c
#
#     When debugging, it is often useful to use "verbose" mode as well
#     as include symbolic debugging information:
#
#       mex -v -g myprog.c
#
#     To then recompile and link against "libmylib", you would use:
#
#       mex myprog.c -lmylib
#
#  Files:
#     $OPTSFILE_NAME,                     Mex options file that is
#     $HOME/$OPTSFILE_NAME,               source from from the first
#     matlab/bin/$OPTSFILE_NAME           file in the list. It allows
#                                         the user to set the values 
#                                         for important directories,
#                                         files, and environment
#                                         variables. See 
#                                         matlab/bin/$OPTSFILE_NAME 
#                                         for a template.
#     matlab/extern/include/mex.h         Header file for MEX files.
#     matlab/extern/lib/ibm_rs/exp.ibm_rs Text file containing a list of
#                                         symbols exported by MATLAB. Needed
#                                         for linking mex files on the
#                                         IBM/RS 6000.
#     matlab/extern/lib/sol2/mapfile      Map file to specify export
#                                         symbols on Solaris platform.
#
#  See Also:
#     MATLAB API Guide
#
# Copyright (c) 1984-1998 by The MathWorks, Inc.
# All Rights Reserved.
# $Revision: 1.71 $  $Date: 1998/10/13 16:37:37 $
#____________________________________________________________________________
    arg0_=$0
#
    abort='rm -f $files_to_remove $basename.o > /dev/null 2>&1; \
          echo ""; \
          echo "    mex:  interrupted."; \
          echo ""'
#
    trap "eval $abort; exit 1" 1 2 3 15
#
#============================================================================
#  FUNCTION DEFINITIONS
#============================================================================
#
#****************************************************************************
#
  cleanup () {
#
# Clean up temporary and intermediate files (usually in preparation
# for exiting)
#
    trap "eval $abort; exit 1" 1 2 3 15
    if [ -f $SO_LOCATIONS ]; then
        rm -f $SO_LOCATIONS > /dev/null 2>&1
    fi
    rm -f $files_to_remove > /dev/null 2>&1
    }
#   end cleanup ()
#
#****************************************************************************
#
  describe () {
#
    case "$1" in
        internal_error_1)
    echo ''
    echo 'Internal error 1: We could not determine the path of the'
    echo '                  MATLAB root directory.'
    echo ''
    echo "                  original command path = $arg0_"
    echo "                  current  command path = $filename"
    echo ''
    echo '                  Please contact:'
    echo '' 
    echo '                      MathWorks Technical Support'
    echo ''
    echo '                  for further assistance.'
    echo ''
            ;;
        internal_error_2)
    echo ''
    echo 'Internal error 2: Could not determine the path of the'
    echo '                  MATLAB root directory.'
    echo ''
    echo "                  original command path = $filename"
    echo "                  current  command path = $filename"
    echo ''
    echo '                  Please contact:'
    echo '' 
    echo '                      MathWorks Technical Support'
    echo ''
    echo '                  for further assistance.'
    echo ''
            ;;
        internal_error_3)
    echo ''
    echo 'Internal error 3: More than $maxlinks links in path to'
    echo "                  this script. That's too many!"
    echo ''
    echo "                  original command path = $filename"
    echo "                  current  command path = $filename"
    echo ''
    echo '                  Please contact:'
    echo '' 
    echo '                      MathWorks Technical Support'
    echo ''
    echo '                  for further assistance.'
    echo ''
            ;;        
        unknown_architecture)
    echo ''
    echo '    Sorry! We could not determine the machine architecture'
    echo '           for your host. Please contact:'
    echo ''
    echo '               MathWorks Technical Support'
    echo ''
    echo '           for further assistance.'
    echo ''
            ;;
        no_util_scripts)
    echo ''
    echo '    Sorry! We could not determine the machine architecture'
    echo '           for your host, because one of the utilities'
    echo ''
    echo '               $MATLAB/bin/util/arch.sh'
    echo ''
    echo '           or'
    echo ''
    echo '               $MATLAB/bin/util/oscheck.sh'
    echo ''
    echo '           could not be found. Please make sure that your'
    echo '           installation is not corrupted.  If you specified'
    echo '           the value of $MATLAB in the command line, please'
    echo '           make sure you specified the right value.'
    echo ''
    echo '           Here'
    echo ''
    echo "               MATLAB = $MATLAB"
    echo ''
    echo '           Please contact:'
    echo ''
    echo '               MathWorks Technical Support'
    echo ''
    echo '           if you need assistance.'
    echo ''
            ;;
        unknown_arch)
    echo ''
    echo "    mex:  machine architecture '$Arch' not supported."
    echo ''
            ;;
        invalid_options_file)
    echo ''
    echo '    Error: An invalid options file name was specified:'
    echo "           $2 is not a normal file or does not exist."
    echo ''
            ;;
        no_options_file)
    echo ''
    echo '    Sorry! No options file was found for mex.'
    echo '           The mex script must be able to source'
    echo '           an options file to define compiler flags'
    echo '           and other settings.  This options file'
    echo "           is normally found in MATLAB/bin/$OPTSFILE_NAME."
    echo '           Please check to make sure that your installation'
    echo '           is complete and includes this file.'
    echo ''
    echo '           Here'
    echo ''
    echo "               MATLAB = $MATLAB"
    echo ''
    echo '           Please contact:'
    echo ''
    echo '               MathWorks Technical Support'
    echo ''
    echo '           for further assistance.'
    echo ''
            ;;
        final_options)
            if [ "$SOURCE_DIR" = "none" ]; then
    echo '----------------------------------------------------------------'
    echo "-> options file specified on command line:"
    echo "   FILE = $OPTIONS_FILE"
            elif [ "$SOURCE_DIR" != "" ]; then
    echo "-> $OPTSFILE_NAME sourced from directory (DIR = $SOURCE_DIR)"
    echo "   FILE = $SOURCE_DIReval/$OPTSFILE_NAME"
            else
    echo "-> options file not found ($OPTSFILE_NAME looked for)."
            fi
    echo '----------------------------------------------------------------'
    echo "->    MATLAB                = $MATLAB"
    echo "->    CC                    = $CC"
    echo "->    CC flags:"
    echo "         CFLAGS             = $CFLAGS"
    echo "         CDEBUGFLAGS        = $CDEBUGFLAGS"
    echo "         COPTIMFLAGS        = $COPTIMFLAGS"
    echo "         CLIBS              = $CLIBS"
    echo "         arguments          = $cc_flags"
    echo "->    FC                    = $FC"
    echo "->    FC flags:"
    echo "         FFLAGS             = $FFLAGS"
    echo "         FDEBUGFLAGS        = $FDEBUGFLAGS"
    echo "         FOPTIMFLAGS        = $FOPTIMFLAGS"
    echo "         FLIBS              = $FLIBS"
    echo "         arguments          = $fc_flags"
    echo "->    LD                    = $LD"
    echo "->    Link flags:"
    echo "         LDFLAGS            = $LDFLAGS"
    echo "         LDDEBUGFLAGS       = $LDDEBUGFLAGS"
    echo "         LDOPTIMFLAGS       = $LDOPTIMFLAGS"
    echo "         arguments          = $libs"
    echo '----------------------------------------------------------------'
    echo ''
            ;;
        assuming_c_source)
    echo ''
    echo '    Warning: No source files in argument list.'
    echo ''
    echo '      Assuming C source code. To override this assumption, use'
    echo '      -fortran.'
    echo ''
            ;;
        meaningless_output_flag)
    echo ''
    echo '    Warning: -output ignored (no MEX-file is being created).'
    echo ''
            ;;
        assuming_matlab_5)
    echo '      Assuming fully MATLAB 5 compliant MEX-file.  To override'
    echo '      this assumption, use -V4.'
    echo ''
            ;;
        status)
    echo ""
    echo "    mex:  $stat"
            ;;
        help)
    echo ''
    echo 'MEX <options> <files> compiles a MEX-function from C or FORTRAN source code. '
    echo '   All non-source code file names passed as arguments are passed to the '
    echo '   linker without being compiled.'
    echo ' '
    echo '   Available options on all platforms are:'
    echo '   -argcheck        Add code to check validity of input arguments to'
    echo '                    MATLAB API functions (C functions only)'
    echo '   -c               Compile only; do not link'
    echo '   -D<name>[=<def>] Define preprocessor macro name <name> [as having value'
    echo '                    <def> (assignment not available under Windows)]'
    echo '   -f <file>        Use <file> as the options file; <file> is a full path '
    echo '                    name if not in current directory'
    echo '   -g               Build a MEX-function with debugging symbols included'
    echo '   -h[elp]          Help; print this message'
    echo '   -I<pathname>     Include <pathname> in the compiler include path'
    echo '   -O               Build an optimized MEX-function'
    echo '   -output <name>   Create MEX-function named <name> (an appropriate'
    echo '                    MEX-file extension is automatically appended)'
    echo '   -V4              Compile MATLAB 4 compatible MEX-file'
    echo '   -v               Verbose; print all compiler and linker settings'
    echo ' '
    echo '   On UNIX, the following options are available:'
    echo '   -l<file>         Link against library lib<file>'
    echo '   -L<pathname>     Include <pathname> in the list of directories to search '
    echo '                    for libraries'
    echo ' '
    echo '   -setup [optionsfile]'
    echo '                    Specify the compiler options file to use as'
    echo '                    default for future invocations of mex by'
    echo '                    placing it in $HOME/matlab.' 
    echo '                    When this option is specified, no other'
    echo '                    command line input is accepted' 
    echo ' '
    echo '   -U<name>         Undefine preprocessor macro name <name>'
    echo '   <name>=<def>     Override options file setting for variable <name>'
    echo ' '
    echo '   On Windows, the following options are available:'
    echo '   -U<name>         Undefine preprocessor macro name <name>'
    echo ' '
    echo "   MEX's execution is affected by both command-line arguments and"
    echo '   an options file.  The options file contains all compiler-specific '
    echo '   information necessary to create a MEX-function.  The default name for this'
    echo '   options file, if none is specified with the -f option, is "mexopts.bat" '
    echo '   (Windows), and "mexopts.sh" (UNIX).'
    echo ' '
    echo '   On UNIX, the options file is written in the Bourne shell script language.'
    echo '   The options file which occurs first in the following list is used: '
    echo '   ./mexopts.sh, $HOME/matlab/mexopts.sh, $MATLAB/bin/mexopts.sh.  Any '
    echo '   variable specified in the options file can be overridden at the command '
    echo '   line by use of the <name>=<def> command line argument.  If <def> has '
    echo '   spaces in it, then it should be wrapped in single quotes '
    echo "   (e.g. CFLAGS='opt1 opt2').  The definition can rely on other variables "
    echo '   defined in the options file; in this case the variable referenced should '
    echo "   have a prepended "'"$"'" (e.g. CFLAGS='"'$'"CFLAGS opt2')."
    echo ' '
    echo '   On Windows, the options file is written in the Perl script language.  The'
    echo '   options file, mexopts.bat, is searched for in the following directories:'
    echo '   the current directory first, then the same directory as "mex.bat".  No'
    echo '   arguments can have an embedded equal sign ("="); thus,'
    echo ''
    echo '      -DFOO     is valid, but'
    echo '      -DFOO=BAR is not.'
    echo ' '
            ;;
        usage)
    echo ""
    echo "    Usage: mex [ -argcheck -c -Dname[=def] -f optionsfile"
    echo "       -fortran -g -Ipathname -h[elp] -llibrary -Ldir"
    echo "       -output resultname -O -Uname -V4 -v"
    echo "       name=[def] ] sourcefile ... [ objectfile ... ]"
    echo "       [ library ... ]" 
    echo ""
    echo "    or: mex -setup [optionsfile]"
    echo ""
    echo "    Use the -help option for more information, or consult"
    echo "    the MATLAB API Guide manual."
    echo ""
            ;;
        file_not_found)
    echo ''
    echo "    mex:  $file not a normal file or does not exist."
    echo ''
            ;;
        compile_stage)
    echo "-> $compile_command"
    echo ''
            ;;
        ibm_preprocess)
            if [ "$TEMP" != "" -a "$compile_only" != "1" ]; then
    echo "-> cp -f $file $basename.F"
    echo "-> $CC -P $include_dirs $flags $basename.F"
    echo "-> rm -f $basename.F"
            else
    echo "-> $CC -P $include_dirs $flags $file"
            fi
    echo "-> mv -f $basename.i $basename.f"
    echo ''
            ;;
        failed_compile)
    echo ''
    echo "    mex: compile of '$file' failed."
    echo ''
            ;;
        dryrun)
    echo '################################################################'
    echo "-> output of 'dryrun' to help determine libraries for linking:"
    echo ''
    eval "   $dryrun_compiler $dryrunopts $objs $libs 2>&1"
    echo ''
    echo '################################################################'
    echo ''
            ;;
        link_stage)
    echo "-> $LD $LDFLAGS -o $mex_file $libetc"
    echo ''
            ;;
        solaris_linker_patch)
    echo ''
    echo '    The Solaris linker requires patch #102303-05.'
    echo '    This script has determined that your linker does'
    echo '    not have this patch; please install it.  For more'
    echo "    information run the 'matlabdoc' command at the UNIX"
    echo '    prompt and read Section 8.2 of the Appendix in'
    echo '    UNIX News for MATLAB 5.0.'
    echo ''
    echo 'Link stage not attempted.'
    echo ''
            ;;
        failed_link)
    echo ''
    echo "    mex: link of '$mex_file' failed."
    echo ''
            ;;
        *)
    echo ''
    echo " Internal error 4: unimplemented message $1"
    echo ''
            ;;
    esac
  }
# end describe ()
#
#****************************************************************************
#
  get_root_dir () {
#
#   Determine the path of the MATLAB root directory - always one directory
#   up from the path to this command.
#
    filename=$1
#
# Now it is either a file or a link to a file.
#
    cpath=`pwd`
#
# Follow up to 8 links before giving up. Same as BSD 4.3
#
    n=1
    maxlinks=8
    while [ $n -le $maxlinks ]
    do
#
# Get directory correctly!
#
        newdir=`echo "$filename" | awk '
                        { tail = $0
                          np = index (tail, "/")
                          while ( np != 0 ) {
                             tail = substr (tail, np + 1, length (tail) - np)
                             if (tail == "" ) break
                             np = index (tail, "/")
                          }
                          head = substr ($0, 1, length ($0) - length (tail))
                          if ( tail == "." || tail == "..")
                             print $0
                          else
                             print head
                        }'`
        if [ ! "$newdir" ]; then
            newdir="."
        fi
        (cd $newdir) > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            describe internal_error_1 >&2
            exit 1
        fi
        cd $newdir
#
# Need the function pwd - not the built in one
#
        newdir=`/bin/pwd`
#
        newbase=`expr //$filename : '.*/\(.*\)' \| $filename`
        lscmd=`ls -l $newbase 2>/dev/null`
        if [ ! "$lscmd" ]; then
            describe internal_error_2 >&2
            exit 1
        fi
#
# Check for link portably
#
        if [ `expr "$lscmd" : '.*->.*'` -ne 0 ]; then
            filename=`echo "$lscmd" | awk '{ print $NF }'`
        else
#
# It's a file
#
            dir="$newdir"
            command="$newbase"
#
            cd $dir/..
            MATLAB=`/bin/pwd`; export MATLAB
            break
        fi
        n=`expr $n + 1`
    done
    if [ $n -gt $maxlinks ]; then
        describe internal_error_3 >&2
        exit 1
    fi
#       
    cd $cpath
  }
#   end get_root_dir ()
#
#****************************************************************************
#
  get_entrypt () {
#
#   Set up the entry point based on the input argument
#
    if [ "$1" = "FORTRAN" ]; then
#
#   The gateway routine is in Fortran; use Fortran entry point
#
        MAPFILE='fexport.map'
        if [ "$Arch" = "hp700" ]; then
            ENTRYPOINT='mexfunction'
        elif [ "$Arch" != "ibm_rs" ]; then
            ENTRYPOINT='mexfunction_'
        else
            ENTRYPOINT='mexFunction'
        fi
    else
#
#   C and C++ entry points are the same
#
        MAPFILE='export.map'
        ENTRYPOINT='mexFunction'
    fi
  }
# end get_entrypt ()
#
#****************************************************************************
#
  determine_options_file () {
# Source options file (default is $OPTSFILE_NAME) and get values for the
# following local variables
# 
#       MATLAB                  (MATLAB root directory)
#       CC                      (C compiler)
#       CFLAGS                  (C compiler options)
#       COPTIMFLAGS             (Compiler optimization flags)
#       CDEBUGFLAGS             (Compiler debugging flags)
#       CLIBS                   (C libraries for linking)
#       FC                      (Fortran 77 compiler)
#       FFLAGS                  (Fortran 77 options)
#       FOPTIMFLAGS             (Compiler optimization flags)
#       FDEBUGFLAGS             (Compiler debugging flags)
#       FLIBS                   (Fortran libraries for linking)
#       LD                      (Linker command)
#       LDFLAGS                 (Linker options)
#       LDOPTIMFLAGS            (Compiler optimization flags)
#       LDDEBUGFLAGS            (Compiler debugging flags)
#
# The search order for the options file is:
#
#  -f optionsfile               (file specified with -f command line option)
#  ./$OPTSFILE_NAME             ($OPTSFILE_NAME in current directory)
#  $HOME/matlab/$OPTSFILE_NAME  ($OPTSFILE_NAME in user's matlab directory)
#  $MATLAB/bin/$OPTSFILE_NAME   ($OPTSFILE_NAME file in MATLAB bin directory)
#
#
    if [ -f ./$OPTSFILE_NAME ]; then
        SOURCE_DIR='.'
        SOURCE_DIReval=`pwd`
        OPTIONS_FILE="./$OPTSFILE_NAME"
    elif [ -f $HOME/matlab/$OPTSFILE_NAME ]; then
        SOURCE_DIR='$HOME/matlab'
        SOURCE_DIReval=$HOME/matlab
        OPTIONS_FILE="$HOME/matlab/$OPTSFILE_NAME"
    elif [ -f $MATLAB/bin/$OPTSFILE_NAME ]; then
#
# NOTE: At this point we will use the MATLAB determined earlier to
#       source the file. After that the value in that file if not
#       null will be used.
#
        SOURCE_DIR='$MATLAB/bin'
        SOURCE_DIReval=$MATLAB/bin
        OPTIONS_FILE="$MATLAB/bin/$OPTSFILE_NAME"
    else
        describe no_options_file >&2
        trap ""
        exit 1
    fi
  }
# end determine_options_file ()
#
#****************************************************************************
#
  get_arch () {
    if [ "$ARCH" = "" ]; then # No command line override given
	if [ ! -f $MATLAB/bin/util/arch.sh ]; then
	    describe no_util_scripts >&2
	    trap ""
	    exit 1
	fi
	. $MATLAB/bin/util/arch.sh
	if [ "$Arch" = "unknown" ]; then
	    describe unknown_architecture >&2
	    trap ""
	    exit 1
	fi
    else # Use command line override
	Arch=$ARCH
    fi
    if [ ! -f $MATLAB/bin/util/oscheck.sh ]; then
        describe no_util_scripts >&2
        trap ""
        exit 1
    fi
    if [ "$verbose" = "1" ]; then
        temp_file=/tmp/$$b
        files_to_remove="$files_to_remove $temp_file"
        . $MATLAB/bin/util/oscheck.sh
        if [ "$oscheck_status" = "1" ]; then
            cleanup
            exit 1
        fi
    fi
  }
# end get_arch ()
#
#****************************************************************************
#
  eval_assignments () {
#
# Source the file of argument variables, name=[def]
#
    if [ -f /tmp/$$a ]; then
        . /tmp/$$a
    fi
  }
# end eval_assignments ()
#
#****************************************************************************
#
  error_check () {
#
#   Check for errors in calling syntax
#
    if [ "$argcheck" = "1" -a "$cfiles" != "1" ]; then
        stat="Argument checking not possible without C source files."
    fi
    if [ "$argcheck" = "1" -a "$v4_compat" = "1" ]; then
        stat="Argument checking not available for V4 MEX-files."
    fi
    if [ "$inlined" = "1" -a "$cfiles" != "1" ]; then
        stat="Inlining not possible without C source files."
    fi
    if [ "$inlined" = "1" -a "$v4_compat" = "1" ]; then
        stat="Inlining not available for V4 MEX-files."
    fi
    if [ "$argcheck" = "1" -a "$inlined" = "1" ]; then
        stat="Argument checking and inlining are mutually exclusive."
    fi
    if [ "$files" != "" -a "$cfiles" != "1" -a "$ffiles" != "1" ]; then
        cfiles=1
	if [ "$verbose" != "" ]; then
	    describe assuming_c_source
	    if [ "$v4_compat" != "1" ]; then
		describe assuming_matlab_5
	    fi
	fi
    fi
    if [ "$stat" = "no file name given." -a "$verbose" = "1" ]; then
        # Exit quietly
        cleanup
        exit 0
    fi
    if [ "$stat" != "OK" ]; then                  # An error occurred.
        if [ "$stat" != "" ]; then
            describe status >&2
        fi
        describe usage >&2
        cleanup
        exit 1
    fi
  }
# end error_check ()
#
#****************************************************************************
#
  get_ext () {
#
#   Determine extension for MEX-file
#
        case "$Arch" in
            alpha)
                mex_ext='mexaxp'
                ;;
            hp700)
                mex_ext='mexhp7'
                ;;
            ibm_rs)
                mex_ext='mexrs6'
                ;;
            lnx86)
                mex_ext='mexlx'
                ;;
            sgi)
                mex_ext='mexsg'
                ;;
            sgi64)
                mex_ext='mexsg64'
                ;;
            sol2)
                mex_ext='mexsol'
                ;;
        esac
  }
# end get_ext ()
#
#****************************************************************************
#
  get_name () {
#
#   If there is already a mex name, -output was used: supply an appropriate
#   MEX-file extension if necessary. (Warn if -c was also used.)
#   Otherwise, use the first file name to determine the MEX-file name.
#   If there are no files, don't complain (error_check comes later).
#
    if [ "$mex_file" != "" ]; then
	if [ "$compile_only" = "1" ]; then
	    describe meaningless_output_flag
	fi
        ext=`expr "$mex_file" : ".*\.$mex_ext$"`
        if [ "$ext" = "0" ]; then
            mex_file=$mex_file.$mex_ext
        fi
    elif [ "$1" != "" ]; then
        ext=`expr "$1" : '\.*[^.].*\.\([^.]*\)$'`
        mex_file=`expr "//$1" : ".*/\(.*\)\.${ext}$" \| "//$1" : ".*/\(.*\)"`
	mex_file=$mex_file.$mex_ext
    fi
    if [ "$OUTDIR" != "" ]; then
	mex_file="$OUTDIR/$mex_file"
    fi
  }
# end get_name ()
#
#****************************************************************************
#
  get_includes () {
#
#   Determine which include directories to specify
#
    include_dirs="$include_dirs -I$MATLAB/$MEX_INCLUDE_DIR"
    if [ -d $MATLAB/simulink ]; then
        include_dirs="$include_dirs -I$MATLAB/simulink/include"
    fi
    if [ -d $MATLAB/codegen ]; then
        include_dirs="$include_dirs -I$MATLAB/codegen/external/common"
    fi
  }
# end get_includes ()
#
#****************************************************************************
#
  compile () {
    trap "eval $abort; exit 1" 1 2 3 15
#
#   For each file, compile source files and add other files
#   to the list of link options.
#
    file="$1"
    if [ ! -f "$file" ]; then
        describe file_not_found >&2
        cleanup
        exit 1
    fi
#
# determine extension and basename
#
    ext=`expr "$file" : '\.*[^.].*\.\([^.]*\)$'`
    if [ "$ext" = "" ]; then
        ext=`expr "$file" : '\.*[^.].*\.\(so\)[.0-9]*$'`
    fi
    basename=`expr "//$file" : ".*/\(.*\)\.${ext}$" \| //$file : ".*/\(.*\)"`
#
    if [ "$TEMP" != "" -a "$compile_only" != "1" ]; then
        basename=$TEMP/$basename$$
    elif [ "$OUTDIR" != "" ]; then
        basename=$OUTDIR/$basename
    fi
#
# Source file extensions: .c .C .cc .cxx .cpp .f .for .F
#
    case "$ext" in
        c | C | cc | cpp | cxx) # C/C++ source file.
#
# determine whether to optimize or debug
#
            if [ "$debug" != "1" ]; then
                flags="$COPTIMFLAGS"
            elif [ "$optimize" = "1" ]; then
                flags="$CDEBUGFLAGS $COPTIMFLAGS"
            else
                flags="$CDEBUGFLAGS"
            fi
#
# Determine final compile command for C source code.
#
            flags="-DMATLAB_MEX_FILE $CFLAGS $cc_flags $flags"
            compile_command="$CC -c $include_dirs $flags $file"
            ;;
        f | for | F)                   # Fortran source file.
#
# determine whether to optimize or debug
#
            if [ "$debug" != "1" ]; then
                flags="$FOPTIMFLAGS"
            elif [ "$optimize" = "1" ]; then
                flags="$FDEBUGFLAGS $FOPTIMFLAGS"
            else
                flags="$FDEBUGFLAGS"
            fi
#
# Determine final compile command for Fortran source code.
#
            flags="$FFLAGS $fc_flags $flags"
            if [ "$Arch" = "ibm_rs" -a "$ext" = "F" ]; then
                if [ "$verbose" = "1" ]; then
                    describe ibm_preprocess
                fi
                if [ "$TEMP" != "" -a "$compile_only" != "1" ]; then
                    CD=`pwd`
                    eval "cp -f $file $basename.F"
                    eval "cd $TEMP"
                    eval "$CC -P $include_dirs $flags $basename.F"
                    eval "cd $CD"
                    files_to_remove="$files_to_remove $basename.f $basename.F"
                else
                    eval "$CC -P $include_dirs $flags $file"
                fi
                eval "mv -f $basename.i $basename.f"
                file=$basename.f
            fi
            compile_command="$FC -c $include_dirs $flags $file"
#
# Using f2c/gcc for Fortran MEX requires appending gcc backend to the
# command line
# bmb 7/25/96
#
            if [ "$Arch" = "lnx86" -a "$FC" = "f2c" ]; then
                cc_file=`expr "//$file" : ".*/\(.*\)\.${ext}$" \| //$file : ".*/\(.*\)"`.c;
                compile_command="$compile_command; $CC -c $include_dirs $flags $cc_file"
	        files_to_remove="$files_to_remove $basename.c"
            fi
            ;;
        *)
#
# Object files: Don't need to do anything except add to compiled list
#
            objs="$objs $file"
            return 0
            ;;
    esac
#
    if [ "$TEMP" != "" -a "$compile_only" != "1" ]; then
        compile_command="$compile_command -o $basename.o"
    elif [ "$OUTDIR" != "" ]; then
        compile_command="$compile_command -o $basename.o"
    fi
#
    if [ "$verbose" = "1" ]; then
        describe compile_stage
    fi
#
    eval "$compile_command"
    if [ $? -ne 0 ]; then
        describe failed_compile >&2
	cleanup
        exit 1
    fi
    if [ "$compile_only" != "1" ]; then
        if [ "$Arch" = "sol2" -a "$debug" = "1" -a \
	     "$basename" != "$TEMP/mexversion$$" ]; then
            # We need to keep the object files around
            :
        else
            files_to_remove="$files_to_remove $basename.o"
        fi
    fi
    objs="$objs $basename.o"
  }
# end compile ()
#
#****************************************************************************
#
  link () {
    trap "eval $abort; exit 1" 1 2 3 15
#
#   Link stage
#
    if [ "$cfiles" = "1" ]; then
        libs="$libs $CLIBS"
    fi
    if [ "$ffiles" = "1" ]; then
        libs="$libs $FLIBS"
    fi
    libetc="$objs $libs"
#
# determine whether to optimize or debug
#
    if [ "$debug" != "1" ]; then
        LDFLAGS="$LDOPTIMFLAGS $LDFLAGS"
    elif [ "$optimize" = "1" ]; then
        LDFLAGS="$LDDEBUGFLAGS $LDOPTIMFLAGS $LDFLAGS"
    else
        LDFLAGS="$LDDEBUGFLAGS $LDFLAGS"
    fi
    case "$Arch" in
        alpha | sgi | sgi64)
            if [ "$TEMP" != "" ]; then
                SO_LOCATIONS=$TEMP/so_locations$$
                LDFLAGS="$LDFLAGS -update_registry $SO_LOCATIONS"
            fi
            ;;
        ibm_rs)
            if [ "$ffiles" = "1" ]; then
                LD=$FC
            fi
            ;;
        sol2)
#
# The mechanism for defining which symbols to export or hide is
# the ld -Wmapfile option.  For Solaris 2.4 this requires patch
# 102303-05.
#
            patched=`showrev -p | grep -c '102303-05'`
            osversion=`uname -r`
            if [ "$osversion" = '5.4' ]; then
                if [ ! "$patched" = '1' ]; then
                    describe solaris_linker_patch >&2
                    trap ""
                    exit 1
                fi
            fi
            ;;
    esac
    if [ "$verbose" = "1" ]; then
        describe link_stage
    fi
    eval "$LD $LDFLAGS $ld_flags -o $mex_file $libetc"
    if [ $? -ne 0 ]; then
        describe failed_link >&2
        cleanup
        exit 1
    fi
  }
# end link ()
#
#****************************************************************************
#
# Main routine
#
#
#  Initialize some variables
#
    OPTSFILE_NAME='mexopts.sh'
#
    MEX_INCLUDE_DIR='extern/include'
#
    SO_LOCATIONS=so_locations
#
    stat="OK"
    ARCH=
    Arch='Undetermined'
    verbose=0
#
#  Use a C entry point by default
#
    gateway_lang=C
#
    arg_count=$#
    while [ "$stat" = "OK" -a  $# -gt 0 ]; do
#
# Parse input arguments.  The routine may need the next two arguments,
# as in -f optionsfile and -o mexfilename.
#
        case "$1" in
            -argcheck)
                argcheck=1
                cc_flags="$cc_flags -DARGCHECK"
                ;;
            -c)
                compile_only=1
                ;;
            -[DU]*)                         # Compiler flags.
                cc_flags="$cc_flags $1"
                fc_flags="$fc_flags $1"
                if [ "$1" = "-DV4_COMPAT" ]; then
                    stat="Please use -V4 rather than directly passing"
                    stat="$stat -DV4_COMPAT."
                fi
                if [ "$1" = "-DARRAY_ACCESS_INLINING" ]; then
                    stat="Please use -inline rather than directly passing"
                    stat="$stat -DARRAY_ACCESS_INLINING."
                fi
                ;;
            -I*)                            # Include directories
                include_dirs="$include_dirs $1"
                ;;
            -f)
                if [ -f "$2" ]; then
                    OPTIONS_FILE="$2"
                    SOURCE_DIR='none'
                else
                    describe invalid_options_file >& 2
                    exit 1
                fi
                shift
                ;;
            -fortran)
                ffiles=1
                gateway_lang=FORTRAN
                ;;
            -[g]*)                          # Use debugging flags.
                debug=1
                ;;
            -h | -help)                     # -help: Help option.
                describe "help"
                cleanup
                exit 0
                ;;
            -inline)
                cc_flags="$cc_flags -DARRAY_ACCESS_INLINING"
                inlined=1
                ;;
            -[Ll]*)
                libs="$libs $1"
                ;;
            -o | -output)                   # mexfile name - undocumented
                mex_file=$2
                shift
                ;;
            -outdir)                        # output directory - undocumented
                OUTDIR=$2
                shift
                ;;
            -O)                             # Use optimization flags.
                optimize=1
                ;;
            -setup)
		if [ $arg_count -ne 2 -a $arg_count -ne 1 ]; then
		    describe usage >&2
		    trap ""
		    exit 1
		else
		    SETUP_OPTIONS_FILE=$2
		    if [ ! "$MATLAB" ]; then       # If no MATLAB='' was used
			get_root_dir $arg0_
		    fi
		    TMW_ROOT=$MATLAB
		    #
		    # source the setup_options_file finction declaration  
		    #
		    . $MATLAB/bin/optsetup.sh
		    #
		    setup_options_file $SETUP_OPTIONS_FILE
		    trap ""
		    exit 0
		fi
                ;;
            -silent)            # really not verbose - undocumented
                verbose=
                ;;
            -v)
                verbose=1
                ;;
            -v3.5)
                stat="The -v3.5 option is no longer supported."
                ;;
            -V4)
                cc_flags="$cc_flags -DV4_COMPAT"
                v4_compat=1
                ;;
            -*)
                stat="$1 not a valid option."
                ;;
            ARCH=*)
                rhs=`expr "$1" : '[a-zA-Z0-9_]*=\(.*\)$'`
                ARCH="`eval echo $rhs`"
                ;;
            MATLAB=*)
                mlrhs=`expr "$1" : '[a-zA-Z0-9_]*=\(.*\)$'`
                MATLAB="`eval echo $mlrhs`"
                ;;
            *=*)
                lhs=`expr "$1" : '\([a-zA-Z0-9_]*\)=.*'`
                rhs=`expr "$1" : '[a-zA-Z0-9_]*=\(.*\)$'`
                echo $lhs='"'$rhs'"' >> /tmp/$$a
                files_to_remove="$files_to_remove /tmp/$$a"
                ;;
            *.c | *.C | *.cc | *.cpp | *.cxx) # C/C++ source file.
                cfiles='1'
                files="$files $1"
                ;;
            *.f | *.for | *.F)                # FORTRAN source file.
                if [ "$ffiles" != "1" -a "$cfiles" != "1" ]; then
                    gateway_lang=FORTRAN
                fi
                ffiles='1'
                files="$files $1"
                ;;
            *.o)                              # object files
                files="$files $1"
                ;;
            *)                                # other files
                libs="$libs $1"
                ;;
        esac
    shift
    done
    if [ $# -eq 0 -a "$files" = "" -a "$stat" = "OK" ]; then
        stat="no file name given."
    fi
#
# It is now safe to use functions, since we have parsed all of the
# input arguments.  (The use of functions corrupts $# and $* on
# HP-UX 9.0x systems.)
#
    if [ ! "$MATLAB" ]; then            # If no MATLAB='' was used
        get_root_dir $arg0_
    fi
#
    if [ ! "$OPTIONS_FILE" ]; then      # If no -f optionsfile was used
        determine_options_file
    fi
#
    . $OPTIONS_FILE                     # Source file to determine $MATLAB
    get_arch                            # Call $MATLAB/bin/util/arch.sh
#
    get_ext                             # Determine MEX-file extension
    get_name $files                     # Determine MEX-file name
    get_entrypt $gateway_lang           # Determine MEX-file entry pt
#
    . $OPTIONS_FILE                     # Source options file
#
    eval_assignments                    # Evaluate VAR=value arguments
    if [ "$verbose" = "1" ]; then
        describe final_options
    fi
#
    error_check                         # Check calling syntax errors
#
    get_includes                        # Determine include directories
#
    if [ "$compile_only" != "1" ]; then
	if [ "$gateway_lang" = "C" ]; then
	    files="$files $MATLAB/extern/src/mexversion.c"
	else
	    files="$files $MATLAB/extern/lib/$Arch/version4.o"
	fi
    fi
    if [ "$argcheck" = "1" ]; then
        files="$files $MATLAB/extern/src/mwdebug.c"
    fi
#
# From this point on, we need to put traps in each function.  The IBM
# resets traps on entry to each function, so we need to safeguard
# any functions we call after compiling.  This includes compile(),
# link(), and cleanup().
#
    set $files
    for file in $*
    do
        compile $file                   # Process each file in list
    done
#
    if [ "$compile_only" != "1" ]; then
        link                            # Perform linking
    fi
#
    cleanup
    exit 0
#
#****************************************************************************
