Add Fortran 90/95 support. (Chris Murray)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 29 Jul 2004 13:22:43 +0000 (13:22 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 29 Jul 2004 13:22:43 +0000 (13:22 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1008 fdb21ef1-2011-0410-befe-b5e4ea1792b1

30 files changed:
doc/man/scons.1
src/CHANGES.txt
src/engine/MANIFEST.in
src/engine/SCons/Defaults.py
src/engine/SCons/Scanner/Fortran.py
src/engine/SCons/Scanner/FortranTests.py
src/engine/SCons/Tool/__init__.py
src/engine/SCons/Tool/as.py
src/engine/SCons/Tool/bcc32.py
src/engine/SCons/Tool/c++.py
src/engine/SCons/Tool/cc.py
src/engine/SCons/Tool/cvf.py [new file with mode: 0644]
src/engine/SCons/Tool/dmd.py
src/engine/SCons/Tool/f77.py
src/engine/SCons/Tool/f90.py [new file with mode: 0644]
src/engine/SCons/Tool/f95.py [new file with mode: 0644]
src/engine/SCons/Tool/fortran.py [new file with mode: 0644]
src/engine/SCons/Tool/g77.py
src/engine/SCons/Tool/masm.py
src/engine/SCons/Tool/msvc.py
src/engine/SCons/Tool/nasm.py
src/engine/SCons/Util.py
test/BuildDir.py
test/CPPFLAGS.py
test/F77.py [deleted file]
test/F77FLAGS.py [deleted file]
test/F77PATH.py [deleted file]
test/FORTRANSUFFIXES.py [deleted file]
test/SHF77.py [deleted file]
test/SHF77FLAGS.py [deleted file]

index 35a1619f0a64dd3a444878c68c771078099ec2ab..c9fed7ae9f49f9ed5b137fa2eb76e85600765a92 100644 (file)
@@ -990,10 +990,14 @@ as
 bcc32
 c++
 cc
+cvf
 dmd
 dvipdf
 dvips
 f77
+f90
+f95
+fortran
 g++
 g77
 gas
@@ -4218,7 +4222,8 @@ User-specified C preprocessor options.
 These will be included in any command that uses the C preprocessor,
 including not just compilation of C and C++ source files
 via the $CCCOM, $SHCCCOM, $CXXCOM and $SHCXXCOM command lines,
-but also the $F77PPCOM and $SHF77PPCOM command lines
+but also the $FORTRANPPCOM, $SHFORTRANPPCOM,
+$F77PPCOM and $SHF77PPCOM command lines
 used to compile a Fortran source file,
 and the $ASPPCOM command line
 used to assemble an assembly language source file,
@@ -4438,13 +4443,23 @@ command lines. The function should take one argument: the command line
 string to escape; and should return the escaped command line.
 
 .IP F77
-The Fortran compiler.
-
-.IP F77COM 
-The command line used to compile a Fortran source file to an object file.
+The Fortran 77 compiler.
+You should normally set the $FORTRAN variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $F77 if you need to use a specific compiler
+or compiler version for Fortran 77 files.
+
+.IP F77COM
+The command line used to compile a Fortran 77 source file to an object file.
+You only need to set $F77COM if you need to use a specific
+command line for Fortran 77 files.
+You should normally set the $FORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
 
 .IP F77FLAGS
-General user-specified options that are passed to the Fortran compiler.
+General user-specified options that are passed to the Fortran 77 compiler.
 Note that this variable does
 .I not
 contain
@@ -4455,10 +4470,16 @@ See
 .BR _F77INCFLAGS ,
 below,
 for the variable that expands to those options.
+You only need to set $F77FLAGS if you need to define specific
+user options for Fortran 77 files.
+You should normally set the $FORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
 
 .IP _F77INCFLAGS
 An automatically-generated construction variable
-containing the Fortran compiler command-line options
+containing the Fortran 77 compiler command-line options
 for specifying directories to be searched for include files.
 The value of $_F77INCFLAGS is created
 by appending $INCPREFIX and $INCSUFFIX
@@ -4466,22 +4487,28 @@ to the beginning and end
 of each directory in $F77PATH.
 
 .IP F77PATH
-The list of directories that the Fortran compiler will search for include
-directories. The Fortran implicit dependency scanner will search these
+The list of directories that the Fortran 77 compiler will search for include
+directories. The implicit dependency scanner will search these
 directories for include files. Don't explicitly put include directory
-arguments in F77FLAGS because the result will be non-portable
+arguments in $F77FLAGS because the result will be non-portable
 and the directories will not be searched by the dependency scanner. Note:
-directory names in F77PATH will be looked-up relative to the SConscript
-directory when they are used in a command. To force 
+directory names in $F77PATH will be looked-up relative to the SConscript
+directory when they are used in a command. To force
 .B scons
 to look-up a directory relative to the root of the source tree use #:
+You only need to set $F77PATH if you need to define a specific
+include path for Fortran 77 files.
+You should normally set the $FORTRANPATH variable,
+which specifies the include path
+for the default Fortran compiler
+for all Fortran versions.
 
 .ES
 env = Environment(F77PATH='#/include')
 .EE
 
 .IP
-The directory look-up can also be forced using the 
+The directory look-up can also be forced using the
 .BR Dir ()
 function:
 
@@ -4509,20 +4536,373 @@ include $_F77INCFLAGS:
 env = Environment(F77COM="my_compiler $_F77INCFLAGS -c -o $TARGET $SOURCE")
 .EE
 
-.IP F77PPCOM 
-The command line used to compile a Fortran source file to an object file
+.IP F77PPCOM
+The command line used to compile a Fortran 77 source file to an object file
 after first running the file through the C preprocessor.
 Any options specified in the $F77FLAGS and $CPPFLAGS construction variables
 are included on this command line.
+You only need to set $F77PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 77 files.
+You should normally set the $FORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP F90
+The Fortran 90 compiler.
+You should normally set the $FORTRAN variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $F90 if you need to use a specific compiler
+or compiler version for Fortran 90 files.
+
+.IP F90COM
+The command line used to compile a Fortran 90 source file to an object file.
+You only need to set $F90COM if you need to use a specific
+command line for Fortran 90 files.
+You should normally set the $FORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
+
+.IP F90FLAGS
+General user-specified options that are passed to the Fortran 90 compiler.
+Note that this variable does
+.I not
+contain
+.B -I
+(or similar) include search path options
+that scons generates automatically from $F90PATH.
+See
+.BR _F90INCFLAGS ,
+below,
+for the variable that expands to those options.
+You only need to set $F90FLAGS if you need to define specific
+user options for Fortran 90 files.
+You should normally set the $FORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
+
+.IP _F90INCFLAGS
+An automatically-generated construction variable
+containing the Fortran 90 compiler command-line options
+for specifying directories to be searched for include files.
+The value of $_F90INCFLAGS is created
+by appending $INCPREFIX and $INCSUFFIX
+to the beginning and end
+of each directory in $F90PATH.
+
+.IP F90PATH
+The list of directories that the Fortran 90 compiler will search for include
+directories. The implicit dependency scanner will search these
+directories for include files. Don't explicitly put include directory
+arguments in $F90FLAGS because the result will be non-portable
+and the directories will not be searched by the dependency scanner. Note:
+directory names in $F90PATH will be looked-up relative to the SConscript
+directory when they are used in a command. To force
+.B scons
+to look-up a directory relative to the root of the source tree use #:
+You only need to set $F90PATH if you need to define a specific
+include path for Fortran 90 files.
+You should normally set the $FORTRANPATH variable,
+which specifies the include path
+for the default Fortran compiler
+for all Fortran versions.
+
+.ES
+env = Environment(F90PATH='#/include')
+.EE
+
+.IP
+The directory look-up can also be forced using the
+.BR Dir ()
+function:
+
+.ES
+include = Dir('include')
+env = Environment(F90PATH=include)
+.EE
+
+.IP
+The directory list will be added to command lines
+through the automatically-generated
+$_F90INCFLAGS
+construction variable,
+which is constructed by
+appending the values of the
+$INCPREFIX and $INCSUFFIX
+construction variables
+to the beginning and end
+of each directory in $F90PATH.
+Any command lines you define that need
+the F90PATH directory list should
+include $_F90INCFLAGS:
+
+.ES
+env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE")
+.EE
+
+.IP F90PPCOM
+The command line used to compile a Fortran 90 source file to an object file
+after first running the file through the C preprocessor.
+Any options specified in the $F90FLAGS and $CPPFLAGS construction variables
+are included on this command line.
+You only need to set $F90PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 90 files.
+You should normally set the $FORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP F95
+The Fortran 95 compiler.
+You should normally set the $FORTRAN variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $F95 if you need to use a specific compiler
+or compiler version for Fortran 95 files.
+
+.IP F95COM
+The command line used to compile a Fortran 95 source file to an object file.
+You only need to set $F95COM if you need to use a specific
+command line for Fortran 95 files.
+You should normally set the $FORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
+
+.IP F95FLAGS
+General user-specified options that are passed to the Fortran 95 compiler.
+Note that this variable does
+.I not
+contain
+.B -I
+(or similar) include search path options
+that scons generates automatically from $F95PATH.
+See
+.BR _F95INCFLAGS ,
+below,
+for the variable that expands to those options.
+You only need to set $F95FLAGS if you need to define specific
+user options for Fortran 95 files.
+You should normally set the $FORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
+
+.IP _F95INCFLAGS
+An automatically-generated construction variable
+containing the Fortran 95 compiler command-line options
+for specifying directories to be searched for include files.
+The value of $_F95INCFLAGS is created
+by appending $INCPREFIX and $INCSUFFIX
+to the beginning and end
+of each directory in $F95PATH.
+
+.IP F95PATH
+The list of directories that the Fortran 95 compiler will search for include
+directories. The implicit dependency scanner will search these
+directories for include files. Don't explicitly put include directory
+arguments in $F95FLAGS because the result will be non-portable
+and the directories will not be searched by the dependency scanner. Note:
+directory names in $F95PATH will be looked-up relative to the SConscript
+directory when they are used in a command. To force
+.B scons
+to look-up a directory relative to the root of the source tree use #:
+You only need to set $F95PATH if you need to define a specific
+include path for Fortran 95 files.
+You should normally set the $FORTRANPATH variable,
+which specifies the include path
+for the default Fortran compiler
+for all Fortran versions.
+
+.ES
+env = Environment(F95PATH='#/include')
+.EE
+
+.IP
+The directory look-up can also be forced using the
+.BR Dir ()
+function:
+
+.ES
+include = Dir('include')
+env = Environment(F95PATH=include)
+.EE
+
+.IP
+The directory list will be added to command lines
+through the automatically-generated
+$_F95INCFLAGS
+construction variable,
+which is constructed by
+appending the values of the
+$INCPREFIX and $INCSUFFIX
+construction variables
+to the beginning and end
+of each directory in $F95PATH.
+Any command lines you define that need
+the F95PATH directory list should
+include $_F95INCFLAGS:
+
+.ES
+env = Environment(F95COM="my_compiler $_F95INCFLAGS -c -o $TARGET $SOURCE")
+.EE
+
+.IP F95PPCOM
+The command line used to compile a Fortran 95 source file to an object file
+after first running the file through the C preprocessor.
+Any options specified in the $F95FLAGS and $CPPFLAGS construction variables
+are included on this command line.
+You only need to set $F95PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 95 files.
+You should normally set the $FORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP FORTRAN
+The default Fortran compiler
+for all versions of Fortran.
+
+.IP FORTRANCOM 
+The command line used to compile a Fortran source file to an object file.
+By default, any options specified
+in the $FORTRANFLAGS, $CPPFLAGS, $_CPPDEFFLAGS, 
+$_FORTRANMODFLAG, and $_FORTRANINCFLAGS construction variables
+are included on this command line.
+
+.IP FORTRANFLAGS
+General user-specified options that are passed to the Fortran compiler.
+Note that this variable does
+.I not
+contain
+.B -I
+(or similar) include or module search path options
+that scons generates automatically from $FORTRANPATH.
+See
+.BR _FORTRANINCFLAGS and _FORTRANMODFLAGS,
+below,
+for the variables that expand those options.
+
+.IP _FORTRANINCFLAGS
+An automatically-generated construction variable
+containing the Fortran compiler command-line options
+for specifying directories to be searched for include 
+files and module files.
+The value of $_FORTRANINCFLAGS is created
+by prepending/appending $INCPREFIX and $INCSUFFIX
+to the beginning and end
+of each directory in $FORTRANPATH.
+
+.IP FORTRANMODDIR
+Directory location where the Fortran compiler should place
+any module files it generates.  This variable is empty, by default. Some 
+Fortran compilers will internally append this directory in the search path 
+for module files, as well
+
+.IP FORTRANMODDIRPREFIX
+The prefix used to specify a module directory on the Fortran compiler command
+line.
+This will be appended to the beginning of the directory
+in the $FORTRANMODDIR construction variables
+when the $_FORTRANMODFLAG variables is automatically generated.
+
+.IP FORTRANMODDIRSUFFIX
+The suffix used to specify a module directory on the Fortran compiler command
+line.
+This will be appended to the beginning of the directory
+in the $FORTRANMODDIR construction variables
+when the $_FORTRANMODFLAG variables is automatically generated.
+
+.IP FORTRANMODFLAG
+An automatically-generated construction variable
+containing the Fortran compiler command-line option
+for specifying the directory location where the Fortran
+compiler should place any module files that happen to get 
+generated during compilation.
+The value of $_FORTRANMODFLAG is created
+by prepending/appending $FORTRANMODDIRPREFIX and $FORTRANMODDIRSUFFIX
+to the beginning and end of the directory in $FORTRANMODDIR.
+
+.IP FORTRANMODPREFIX
+The module file prefix used by the Fortran compiler.  SCons assumes that
+the Fortran compiler follows the quasi-standard naming convention for
+module files of
+.I <module_name>.mod.
+As a result, this variable is left empty, by default.  For situations in
+which the compiler does not necessarily follow the normal convention,
+the user may use this variable.  Its value will be appended to every
+module file name as scons attempts to resolve dependencies.
+
+.IP FORTRANMODSUFFIX
+The module file suffix used by the Fortran compiler.  SCons assumes that
+the Fortran compiler follows the quasi-standard naming convention for
+module files of
+.I <module_name>.mod.
+As a result, this variable is set to ".mod", by default.  For situations
+in which the compiler does not necessarily follow the normal convention,
+the user may use this variable.  Its value will be appended to every
+module file name as scons attempts to resolve dependencies.
+
+.IP FORTRANPATH
+The list of directories that the Fortran compiler will search for
+include files and (for some compilers) module files. The Fortran implicit
+dependency scanner will search these directories for include files (but
+not module files since they are autogenerated and, as such, may not
+actually exist at the time the scan takes place). Don't explicitly put
+include directory arguments in FORTRANFLAGS because the result will be
+non-portable and the directories will not be searched by the dependency
+scanner. Note: directory names in FORTRANPATH will be looked-up relative
+to the SConscript directory when they are used in a command. To force
+.B scons
+to look-up a directory relative to the root of the source tree use #:
+
+.ES
+env = Environment(FORTRANPATH='#/include')
+.EE
+
+.IP
+The directory look-up can also be forced using the 
+.BR Dir ()
+function:
+
+.ES
+include = Dir('include')
+env = Environment(FORTRANPATH=include)
+.EE
+
+.IP
+The directory list will be added to command lines
+through the automatically-generated
+$_FORTRANINCFLAGS
+construction variable,
+which is constructed by
+appending the values of the
+$INCPREFIX and $INCSUFFIX
+construction variables
+to the beginning and end
+of each directory in $FORTRANPATH.
+Any command lines you define that need
+the FORTRANPATH directory list should
+include $_FORTRANINCFLAGS:
+
+.ES
+env = Environment(FORTRANCOM="my_compiler $_FORTRANINCFLAGS -c -o $TARGET $SOURCE")
+.EE
+
+.IP FORTRANPPCOM 
+The command line used to compile a Fortran source file to an object file
+after first running the file through the C preprocessor. 
+By default, any options specified in the $FORTRANFLAGS, $CPPFLAGS,
+_CPPDEFFLAGS, $_FORTRANMODFLAG, and $_FORTRANINCFLAGS
+construction variables are included on this command line.
 
 .IP FORTRANSUFFIXES
 The list of suffixes of files that will be scanned
 for Fortran implicit dependencies
-(INCLUDE lines).
+(INCLUDE lines & USE statements).
 The default list is:
 
 .ES
-[".f", ".F", ".for", ".FOR"]
+[".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
+".f77", ".F77", ".f90", ".F90", ".f95", ".F95"]
 .EE
 
 .IP File
@@ -4553,16 +4933,16 @@ The default list is:
 The prefix used to specify an include directory on the C compiler command
 line.
 This will be appended to the beginning of each directory
-in the $CPPPATH and $F77PATH construction variables
-when the $_CPPINCFLAGS and $_F77INCFLAGS
+in the $CPPPATH and $FORTRANPATH construction variables
+when the $_CPPINCFLAGS and $_FORTRANINCFLAGS
 variables are automatically generated.
 
 .IP INCSUFFIX
 The suffix used to specify an include directory on the C compiler command
 line.
 This will be appended to the end of each directory
-in the $CPPPATH and $F77PATH construction variables
-when the $_CPPINCFLAGS and $_F77INCFLAGS
+in the $CPPPATH and $FORTRANPATH construction variables
+when the $_CPPINCFLAGS and $_FORTRANINCFLAGS
 variables are automatically generated.
 
 .IP INSTALL
@@ -5336,22 +5716,140 @@ See the
 construction variable for more information.
 
 .IP SHF77
-The Fortran compiler used for generating shared-library objects.
+The Fortran 77 compiler used for generating shared-library objects.
+You should normally set the $SHFORTRANC variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $SHF77 if you need to use a specific compiler
+or compiler version for Fortran 77 files.
 
 .IP SHF77COM
-The command line used to compile a Fortran source file
+The command line used to compile a Fortran 77 source file
 to a shared-library object file.
+You only need to set $SHF77COM if you need to use a specific
+command line for Fortran 77 files.
+You should normally set the $SHFORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
 
 .IP SHF77FLAGS
-Options that are passed to the Fortran compiler
+Options that are passed to the Fortran 77 compiler
 to generated shared-library objects.
+You only need to set $SHF77FLAGS if you need to define specific
+user options for Fortran 77 files.
+You should normally set the $SHFORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
 
 .IP SHF77PPCOM
-The command line used to compile a Fortran source file to a
+The command line used to compile a Fortran 77 source file to a
 shared-library object file
 after first running the file through the C preprocessor.
 Any options specified in the $SHF77FLAGS and $CPPFLAGS construction variables
 are included on this command line.
+You only need to set $SHF77PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 77 files.
+You should normally set the $SHFORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP SHF90
+The Fortran 90 compiler used for generating shared-library objects.
+You should normally set the $SHFORTRANC variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $SHF90 if you need to use a specific compiler
+or compiler version for Fortran 90 files.
+
+.IP SHF90COM
+The command line used to compile a Fortran 90 source file
+to a shared-library object file.
+You only need to set $SHF90COM if you need to use a specific
+command line for Fortran 90 files.
+You should normally set the $SHFORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
+
+.IP SHF90FLAGS
+Options that are passed to the Fortran 90 compiler
+to generated shared-library objects.
+You only need to set $SHF90FLAGS if you need to define specific
+user options for Fortran 90 files.
+You should normally set the $SHFORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
+
+.IP SHF90PPCOM
+The command line used to compile a Fortran 90 source file to a
+shared-library object file
+after first running the file through the C preprocessor.
+Any options specified in the $SHF90FLAGS and $CPPFLAGS construction variables
+are included on this command line.
+You only need to set $SHF90PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 90 files.
+You should normally set the $SHFORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP SHF95
+The Fortran 95 compiler used for generating shared-library objects.
+You should normally set the $SHFORTRANC variable,
+which specifies the default Fortran compiler
+for all Fortran versions.
+You only need to set $SHF95 if you need to use a specific compiler
+or compiler version for Fortran 95 files.
+
+.IP SHF95COM
+The command line used to compile a Fortran 95 source file
+to a shared-library object file.
+You only need to set $SHF95COM if you need to use a specific
+command line for Fortran 95 files.
+You should normally set the $SHFORTRANCOM variable,
+which specifies the default command line
+for all Fortran versions.
+
+.IP SHF95FLAGS
+Options that are passed to the Fortran 95 compiler
+to generated shared-library objects.
+You only need to set $SHF95FLAGS if you need to define specific
+user options for Fortran 95 files.
+You should normally set the $SHFORTRANFLAGS variable,
+which specifies the user-specified options
+passed to the default Fortran compiler
+for all Fortran versions.
+
+.IP SHF95PPCOM
+The command line used to compile a Fortran 95 source file to a
+shared-library object file
+after first running the file through the C preprocessor.
+Any options specified in the $SHF95FLAGS and $CPPFLAGS construction variables
+are included on this command line.
+You only need to set $SHF95PPCOM if you need to use a specific
+C-preprocessor command line for Fortran 95 files.
+You should normally set the $SHFORTRANPPCOM variable,
+which specifies the default C-preprocessor command line
+for all Fortran versions.
+
+.IP SHFORTRAN
+The default Fortran compiler used for generating shared-library objects.
+
+.IP SHFORTRANCOM
+The command line used to compile a Fortran source file
+to a shared-library object file.
+
+.IP SHFORTRANFLAGS
+Options that are passed to the Fortran compiler
+to generate shared-library objects.
+
+.IP SHFORTRANPPCOM
+The command line used to compile a Fortran source file to a
+shared-library object file
+after first running the file through the C preprocessor.
+Any options specified
+in the $SHFORTRANFLAGS and $CPPFLAGS construction variables
+are included on this command line.
 
 .IP SHLIBPREFIX
 The prefix used for shared library file names.
index 73c70475924001207087320d5d216f4a17c1b17d..6626a9043f3fa1011d6bae3dd5d91ed8f086f98a 100644 (file)
@@ -147,6 +147,12 @@ RELEASE 0.96 - XXX
   - Fix escaping file names on command lines when the expansion is
     concatenated with another string.
 
+  - Add support for Fortran 90 and Fortran 95.  This adds $FORTRAN*
+    variables that specify a default compiler, command-line, flags,
+    etc. for all Fortran versions, plus separate $F90* and $F95*
+    variables for when different compilers/flags/etc. must be specified
+    for different Fortran versions.
+
   From Gary Oberbrunner:
 
   - Add a --debug=presub option to print actions prior to substitution.
index 1b8a06fa3fcc9fc125831a655fb76ea7f461bc4e..4480713cec40bd207c9231cf4d7a40b8eb2b7f42 100644 (file)
@@ -59,12 +59,16 @@ SCons/Tool/bcc32.py
 SCons/Tool/BitKeeper.py
 SCons/Tool/c++.py
 SCons/Tool/cc.py
+SCons/Tool/cvf.py
 SCons/Tool/CVS.py
 SCons/Tool/dmd.py
 SCons/Tool/default.py
 SCons/Tool/dvipdf.py
 SCons/Tool/dvips.py
 SCons/Tool/f77.py
+SCons/Tool/f90.py
+SCons/Tool/f95.py
+SCons/Tool/fortran.py
 SCons/Tool/g++.py
 SCons/Tool/g77.py
 SCons/Tool/gas.py
index fb3669a00211cab1d91bee197fb3f97880a32de8..8100869a737cf96297036abc300556b30296e95e 100644 (file)
@@ -49,7 +49,6 @@ import SCons.Builder
 import SCons.Environment
 import SCons.Scanner.C
 import SCons.Scanner.D
-import SCons.Scanner.Fortran
 import SCons.Scanner.Prog
 import SCons.Sig
 
@@ -115,13 +114,6 @@ DSuffixes = ['.d']
 for suffix in DSuffixes:
     ObjSourceScan.add_scanner(suffix, DScan)
 
-FortranScan = SCons.Scanner.Fortran.FortranScan()
-
-FortranSuffixes = [".f", ".F", ".for", ".FOR"]
-
-for suffix in FortranSuffixes:
-    ObjSourceScan.add_scanner(suffix, FortranScan)
-
 IDLSuffixes = [".idl", ".IDL"]
 
 # cleanup
@@ -134,11 +126,6 @@ ShCAction = SCons.Action.Action("$SHCCCOM")
 CXXAction = SCons.Action.Action("$CXXCOM")
 ShCXXAction = SCons.Action.Action("$SHCXXCOM")
 
-F77Action = SCons.Action.Action("$F77COM")
-ShF77Action = SCons.Action.Action("$SHF77COM")
-F77PPAction = SCons.Action.Action("$F77PPCOM")
-ShF77PPAction = SCons.Action.Action("$SHF77PPCOM")
-
 ASAction = SCons.Action.Action("$ASCOM")
 ASPPAction = SCons.Action.Action("$ASPPCOM")
 
@@ -235,7 +222,7 @@ def _concat(prefix, list, suffix, env, f=lambda x: x):
     element in the list using the 'env' dictionary and then calling f
     on the list, and finally concatenating 'prefix' and 'suffix' onto
     each element of the list. A trailing space on 'prefix' or leading
-    space on 'suffix' will cause them to be put into seperate list
+    space on 'suffix' will cause them to be put into separate list
     elements rather than being concatenated."""
     
     if not list:
@@ -347,7 +334,6 @@ ConstructionEnvironment = {
     'SCANNERS'   : [],
     'CPPSUFFIXES': CSuffixes,
     'DSUFFIXES'  : DSuffixes,
-    'FORTRANSUFFIXES': FortranSuffixes,
     'IDLSUFFIXES': IDLSuffixes,
     'PDFPREFIX'  : '',
     'PDFSUFFIX'  : '.pdf',
@@ -361,7 +347,6 @@ ConstructionEnvironment = {
     '_LIBFLAGS'    : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
     '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs)} $)',
     '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)',
-    '_F77INCFLAGS' : '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs)} $)',
     '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
     'TEMPFILE'     : NullCmdGenerator
     }
index 9e9a990fae70d9a0fbc3335253b1da498da1fb95..786d4ab45e08b0f997d00b299e80e87967800c70 100644 (file)
@@ -1,6 +1,6 @@
 """SCons.Scanner.Fortran
 
-This module implements the dependency scanner for Fortran code. 
+This module implements the dependency scanner for Fortran code.
 
 """
 
@@ -29,18 +29,266 @@ This module implements the dependency scanner for Fortran code.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
+import re
+import string
+
 import SCons.Node
 import SCons.Node.FS
 import SCons.Scanner
 import SCons.Util
 import SCons.Warnings
 
-def FortranScan(fs = SCons.Node.FS.default_fs):
+class F90Scanner(SCons.Scanner.Classic):
+    """
+    A Classic Scanner subclass for Fortran source files which takes
+    into account both USE and INCLUDE statements.  This scanner will
+    work for both F77 and F90 (and beyond) compilers.
+
+    Currently, this scanner assumes that the include files do not contain
+    USE statements.  To enable the ability to deal with USE statements
+    in include files, add logic right after the module names are found
+    to loop over each include file, search for and locate each USE
+    statement, and append each module name to the list of dependencies.
+    Caching the search results in a common dictionary somewhere so that
+    the same include file is not searched multiple times would be a
+    smart thing to do.
+    """
+
+    def __init__(self, name, suffixes, path_variable, use_regex,
+                 incl_regex, fs=SCons.Node.FS.default_fs, *args, **kw):
+
+        self.cre_use = re.compile(use_regex, re.M)
+        self.cre_incl = re.compile(incl_regex, re.M)
+        self.fs = fs
+
+        def _scan(node, env, path, self=self, fs=fs):
+            return self.scan(node, env, path)
+
+        kw['function'] = _scan
+        kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable, fs)
+        kw['recursive'] = 1
+        kw['skeys'] = suffixes
+        kw['name'] = name
+
+        apply(SCons.Scanner.Current.__init__, (self,) + args, kw)
+
+    def scan(self, node, env, path=()):
+        node = node.rfile()
+
+        if not node.exists():
+            return []
+
+        # cache the includes list in node so we only scan it once:
+        if node.includes != None:
+            mods_and_includes = node.includes
+        else:
+            # retrieve all included filenames
+            includes = self.cre_incl.findall(node.get_contents())
+            # retrieve all USE'd module names
+            modules = self.cre_use.findall(node.get_contents())
+
+            # Convert module name to a .mod filename
+            suffix = env.subst('$FORTRANMODSUFFIX')
+            modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+            # Remove unique items from the list
+            mods_and_includes = SCons.Util.unique(includes+modules)
+            node.includes = mods_and_includes
+
+        nodes = []
+        source_dir = node.get_dir()
+        for dep in mods_and_includes:
+            n, i = self.find_include(dep, source_dir, path)
+
+            if not n is None:
+                nodes.append(n)
+            else:
+                SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
+                                    "No dependency generated for file: %s (referenced by: %s) -- file not found" % (i, node))
+
+        #  Sort the list of dependencies
+
+        # Schwartzian transform from the Python FAQ Wizard
+        def st(List, Metric):
+            def pairing(element, M = Metric):
+                return (M(element), element)
+            def stripit(pair):
+                return pair[1]
+            paired = map(pairing, List)
+            paired.sort()
+            return map(stripit, paired)
+
+        def normalize(node):
+            # We don't want the order of includes to be
+            # modified by case changes on case insensitive OSes, so
+            # normalize the case of the filename here:
+            # (see test/win32pathmadness.py for a test of this)
+            return SCons.Node.FS._my_normcase(str(node))
+
+        # Apply a Schwartzian transform to return the list of
+        # dependencies, sorted according to their normalized names
+        transformed = st(nodes, normalize)
+#        print "ClassicF90: " + str(node) + " => " + str(map(lambda x: str(x),list(transformed)))
+        return transformed
+
+
+def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
     """Return a prototype Scanner instance for scanning source files
-    for Fortran INCLUDE statements"""
-    scanner = SCons.Scanner.Classic("FortranScan",
-                                    "$FORTRANSUFFIXES",
-                                    "F77PATH",
-                                    "(?i)INCLUDE[ \t]+'([\\w./\\\\]+)'",
-                                    fs = fs)
+    for Fortran USE & INCLUDE statements"""
+
+#   The USE statement regex matches the following:
+#
+#   USE module_name
+#   USE :: module_name
+#   USE, INTRINSIC :: module_name
+#   USE, NON_INTRINSIC :: module_name
+#
+#   Limitations
+#
+#   --  While the regex can handle multiple USE statements on one line,
+#       it cannot properly handle them if they are commented out.
+#       In either of the following cases:
+#
+#            !  USE mod_a ; USE mod_b         [entire line is commented out]
+#               USE mod_a ! ; USE mod_b       [in-line comment of second USE statement]
+#
+#       the second module name (mod_b) will be picked up as a dependency
+#       even though it should be ignored.  The only way I can see
+#       to rectify this would be to modify the scanner to eliminate
+#       the call to re.findall, read in the contents of the file,
+#       treating the comment character as an end-of-line character
+#       in addition to the normal linefeed, loop over each line,
+#       weeding out the comments, and looking for the USE statements.
+#       One advantage to this is that the regex passed to the scanner
+#       would no longer need to match a semicolon.
+#
+#   --  I question whether or not we need to detect dependencies to
+#       INTRINSIC modules because these are built-in to the compiler.
+#       If we consider them a dependency, will SCons look for them, not
+#       find them, and kill the build?  Or will we there be standard
+#       compiler-specific directories we will need to point to so the
+#       compiler and SCons can locate the proper object and mod files?
+
+#   Here is a breakdown of the regex:
+#
+#   (?i)               : regex is case insensitive
+#   ^                  : start of line
+#   (?:                : group a collection of regex symbols without saving the match as a "group"
+#      ^|;             : matches either the start of the line or a semicolon - semicolon
+#   )                  : end the unsaved grouping
+#   \s*                : any amount of white space
+#   USE                : match the string USE, case insensitive
+#   (?:                : group a collection of regex symbols without saving the match as a "group"
+#      \s+|            : match one or more whitespace OR ....  (the next entire grouped set of regex symbols)
+#      (?:             : group a collection of regex symbols without saving the match as a "group"
+#         (?:          : establish another unsaved grouping of regex symbols
+#            \s*          : any amount of white space
+#            ,         : match a comma
+#            \s*       : any amount of white space
+#            (?:NON_)? : optionally match the prefix NON_, case insensitive
+#            INTRINSIC : match the string INTRINSIC, case insensitive
+#         )?           : optionally match the ", INTRINSIC/NON_INTRINSIC" grouped expression
+#         \s*          : any amount of white space
+#         ::           : match a double colon that must appear after the INTRINSIC/NON_INTRINSIC attribute
+#      )               : end the unsaved grouping
+#   )                  : end the unsaved grouping
+#   \s*                : match any amount of white space
+#   (\w+)              : match the module name that is being USE'd
+#
+#
+    use_regex = "(?i)(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"
+
+
+#   The INCLUDE statement regex matches the following:
+#
+#   INCLUDE 'some_Text'
+#   INCLUDE "some_Text"
+#   INCLUDE "some_Text" ; INCLUDE "some_Text"
+#   INCLUDE kind_"some_Text"
+#   INCLUDE kind_'some_Text"
+#
+#   where some_Text can include any alphanumeric and/or special character
+#   as defined by the Fortran 2003 standard.
+#
+#   Limitations:
+#
+#   --  The Fortran standard dictates that a " or ' in the INCLUDE'd
+#       string must be represented as a "" or '', if the quotes that wrap
+#       the entire string are either a ' or ", respectively.   While the
+#       regular expression below can detect the ' or " characters just fine,
+#       the scanning logic, presently is unable to detect them and reduce
+#       them to a single instance.  This probably isn't an issue since,
+#       in practice, ' or " are not generally used in filenames.
+#
+#   --  This regex will not properly deal with multiple INCLUDE statements
+#       when the entire line has been commented out, ala
+#
+#           ! INCLUDE 'some_file' ; INCLUDE 'some_file'
+#
+#       In such cases, it will properly ignore the first INCLUDE file,
+#       but will actually still pick up the second.  Interestingly enough,
+#       the regex will properly deal with these cases:
+#
+#             INCLUDE 'some_file'
+#             INCLUDE 'some_file' !; INCLUDE 'some_file'
+#
+#       To get around the above limitation, the FORTRAN programmer could
+#       simply comment each INCLUDE statement separately, like this
+#
+#           ! INCLUDE 'some_file' !; INCLUDE 'some_file'
+#
+#       The way I see it, the only way to get around this limitation would
+#       be to modify the scanning logic to replace the calls to re.findall
+#       with a custom loop that processes each line separately, throwing
+#       away fully commented out lines before attempting to match against
+#       the INCLUDE syntax.
+#
+#   Here is a breakdown of the regex:
+#
+#   (?i)               : regex is case insensitive
+#   (?:                : begin a non-saving group that matches the following:
+#      ^               :    either the start of the line
+#      |               :                or
+#      ['">]\s*;       :    a semicolon that follows a single quote,
+#                           double quote or greater than symbol (with any
+#                           amount of whitespace in between).  This will
+#                           allow the regex to match multiple INCLUDE
+#                           statements per line (although it also requires
+#                           the positive lookahead assertion that is
+#                           used below).  It will even properly deal with
+#                           (i.e. ignore) cases in which the additional
+#                           INCLUDES are part of an in-line comment, ala
+#                                           "  INCLUDE 'someFile' ! ; INCLUDE 'someFile2' "
+#   )                  : end of non-saving group
+#   \s*                : any amount of white space
+#   INCLUDE            : match the string INCLUDE, case insensitive
+#   \s+                : match one or more white space characters
+#   (?\w+_)?           : match the optional "kind-param _" prefix allowed by the standard
+#   [<"']              : match the include delimiter - an apostrophe, double quote, or less than symbol
+#   (.+?)              : match one or more characters that make up
+#                        the included path and file name and save it
+#                        in a group.  The Fortran standard allows for
+#                        any non-control character to be used.  The dot
+#                        operator will pick up any character, including
+#                        control codes, but I can't conceive of anyone
+#                        putting control codes in their file names.
+#                        The question mark indicates it is non-greedy so
+#                        that regex will match only up to the next quote,
+#                        double quote, or greater than symbol
+#   (?=["'>])          : positive lookahead assertion to match the include
+#                        delimiter - an apostrophe, double quote, or
+#                        greater than symbol.  This level of complexity
+#                        is required so that the include delimiter is
+#                        not consumed by the match, thus allowing the
+#                        sub-regex discussed above to uniquely match a
+#                        set of semicolon-separated INCLUDE statements
+#                        (as allowed by the F2003 standard)
+
+    include_regex = """(?i)(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+
+    scanner = F90Scanner("FortranScan",
+                         "$FORTRANSUFFIXES",
+                         path_variable,
+                         use_regex,
+                         include_regex,
+                         fs = fs)
     return scanner
index 766f0ee6eaf1da2e7b64ff5dc65510308fe105b9..b7e527ce1ff67364b312056ecc7eaaf31425e6f6 100644 (file)
@@ -134,19 +134,90 @@ test.write([ 'repository', 'src', 'ccc.f'], """
 
 test.write([ 'repository', 'src', 'ddd.f'], "\n")
 
+
+test.write('fff90a.f90',"""
+      PROGRAM FOO
+
+!  Test comments - these includes should NOT be picked up
+C     INCLUDE 'fi.f'
+#     INCLUDE 'fi.f'
+  !   INCLUDE 'fi.f'
+
+      INCLUDE 'f1.f'  ! in-line comments are valid syntax
+      INCLUDE"fi.f"   ! space is significant - this should be ignored
+      INCLUDE  <f2.f>  ! Absoft compiler allows greater than/less than delimiters
+!
+!  Allow kind type parameters
+      INCLUDE kindType_"f3.f"
+      INCLUDE kind_Type_"f4.f"
+!
+!  Test multiple statements per line - use various spacings between semicolons
+      incLUDE 'f5.f';include "f6.f"  ;  include <f7.f>; include 'f8.f' ;include kindType_'f9.f'
+!
+!  Test various USE statement syntaxes
+!
+      USE Mod01
+      use mod02
+      use use
+      USE mOD03, ONLY : someVar
+      USE MOD04 ,only:someVar
+      USE Mod05 , ONLY: someVar ! in-line comment
+      USE Mod06,ONLY :someVar,someOtherVar
+
+      USE  mod07;USE  mod08; USE mod09 ;USE mod10 ; USE mod11  ! Test various semicolon placements
+      use mod12 ;use mod13! Test comment at end of line
+
+!     USE modi
+!     USE modia ; use modib    ! Scanner regexp will only ignore the first - this is a deficiency in the regexp
+    ! USE modic ; ! use modid  ! Scanner regexp should ignore both modules
+      USE mod14 !; USE modi    ! Only ignore the second
+      USE mod15!;USE modi
+      USE mod16  !  ;  USE  modi
+
+!  Test semicolon syntax - use various spacings
+      USE :: mod17
+      USE::mod18
+      USE ::mod19 ; USE:: mod20
+
+      use, non_intrinsic :: mod21, ONLY : someVar ; use,intrinsic:: mod22
+      USE, NON_INTRINSIC::mod23 ; USE ,INTRINSIC ::mod24
+
+USE mod25  ! Test USE statement at the beginning of line
+
+
+; USE modi   ! Scanner should ignore this since it isn't valid syntax
+      USEmodi   ! No space in between USE and module name - ignore it
+      USE mod01   ! This one is a duplicate - there should only be one dependency to it.
+
+      STOP
+      END
+""")
+
+modules = ['mod01.mod', 'mod02.mod', 'mod03.mod', 'mod04.mod', 'mod05.mod',
+           'mod06.mod', 'mod07.mod', 'mod08.mod', 'mod09.mod', 'mod10.mod',
+           'mod11.mod', 'mod12.mod', 'mod13.mod', 'mod14.mod', 'mod15.mod',
+           'mod16.mod', 'mod17.mod', 'mod18.mod', 'mod19.mod', 'mod20.mod',
+           'mod21.mod', 'mod22.mod', 'mod23.mod', 'mod24.mod', 'mod25.mod']
+
+for m in modules:
+    test.write(m, "\n")
+
+test.subdir('modules')
+test.write(['modules', 'use.mod'], "\n")
+
 # define some helpers:
 
 class DummyEnvironment:
     def __init__(self, listCppPath):
         self.path = listCppPath
-        
+
     def Dictionary(self, *args):
         if not args:
-            return { 'F77PATH': self.path }
-        elif len(args) == 1 and args[0] == 'F77PATH':
+            return { 'FORTRANPATH': self.path, 'FORTRANMODSUFFIX' : ".mod" }
+        elif len(args) == 1 and args[0] == 'FORTRANPATH':
             return self.path
         else:
-            raise KeyError, "Dummy environment only has F77PATH attribute."
+            raise KeyError, "Dummy environment only has FORTRANPATH attribute."
 
     def has_key(self, key):
         return self.Dictionary().has_key(key)
@@ -161,6 +232,8 @@ class DummyEnvironment:
         del self.Dictionary()[key]
 
     def subst(self, arg):
+        if arg[0] == '$':
+            return self[arg[1:]]
         return arg
 
     def subst_path(self, path):
@@ -274,7 +347,7 @@ class FortranScannerTestCase8(unittest.TestCase):
         headers =  ['d1/d2/f2.f', 'd1/f2.f', 'f2.f']
         deps_match(self, deps, map(test.workpath, headers))
         test.unlink('f2.f')
-        
+
 class FortranScannerTestCase9(unittest.TestCase):
     def runTest(self):
         test.write('f3.f', "\n")
@@ -290,11 +363,11 @@ class FortranScannerTestCase9(unittest.TestCase):
         setattr(n, 'rexists', my_rexists)
 
         deps = s(n, env, path)
-        
+
         # Make sure rexists() got called on the file node being
         # scanned, essential for cooperation with BuildDir functionality.
         assert n.rexists_called
-        
+
         headers =  ['d1/f3.f', 'f3.f']
         deps_match(self, deps, map(test.workpath, headers))
         test.unlink('f3.f')
@@ -334,7 +407,7 @@ class FortranScannerTestCase11(unittest.TestCase):
 
         # Did we catch the warning from not finding not_there.f?
         assert to.out
-        
+
         deps_match(self, deps, [ 'f5.f' ])
 
 class FortranScannerTestCase12(unittest.TestCase):
@@ -402,6 +475,42 @@ class FortranScannerTestCase15(unittest.TestCase):
         deps_match(self, deps, map(test.workpath, headers))
         test.write(['d1', 'f2.f'], "\n")
 
+class FortranScannerTestCase16(unittest.TestCase):
+    def runTest(self):
+        test.write('f1.f', "\n")
+        test.write('f2.f', "\n")
+        test.write('f3.f', "\n")
+        test.write('f4.f', "\n")
+        test.write('f5.f', "\n")
+        test.write('f6.f', "\n")
+        test.write('f7.f', "\n")
+        test.write('f8.f', "\n")
+        test.write('f9.f', "\n")
+        test.write('f10.f', "\n")
+        env = DummyEnvironment([test.workpath('modules')])
+        s = SCons.Scanner.Fortran.FortranScan()
+        path = s.path(env)
+        fs = SCons.Node.FS.FS(original)
+        deps = s(make_node('fff90a.f90', fs), env, path)
+        headers = ['f1.f', 'f2.f', 'f3.f', 'f4.f', 'f5.f', 'f6.f', 'f7.f', 'f8.f', 'f9.f']
+        modules = ['mod01.mod', 'mod02.mod', 'mod03.mod', 'mod04.mod', 'mod05.mod',
+                   'mod06.mod', 'mod07.mod', 'mod08.mod', 'mod09.mod', 'mod10.mod',
+                   'mod11.mod', 'mod12.mod', 'mod13.mod', 'mod14.mod', 'mod15.mod',
+                   'mod16.mod', 'mod17.mod', 'mod18.mod', 'mod19.mod', 'mod20.mod',
+                   'mod21.mod', 'mod22.mod', 'mod23.mod', 'mod24.mod', 'mod25.mod', 'modules/use.mod']
+        deps_expected = headers + modules
+        deps_match(self, deps, map(test.workpath, deps_expected))
+        test.unlink('f1.f')
+        test.unlink('f2.f')
+        test.unlink('f3.f')
+        test.unlink('f4.f')
+        test.unlink('f5.f')
+        test.unlink('f6.f')
+        test.unlink('f7.f')
+        test.unlink('f8.f')
+        test.unlink('f9.f')
+        test.unlink('f10.f')
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(FortranScannerTestCase1())
@@ -419,6 +528,7 @@ def suite():
     suite.addTest(FortranScannerTestCase13())
     suite.addTest(FortranScannerTestCase14())
     suite.addTest(FortranScannerTestCase15())
+    suite.addTest(FortranScannerTestCase16())
     return suite
 
 if __name__ == "__main__":
index 5753bb92b7b07044aefc4426414fde59c5c7e276..53d288e030b0f8a655bb035dad800162f50676c6 100644 (file)
@@ -6,7 +6,7 @@ This looks for modules that define a callable object that can modify
 a construction environment as appropriate for a given tool (or tool
 chain).
 
-Note that because this subsysem just *selects* a callable that can
+Note that because this subsystem just *selects* a callable that can
 modify a construction environment, it's possible for people to define
 their own "tool specification" in an arbitrary callable function.  No
 one needs to use or tie in to this subsystem in order to roll their own
@@ -170,26 +170,24 @@ def createObjBuilders(env):
         static_obj = env['BUILDERS']['StaticObject']
     except KeyError:
         static_obj = SCons.Builder.Builder(action = {},
-                                           emitter = "$OBJEMITTER",
+                                           emitter = {},
                                            prefix = '$OBJPREFIX',
                                            suffix = '$OBJSUFFIX',
                                            src_builder = ['CFile', 'CXXFile'],
                                            source_scanner = SCons.Defaults.ObjSourceScan, single_source=1)
         env['BUILDERS']['StaticObject'] = static_obj
         env['BUILDERS']['Object'] = static_obj
-        env['OBJEMITTER'] = SCons.Defaults.StaticObjectEmitter
 
     try:
         shared_obj = env['BUILDERS']['SharedObject']
     except KeyError:
         shared_obj = SCons.Builder.Builder(action = {},
-                                           emitter = "$SHOBJEMITTER",
+                                           emitter = {},
                                            prefix = '$SHOBJPREFIX',
                                            suffix = '$SHOBJSUFFIX',
                                            src_builder = ['CFile', 'CXXFile'],
                                            source_scanner = SCons.Defaults.ObjSourceScan, single_source=1)
         env['BUILDERS']['SharedObject'] = shared_obj
-        env['SHOBJEMITTER'] = SCons.Defaults.SharedObjectEmitter
 
     return (static_obj, shared_obj)
 
@@ -251,7 +249,7 @@ def tool_list(platform, env):
         c_compilers = ['msvc', 'mingw', 'gcc', 'icl', 'icc', 'cc', 'bcc32' ]
         cxx_compilers = ['msvc', 'icc', 'g++', 'c++', 'bcc32' ]
         assemblers = ['masm', 'nasm', 'gas', '386asm' ]
-        fortran_compilers = ['g77', 'ifl']
+        fortran_compilers = ['g77', 'ifl', 'cvf', 'fortran']
         ars = ['mslib', 'ar', 'tlib']
     elif str(platform) == 'os2':
         "prefer IBM tools on OS/2"
@@ -267,7 +265,7 @@ def tool_list(platform, env):
         c_compilers = ['sgicc', 'gcc', 'cc']
         cxx_compilers = ['sgic++', 'g++', 'c++']
         assemblers = ['as', 'gas']
-        fortran_compilers = ['f77', 'g77']
+        fortran_compilers = ['f77', 'g77', 'fortran']
         ars = ['sgiar']
     elif str(platform) == 'sunos':
         "prefer Forte tools on SunOS"
@@ -275,7 +273,7 @@ def tool_list(platform, env):
         c_compilers = ['suncc', 'gcc', 'cc']
         cxx_compilers = ['sunc++', 'g++', 'c++']
         assemblers = ['as', 'gas']
-        fortran_compilers = ['f77', 'g77']
+        fortran_compilers = ['f77', 'g77', 'fortran']
         ars = ['sunar']
     elif str(platform) == 'hpux':
         "prefer aCC tools on HP-UX"
@@ -283,7 +281,7 @@ def tool_list(platform, env):
         c_compilers = ['hpcc', 'gcc', 'cc']
         cxx_compilers = ['hpc++', 'g++', 'c++']
         assemblers = ['as', 'gas']
-        fortran_compilers = ['f77', 'g77']
+        fortran_compilers = ['f77', 'g77', 'fortran']
         ars = ['ar']
     elif str(platform) == 'aix':
         "prefer AIX Visual Age tools on AIX"
@@ -291,7 +289,7 @@ def tool_list(platform, env):
         c_compilers = ['aixcc', 'gcc', 'cc']
         cxx_compilers = ['aixc++', 'g++', 'c++']
         assemblers = ['as', 'gas']
-        fortran_compilers = ['aixf77', 'g77']
+        fortran_compilers = ['aixf77', 'g77', 'fortran']
         ars = ['ar']
     else:
         "prefer GNU tools on all other platforms"
@@ -299,7 +297,7 @@ def tool_list(platform, env):
         c_compilers = ['gcc', 'msvc', 'icc', 'cc']
         cxx_compilers = ['g++', 'msvc', 'icc', 'c++']
         assemblers = ['gas', 'nasm', 'masm']
-        fortran_compilers = ['g77', 'ifl']
+        fortran_compilers = ['g77', 'ifl', 'fortran']
         ars = ['ar', 'mslib']
 
     c_compiler = FindTool(c_compilers, env) or c_compilers[0]
index 6cd4184dbfe66d41b8f57441efa46de0f569814d..2bbc8917b216ce4e457064d759e5a423e9cfeff8 100644 (file)
@@ -52,9 +52,11 @@ def generate(env):
 
     for suffix in ASSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
 
     for suffix in ASPPSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
 
     env['AS']        = env.Detect(assemblers) or 'as'
     env['ASFLAGS']   = SCons.Util.CLVar('')
index 6d3acca2181035594db47c4d25be1c29a8a51d37..f891d45c09e15e4bed4a522067c1d036ab5d7078 100644 (file)
@@ -58,6 +58,9 @@ def generate(env):
     for suffix in ['.c', '.cpp']:
         static_obj.add_action(suffix, SCons.Defaults.CAction)
         shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+
     env['CC']        = 'bcc32'
     env['CCFLAGS']   = SCons.Util.CLVar('')
     env['CCCOM']     = '$CC -q $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
index 8e0adfae55093d52bbd752af5d9c04ca79c8205b..10bb1ac7e9fc9da9401113dcd4c5a736296d9ed5 100644 (file)
@@ -65,6 +65,8 @@ def generate(env):
     for suffix in CXXSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.CXXAction)
         shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
         
     env['CXX']        = 'c++'
     env['CXXFLAGS']   = SCons.Util.CLVar('$CCFLAGS')
index 4c19c69068c9553dbeb330ee419c9a821dc82c9b..56c723dd28d7824f9e7e109800e230b253c40151 100644 (file)
@@ -49,6 +49,8 @@ def generate(env):
     for suffix in CSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.CAction)
         shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
         
     env['CC']        = 'cc'
     env['CCFLAGS']   = SCons.Util.CLVar('')
diff --git a/src/engine/SCons/Tool/cvf.py b/src/engine/SCons/Tool/cvf.py
new file mode 100644 (file)
index 0000000..15db1da
--- /dev/null
@@ -0,0 +1,53 @@
+"""engine.SCons.Tool.cvf
+
+Tool-specific initialization for the Compaq Visual Fortran compiler.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Util
+import fortran
+
+compilers = ['f90']
+
+def generate(env):
+    """Add Builders and construction variables for compaq visual fortran to an Environment."""
+
+    fortran.generate(env)
+
+    env['FORTRAN']        = 'f90'
+    env['FORTRANCOM']     = '$FORTRAN $FORTRANFLAGS $_FORTRANMODODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
+    env['FORTRANPPCOM']   = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
+    env['SHFORTRANCOM']   = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANMODODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
+    env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
+    env['OBJSUFFIX']      = '.obj'
+    env['FORTRANMODDIR'] = '${TARGET.dir}'
+    env['FORTRANMODDIRPREFIX'] = '/module:'
+    env['FORTRANMODDIRSUFFIX'] = ''
+
+def exists(env):
+    return env.Detect(compilers)
index 758ed7333ff94e1ce7e1dd084f4d9031520eee2b..5d773c31b2d0eb3d0b82cb82d37d7f118be94027 100644 (file)
@@ -61,6 +61,7 @@ import string
 import SCons.Tool
 import SCons.Scanner.D
 import SCons.Builder
+import SCons.Defaults
 
 # Adapted from c++.py
 def isD(source):
@@ -86,6 +87,8 @@ def generate(env):
 
     static_obj.add_action('.d', '$DCOM')
     shared_obj.add_action('.d', '$DCOM')
+    static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
+    shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
 
     env['DC'] = 'dmd'
     env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES'
index f05a410e4f4e107dc209eb4e56bda9a597c662bf..0651585cc0755e6d1ac1f21a719ef669d4039857 100644 (file)
@@ -34,38 +34,80 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import SCons.Defaults
+import SCons.Scanner.Fortran
 import SCons.Tool
 import SCons.Util
+import fortran
 
 compilers = ['f77']
 
-F77Suffixes = ['.f', '.for', '.FOR']
-F77PPSuffixes = ['.fpp', '.FPP']
-if SCons.Util.case_sensitive_suffixes('.f', '.F'):
-    F77PPSuffixes.append('.F')
+#
+F77Action = SCons.Action.Action("$F77COM")
+ShF77Action = SCons.Action.Action("$SHF77COM")
+F77PPAction = SCons.Action.Action("$F77PPCOM")
+ShF77PPAction = SCons.Action.Action("$SHF77PPCOM")
+
+#
+F77Suffixes = ['.f77']
+F77PPSuffixes = []
+if SCons.Util.case_sensitive_suffixes('.f77', '.F77'):
+    F77PPSuffixes.append('.F77')
 else:
-    F77Suffixes.append('.F')
+    F77Suffixes.append('.F77')
 
-def generate(env):
+#
+F77Scan = SCons.Scanner.Fortran.FortranScan("F77PATH")
+
+for suffix in F77Suffixes + F77PPSuffixes:
+    SCons.Defaults.ObjSourceScan.add_scanner(suffix, F77Scan)
+
+#
+F77Generator = fortran.VariableListGenerator('F77', 'FORTRAN', '_FORTRAND')
+F77FlagsGenerator = fortran.VariableListGenerator('F77FLAGS', 'FORTRANFLAGS')
+ShF77Generator = fortran.VariableListGenerator('SHF77', 'SHFORTRAN', 'F77', 'FORTRAN', '_FORTRAND')
+ShF77FlagsGenerator = fortran.VariableListGenerator('SHF77FLAGS', 'SHFORTRANFLAGS')
+
+def add_to_env(env):
     """Add Builders and construction variables for f77 to an Environment."""
+    env.AppendUnique(FORTRANSUFFIXES = F77Suffixes + F77PPSuffixes)
+
     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
 
     for suffix in F77Suffixes:
-        static_obj.add_action(suffix, SCons.Defaults.F77Action)
-        shared_obj.add_action(suffix, SCons.Defaults.ShF77Action)
+        static_obj.add_action(suffix, F77Action)
+        shared_obj.add_action(suffix, ShF77Action)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
 
     for suffix in F77PPSuffixes:
-        static_obj.add_action(suffix, SCons.Defaults.F77PPAction)
-        shared_obj.add_action(suffix, SCons.Defaults.ShF77PPAction)
-
-    env['F77']        = env.Detect(compilers) or 'f77'
-    env['F77FLAGS']   = SCons.Util.CLVar('')
-    env['F77COM']     = '$F77 $F77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
-    env['F77PPCOM']   = '$F77 $F77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
-    env['SHF77']      = '$F77'
-    env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS')
-    env['SHF77COM']   = '$SHF77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
-    env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
+        static_obj.add_action(suffix, F77PPAction)
+        shared_obj.add_action(suffix, ShF77PPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+
+    env['_F77G']      = F77Generator
+    env['_F77FLAGSG'] = F77FlagsGenerator
+    env['F77COM']     = '$_F77G $_F77FLAGSG $_F77INCFLAGS -c -o $TARGET $SOURCES'
+    env['F77PPCOM']   = '$_F77G $_F77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
+
+    env['_SHF77G']      = ShF77Generator
+    env['_SHF77FLAGSG'] = ShF77FlagsGenerator
+    env['SHF77COM']   = '$_SHF77G $_SHF77FLAGSG $_F77INCFLAGS -c -o $TARGET $SOURCES'
+    env['SHF77PPCOM'] = '$_SHF77G $_SHF77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
+
+    env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs)} $)'
+
+def generate(env):
+    fortran.add_to_env(env)
+
+    import f90
+    import f95
+    f90.add_to_env(env)
+    f95.add_to_env(env)
+
+    add_to_env(env)
+
+    env['_FORTRAND']        = env.Detect(compilers) or 'f77'
 
 def exists(env):
     return env.Detect(compilers)
diff --git a/src/engine/SCons/Tool/f90.py b/src/engine/SCons/Tool/f90.py
new file mode 100644 (file)
index 0000000..b00a76e
--- /dev/null
@@ -0,0 +1,107 @@
+"""engine.SCons.Tool.f90
+
+Tool-specific initialization for the generic Posix f90 Fortran compiler.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Defaults
+import SCons.Scanner.Fortran
+import SCons.Tool
+import SCons.Util
+import fortran
+
+compilers = ['f90']
+
+#
+F90Action = SCons.Action.Action("$F90COM")
+ShF90Action = SCons.Action.Action("$SHF90COM")
+F90PPAction = SCons.Action.Action("$F90PPCOM")
+ShF90PPAction = SCons.Action.Action("$SHF90PPCOM")
+
+#
+F90Suffixes = ['.f90']
+F90PPSuffixes = []
+if SCons.Util.case_sensitive_suffixes('.f90', '.F90'):
+    F90PPSuffixes.append('.F90')
+else:
+    F90Suffixes.append('.F90')
+
+#
+F90Scan = SCons.Scanner.Fortran.FortranScan("F90PATH")
+
+for suffix in F90Suffixes + F90PPSuffixes:
+    SCons.Defaults.ObjSourceScan.add_scanner(suffix, F90Scan)
+
+#
+F90Generator = fortran.VariableListGenerator('F90', 'FORTRAN', '_FORTRAND')
+F90FlagsGenerator = fortran.VariableListGenerator('F90FLAGS', 'FORTRANFLAGS')
+ShF90Generator = fortran.VariableListGenerator('SHF90', 'SHFORTRAN', 'F90', 'FORTRAN', '_FORTRAND')
+ShF90FlagsGenerator = fortran.VariableListGenerator('SHF90FLAGS', 'SHFORTRANFLAGS')
+
+def add_to_env(env):
+    """Add Builders and construction variables for f90 to an Environment."""
+    env.AppendUnique(FORTRANSUFFIXES = F90Suffixes + F90PPSuffixes)
+
+    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+    for suffix in F90Suffixes:
+        static_obj.add_action(suffix, F90Action)
+        shared_obj.add_action(suffix, ShF90Action)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+
+    for suffix in F90PPSuffixes:
+        static_obj.add_action(suffix, F90PPAction)
+        shared_obj.add_action(suffix, ShF90PPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+  
+    env['_F90G']      = F90Generator
+    env['_F90FLAGSG'] = F90FlagsGenerator
+    env['F90COM']     = '$_F90G $_F90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['F90PPCOM']   = '$_F90G $_F90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_SHF90G']      = ShF90Generator
+    env['_SHF90FLAGSG'] = ShF90FlagsGenerator
+    env['SHF90COM']   = '$_SHF90G $_SHF90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['SHF90PPCOM'] = '$_SHF90G $_SHF90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_F90INCFLAGS'] = '$( ${_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__, RDirs)} $)'
+
+def generate(env):
+    fortran.add_to_env(env)
+    add_to_env(env)
+
+    env['_FORTRAND'] = env.Detect(compilers) or 'f90'
+
+def exists(env):
+    return env.Detect(compilers)
diff --git a/src/engine/SCons/Tool/f95.py b/src/engine/SCons/Tool/f95.py
new file mode 100644 (file)
index 0000000..291c980
--- /dev/null
@@ -0,0 +1,106 @@
+"""engine.SCons.Tool.f95
+
+Tool-specific initialization for the generic Posix f95 Fortran compiler.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Defaults
+import SCons.Tool
+import SCons.Util
+import fortran
+
+compilers = ['f95']
+
+#
+F95Action = SCons.Action.Action("$F95COM")
+ShF95Action = SCons.Action.Action("$SHF95COM")
+F95PPAction = SCons.Action.Action("$F95PPCOM")
+ShF95PPAction = SCons.Action.Action("$SHF95PPCOM")
+
+#
+F95Suffixes = ['.f95']
+F95PPSuffixes = []
+if SCons.Util.case_sensitive_suffixes('.f95', '.F95'):
+    F95PPSuffixes.append('.F95')
+else:
+    F95Suffixes.append('.F95')
+
+#
+F95Scan = SCons.Scanner.Fortran.FortranScan("F95PATH")
+
+for suffix in F95Suffixes + F95PPSuffixes:
+    SCons.Defaults.ObjSourceScan.add_scanner(suffix, F95Scan)
+
+#
+F95Generator = fortran.VariableListGenerator('F95', 'FORTRAN', '_FORTRAND')
+F95FlagsGenerator = fortran.VariableListGenerator('F95FLAGS', 'FORTRANFLAGS')
+ShF95Generator = fortran.VariableListGenerator('SHF95', 'SHFORTRAN', 'F95', 'FORTRAN', '_FORTRAND')
+ShF95FlagsGenerator = fortran.VariableListGenerator('SHF95FLAGS', 'SHFORTRANFLAGS')
+
+def add_to_env(env):
+    """Add Builders and construction variables for f95 to an Environment."""
+    env.AppendUnique(FORTRANSUFFIXES = F95Suffixes + F95PPSuffixes)
+
+    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+    for suffix in F95Suffixes:
+        static_obj.add_action(suffix, F95Action)
+        shared_obj.add_action(suffix, ShF95Action)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+
+    for suffix in F95PPSuffixes:
+        static_obj.add_action(suffix, F95PPAction)
+        shared_obj.add_action(suffix, ShF95PPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
+
+    env['_F95G']      = F95Generator
+    env['_F95FLAGSG'] = F95FlagsGenerator
+    env['F95COM']     = '$_F95G $_F95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['F95PPCOM']   = '$_F95G $_F95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_SHF95G']      = ShF95Generator
+    env['_SHF95FLAGSG'] = ShF95FlagsGenerator
+    env['SHF95COM']   = '$_SHF95G $_SHF95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['SHF95PPCOM'] = '$_SHF95G $_SHF95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_F95INCFLAGS'] = '$( ${_concat(INCPREFIX, F95PATH, INCSUFFIX, __env__, RDirs)} $)'
+
+def generate(env):
+    fortran.add_to_env(env)
+    add_to_env(env)
+
+    env['_FORTRAND'] = env.Detect(compilers) or 'f95'
+
+def exists(env):
+    return env.Detect(compilers)
diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py
new file mode 100644 (file)
index 0000000..5e2b5eb
--- /dev/null
@@ -0,0 +1,165 @@
+"""SCons.Tool.fortran
+
+Tool-specific initialization for a generic Posix f77/f90 Fortran compiler.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import re
+import string
+
+import SCons.Action
+import SCons.Defaults
+import SCons.Scanner.Fortran
+import SCons.Tool
+import SCons.Util
+
+compilers = ['f95', 'f90', 'f77']
+
+FortranAction = SCons.Action.Action("$FORTRANCOM")
+ShFortranAction = SCons.Action.Action("$SHFORTRANCOM")
+FortranPPAction = SCons.Action.Action("$FORTRANPPCOM")
+ShFortranPPAction = SCons.Action.Action("$SHFORTRANPPCOM")
+
+#
+#  Not yet sure how to deal with fortran pre-processor functions.
+#  Different compilers do this differently in modern fortran.  Some still
+#  rely on the c pre-processor, some (like cvf, ivf) have their own
+#  pre-processor technology and use intermediary suffixes (.i90)
+#
+FortranSuffixes = [".f", ".for", ".ftn", ]
+FortranPPSuffixes = ['.fpp', '.FPP']
+upper_case = [".F", ".FOR", ".FTN"]
+if SCons.Util.case_sensitive_suffixes('.f', '.F'):
+    FortranPPSuffixes.extend(upper_case)
+else:
+    FortranSuffixes.extend(upper_case)
+
+#
+FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")
+
+for suffix in FortranSuffixes + FortranPPSuffixes:
+    SCons.Defaults.ObjSourceScan.add_scanner(suffix, FortranScan)
+
+#
+def _fortranEmitter(target, source, env):
+    node = source[0].rfile()
+    if not node.exists() and not node.is_derived():
+       print "Could not locate " + str(node.name)
+       return ([], [])
+    mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
+    cre = re.compile(mod_regex,re.M)
+    # Retrieve all USE'd module names
+    modules = cre.findall(node.get_contents())
+    # Remove unique items from the list
+    modules = SCons.Util.unique(modules)
+    # Convert module name to a .mod filename
+    suffix = env.subst('$FORTRANMODSUFFIX')
+    modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+    for m in modules:
+       target.append(m)
+    return (target, source)
+
+def FortranEmitter(target, source, env):
+    target, source = _fortranEmitter(target, source, env)
+    return SCons.Defaults.StaticObjectEmitter(target, source, env)
+
+def ShFortranEmitter(target, source, env):
+    target, source = _fortranEmitter(target, source, env)
+    return SCons.Defaults.SharedObjectEmitter(target, source, env)
+
+class VariableListGenerator:
+    def __init__(self, *variablelist):
+        self.variablelist = variablelist
+    def __call__(self, env, target, source, for_signature):
+        for v in self.variablelist:
+            try: return env[v]
+            except KeyError: pass
+        return ''
+
+FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND')
+FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS')
+ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND')
+ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS')
+
+def add_to_env(env):
+    """Add Builders and construction variables for Fortran to an Environment."""
+
+    env['_FORTRANG']      = FortranGenerator
+    env['_FORTRANFLAGSG'] = FortranFlagsGenerator
+    env['FORTRANCOM']     = '$_FORTRANG $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['FORTRANPPCOM']   = '$_FORTRANG $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_SHFORTRANG']      = ShFortranGenerator
+    env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator
+    env['SHFORTRANCOM']   = '$_SHFORTRANG $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+    env['SHFORTRANPPCOM'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
+
+    env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs)} $)'
+
+    env['FORTRANMODPREFIX'] = ''     # like $LIBPREFIX
+    env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
+
+    env['FORTRANMODDIR'] = ''          # where the compiler should place .mod files
+    env['FORTRANMODDIRPREFIX'] = ''    # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
+    env['FORTRANMODDIRSUFFIX'] = ''    # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
+    env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)'
+
+    env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)
+
+    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+    for suffix in FortranSuffixes:
+        static_obj.add_action(suffix, FortranAction)
+        shared_obj.add_action(suffix, ShFortranAction)
+        static_obj.add_emitter(suffix, FortranEmitter)
+        shared_obj.add_emitter(suffix, ShFortranEmitter)
+
+    for suffix in FortranPPSuffixes:
+        static_obj.add_action(suffix, FortranPPAction)
+        shared_obj.add_action(suffix, ShFortranPPAction)
+        static_obj.add_emitter(suffix, FortranEmitter)
+        shared_obj.add_emitter(suffix, ShFortranEmitter)
+
+def generate(env):
+    import f77
+    import f90
+    import f95
+    f77.add_to_env(env)
+    f90.add_to_env(env)
+    f95.add_to_env(env)
+
+    add_to_env(env)
+
+    env['_FORTRAND'] = env.Detect(compilers) or 'f77'
+
+def exists(env):
+    return env.Detect(compilers)
index 549dffb96b5ef3841d385ff81bae8098ca81d57e..f481546469a094c8f1bac057ee9a648ca9f3d617 100644 (file)
@@ -41,7 +41,7 @@ def generate(env):
     """Add Builders and construction variables for g77 to an Environment."""
     f77.generate(env)
 
-    env['F77'] = env.Detect(compilers) or 'g77'
+    env['_FORTRAND'] = env.Detect(compilers) or 'g77'
 
 def exists(env):
     return env.Detect(compilers)
index 9fa33540e0a873ca2cd180bf19ef0058c27a2495..6841815e16f853e51b59183d6a8d2e62d6e28b9e 100644 (file)
@@ -51,10 +51,14 @@ def generate(env):
     for suffix in ASSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASAction)
         shared_obj.add_action(suffix, SCons.Defaults.ASAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
 
     for suffix in ASPPSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
         shared_obj.add_action(suffix, SCons.Defaults.ASPPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
 
     env['AS']        = 'ml'
     env['ASFLAGS']   = SCons.Util.CLVar('/nologo')
index a32c503731d8eb1cb9f824637f1bc6bc75ed12b0..5ab3779d9895138a7a301b670d56ba8ee3435bb2 100644 (file)
@@ -409,10 +409,14 @@ def generate(env):
     for suffix in CSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.CAction)
         shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
+        static_obj.add_emitter(suffix, static_object_emitter)
+        shared_obj.add_emitter(suffix, shared_object_emitter)
 
     for suffix in CXXSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.CXXAction)
         shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
+        static_obj.add_emitter(suffix, static_object_emitter)
+        shared_obj.add_emitter(suffix, shared_object_emitter)
 
     env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
     env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
@@ -433,8 +437,8 @@ def generate(env):
     env['CPPDEFSUFFIX']  = ''
     env['INCPREFIX']  = '/I'
     env['INCSUFFIX']  = ''
-    env.Append(OBJEMITTER = [static_object_emitter])
-    env.Append(SHOBJEMITTER = [shared_object_emitter])
+#    env.Append(OBJEMITTER = [static_object_emitter])
+#    env.Append(SHOBJEMITTER = [shared_object_emitter])
     env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
 
     env['RC'] = 'rc'
index 6b74341199befc013a227d8d67024a56d052a716..7dd3b63b8586d1d04409691a293fdc336b4f7912 100644 (file)
@@ -50,9 +50,11 @@ def generate(env):
 
     for suffix in ASSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
 
     for suffix in ASPPSuffixes:
         static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
+        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
 
     env['AS']        = 'nasm'
     env['ASFLAGS']   = SCons.Util.CLVar('')
index 49e52ffa6ee3656575b07a5b4726e60c73afbfd8..e2399a83e40b509596148da52e4e8ff684b6b832 100644 (file)
@@ -638,7 +638,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di
     class ListSubber(UserList.UserList):
         """A class to construct the results of a scons_subst_list() call.
 
-        Like StringSubber, this class binds a specific construction 
+        Like StringSubber, this class binds a specific construction
         environment, mode, target and source with two methods
         (substitute() and expand()) that handle the expansion.
 
@@ -774,7 +774,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di
             """Append the string x to the end of the current last word
             in the result.  If that is not possible, then just add
             it as a new word.  Make sure the entire concatenated string
-            inherits the object attributes of x (in particular, the 
+            inherits the object attributes of x (in particular, the
             escape function) by wrapping it as CmdStringHolder."""
 
             if not self.in_strip or self.mode != SUBST_SIG:
@@ -934,17 +934,17 @@ class Proxy:
     subject.  So, for the benefit of the python newbie, what does
     this really mean?  Well, it means that you can take an object, let's
     call it 'objA', and wrap it in this Proxy class, with a statement
-    like this 
+    like this
 
-                 proxyObj = Proxy(objA),   
+                 proxyObj = Proxy(objA),
 
-    Then, if in the future, you do something like this  
+    Then, if in the future, you do something like this
 
-                 x = proxyObj.var1, 
+                 x = proxyObj.var1,
+
+    since Proxy does not have a 'var1' attribute (but presumably objA does),
+    the request actually is equivalent to saying
 
-    since Proxy does not have a 'var1' attribute (but presumably objA does), 
-    the request actually is equivalent to saying 
-                
                  x = objA.var1
 
     Inherit from this class to create a Proxy."""
@@ -1141,7 +1141,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep):
 
     normpaths = []
     paths = []
-    # now we add them only of they are unique
+    # now we add them only if they are unique
     for path in newpaths:
         normpath = os.path.normpath(os.path.normcase(path))
         if path and not normpath in normpaths:
@@ -1317,3 +1317,74 @@ def adjustixes(fname, pre, suf):
     if suf and not splitext(fname)[1] and fname[-len(suf):] != suf:
             fname = fname + suf
     return fname
+
+
+def unique(s):
+    """Return a list of the elements in s, but without duplicates.
+
+    For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3],
+    unique("abcabc") some permutation of ["a", "b", "c"], and
+    unique(([1, 2], [2, 3], [1, 2])) some permutation of
+    [[2, 3], [1, 2]].
+
+    For best speed, all sequence elements should be hashable.  Then
+    unique() will usually work in linear time.
+
+    If not possible, the sequence elements should enjoy a total
+    ordering, and if list(s).sort() doesn't raise TypeError it's
+    assumed that they do enjoy a total ordering.  Then unique() will
+    usually work in O(N*log2(N)) time.
+
+    If that's not possible either, the sequence elements must support
+    equality-testing.  Then unique() will usually work in quadratic
+    time.
+    """
+
+    n = len(s)
+    if n == 0:
+        return []
+
+    # Try using a dict first, as that's the fastest and will usually
+    # work.  If it doesn't work, it will usually fail quickly, so it
+    # usually doesn't cost much to *try* it.  It requires that all the
+    # sequence elements be hashable, and support equality comparison.
+    u = {}
+    try:
+        for x in s:
+            u[x] = 1
+    except TypeError:
+        del u  # move on to the next method
+    else:
+        return u.keys()
+
+    # We can't hash all the elements.  Second fastest is to sort,
+    # which brings the equal elements together; then duplicates are
+    # easy to weed out in a single pass.
+    # NOTE:  Python's list.sort() was designed to be efficient in the
+    # presence of many duplicate elements.  This isn't true of all
+    # sort functions in all languages or libraries, so this approach
+    # is more effective in Python than it may be elsewhere.
+    try:
+        t = list(s)
+        t.sort()
+    except TypeError:
+        del t  # move on to the next method
+    else:
+        assert n > 0
+        last = t[0]
+        lasti = i = 1
+        while i < n:
+            if t[i] != last:
+                t[lasti] = last = t[i]
+                lasti = lasti + 1
+            i = i + 1
+        return t[:lasti]
+
+    # Brute force is all that's left.
+    u = []
+    for x in s:
+        if x not in u:
+            u.append(x)
+    return u
+
+
index 6d5289f82a53f51d7844faf3e28399f916226b31..4e2871a2308aed7e836dbf93044f0aae3150ad5c 100644 (file)
@@ -35,7 +35,7 @@ fortran_runtime = TestSCons.fortran_lib
 
 test = TestSCons.TestSCons()
 
-f77 = test.detect('F77')
+fortran = test.detect('FORTRAN')
 
 foo11 = test.workpath('work1', 'build', 'var1', 'foo1' + _exe)
 foo12 = test.workpath('work1', 'build', 'var1', 'foo2' + _exe)
@@ -78,15 +78,15 @@ env.BuildDir("$BUILD/var4", "$SRC", duplicate=0)
 BuildDir(var5, src, duplicate=0)
 BuildDir(var6, src)
 
-env = Environment(CPPPATH='#src', F77PATH='#src')
+env = Environment(CPPPATH='#src', FORTRANPATH='#src')
 SConscript('build/var1/SConscript', "env")
 SConscript('build/var2/SConscript', "env")
 
-env = Environment(CPPPATH=src, F77PATH=src)
+env = Environment(CPPPATH=src, FORTRANPATH=src)
 SConscript('build/var3/SConscript', "env")
 SConscript(File('SConscript', var4), "env")
 
-env = Environment(CPPPATH='.', F77PATH='.')
+env = Environment(CPPPATH='.', FORTRANPATH='.')
 SConscript('../build/var5/SConscript', "env")
 SConscript('../build/var6/SConscript', "env")
 """)
@@ -118,11 +118,11 @@ env2.Program(target='foo3', source='f3.c')
 env2.Program(target='foo4', source='f4.c')
 
 try:
-    f77 = env['F77']
+    fortran = env.subst('$FORTRAN')
 except:
-    f77 = None
+    fortran = None
 
-if f77 and env.Detect(env['F77']):
+if fortran and env.Detect(fortran):
     env.Command(target='b2.f', source='b2.in', action=buildIt)
     env.Copy(LIBS = %s).Program(target='bar2', source='b2.f')
     env.Copy(LIBS = %s).Program(target='bar1', source='b1.f')
@@ -241,7 +241,7 @@ test.run(program = foo42, stdout = "f2.c\n")
 test.run(program = foo51, stdout = "f1.c\n")
 test.run(program = foo52, stdout = "f2.c\n")
 
-if f77:
+if fortran:
     test.run(program = bar11, stdout = " b1.for\n")
     test.run(program = bar12, stdout = " b2.for\n")
     test.run(program = bar21, stdout = " b1.for\n")
index 357a2413d64ab1982599d9bfc8c2e941bcbf06e5..92c7d7c623aff89c07a152d8807e5dad7167a1e8 100644 (file)
@@ -107,7 +107,7 @@ env = Environment(CPPFLAGS = '-x',
                   CC = r'%s mygcc.py cc',
                   CXX = r'%s mygcc.py c++',
                   CXXFLAGS = [],
-                  F77 = r'%s mygcc.py g77')
+                  FORTRAN = r'%s mygcc.py g77')
 env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F'))
 """ % (python, python, python, python))
 
@@ -144,7 +144,7 @@ env = Environment(CPPFLAGS = '-x',
                   CC = r'%s mygcc.py cc',
                   CXX = r'%s mygcc.py c++',
                   CXXFLAGS = [],
-                  F77 = r'%s mygcc.py g77')
+                  FORTRAN = r'%s mygcc.py g77')
 env.SharedLibrary(target = File('foo.bar'),
                   source = Split('test1.c test2.cpp test3.F'))
 """ % (python, python, python, python))
diff --git a/test/F77.py b/test/F77.py
deleted file mode 100644 (file)
index 94c7c77..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import string
-import sys
-import TestSCons
-
-python = TestSCons.python
-_exe   = TestSCons._exe
-
-test = TestSCons.TestSCons()
-
-
-
-if sys.platform == 'win32':
-
-    test.write('mylink.py', r"""
-import string
-import sys
-args = sys.argv[1:]
-while args:
-    a = args[0]
-    if a[0] != '/':
-        break
-    args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:5] != '#link':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-else:
-
-    test.write('mylink.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'o:')
-for opt, arg in opts:
-    if opt == '-o': out = arg
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:5] != '#link':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-test.write('myg77.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'co:')
-for opt, arg in opts:
-    if opt == '-o': out = arg
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:4] != '#g77':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
-                  LINKFLAGS = [],
-                  F77 = r'%s myg77.py')
-env.Program(target = 'test1', source = 'test1.f')
-env.Program(target = 'test2', source = 'test2.for')
-env.Program(target = 'test3', source = 'test3.FOR')
-env.Program(target = 'test4', source = 'test4.F')
-env.Program(target = 'test5', source = 'test5.fpp')
-env.Program(target = 'test6', source = 'test6.FPP')
-""" % (python, python))
-
-test.write('test1.f', r"""This is a .f file.
-#g77
-#link
-""")
-
-test.write('test2.for', r"""This is a .for file.
-#g77
-#link
-""")
-
-test.write('test3.FOR', r"""This is a .FOR file.
-#g77
-#link
-""")
-
-test.write('test4.F', r"""This is a .F file.
-#g77
-#link
-""")
-
-test.write('test5.fpp', r"""This is a .fpp file.
-#g77
-#link
-""")
-
-test.write('test6.FPP', r"""This is a .FPP file.
-#g77
-#link
-""")
-
-test.run(arguments = '.', stderr = None)
-
-test.fail_test(test.read('test1' + _exe) != "This is a .f file.\n")
-
-test.fail_test(test.read('test2' + _exe) != "This is a .for file.\n")
-
-test.fail_test(test.read('test3' + _exe) != "This is a .FOR file.\n")
-
-test.fail_test(test.read('test4' + _exe) != "This is a .F file.\n")
-
-test.fail_test(test.read('test5' + _exe) != "This is a .fpp file.\n")
-
-test.fail_test(test.read('test6' + _exe) != "This is a .FPP file.\n")
-
-
-
-g77 = test.detect('F77', 'g77')
-FTN_LIB = TestSCons.fortran_lib
-
-if g77:
-
-    test.write("wrapper.py",
-"""import os
-import string
-import sys
-open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
-
-    test.write('SConstruct', """
-foo = Environment(LIBS = %s)
-f77 = foo.Dictionary('F77')
-bar = foo.Copy(F77 = r'%s wrapper.py ' + f77)
-foo.Program(target = 'foo', source = 'foo.f')
-bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
-
-    test.write('foo.f', r"""
-      PROGRAM FOO
-      PRINT *,'foo.f'
-      STOP
-      END
-""")
-
-    test.write('bar.f', r"""
-      PROGRAM BAR
-      PRINT *,'bar.f'
-      STOP
-      END
-""")
-
-
-    test.run(arguments = 'foo' + _exe, stderr = None)
-
-    test.run(program = test.workpath('foo'), stdout =  " foo.f\n")
-
-    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
-
-    test.run(arguments = 'bar' + _exe)
-
-    test.run(program = test.workpath('bar'), stdout =  " bar.f\n")
-
-    test.fail_test(test.read('wrapper.out') != "wrapper.py\n")
-
-test.pass_test()
diff --git a/test/F77FLAGS.py b/test/F77FLAGS.py
deleted file mode 100644 (file)
index 027a02f..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import string
-import sys
-import TestSCons
-
-python = TestSCons.python
-
-test = TestSCons.TestSCons()
-_exe = TestSCons._exe
-
-if sys.platform == 'win32':
-
-    test.write('mylink.py', r"""
-import string
-import sys
-args = sys.argv[1:]
-while args:
-    a = args[0]
-    if a[0] != '/':
-        break
-    args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:5] != '#link':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-else:
-
-    test.write('mylink.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'o:')
-for opt, arg in opts:
-    if opt == '-o': out = arg
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:5] != '#link':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-test.write('myg77.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'co:x')
-optstring = ''
-for opt, arg in opts:
-    if opt == '-o': out = arg
-    else: optstring = optstring + ' ' + opt
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-outfile.write(optstring + "\n")
-for l in infile.readlines():
-    if l[:4] != '#g77':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-
-
-test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
-                  LINKFLAGS = [],
-                  F77 = r'%s myg77.py', F77FLAGS = '-x')
-env.Program(target = 'test1', source = 'test1.f')
-env.Program(target = 'test2', source = 'test2.for')
-env.Program(target = 'test3', source = 'test3.FOR')
-env.Program(target = 'test4', source = 'test4.F')
-env.Program(target = 'test5', source = 'test5.fpp')
-env.Program(target = 'test6', source = 'test6.FPP')
-""" % (python, python))
-
-test.write('test1.f', r"""This is a .f file.
-#g77
-#link
-""")
-
-test.write('test2.for', r"""This is a .for file.
-#g77
-#link
-""")
-
-test.write('test3.FOR', r"""This is a .FOR file.
-#g77
-#link
-""")
-
-test.write('test4.F', r"""This is a .F file.
-#g77
-#link
-""")
-
-test.write('test5.fpp', r"""This is a .fpp file.
-#g77
-#link
-""")
-
-test.write('test6.FPP', r"""This is a .FPP file.
-#g77
-#link
-""")
-
-test.run(arguments = '.', stderr = None)
-
-test.fail_test(test.read('test1' + _exe) != " -x -c\nThis is a .f file.\n")
-
-test.fail_test(test.read('test2' + _exe) != " -x -c\nThis is a .for file.\n")
-
-test.fail_test(test.read('test3' + _exe) != " -x -c\nThis is a .FOR file.\n")
-
-test.fail_test(test.read('test4' + _exe) != " -x -c\nThis is a .F file.\n")
-
-test.fail_test(test.read('test5' + _exe) != " -x -c\nThis is a .fpp file.\n")
-
-test.fail_test(test.read('test6' + _exe) != " -x -c\nThis is a .FPP file.\n")
-
-
-
-g77 = test.detect('F77', 'g77')
-FTN_LIB = TestSCons.fortran_lib
-
-if g77:
-
-    test.write("wrapper.py",
-"""import os
-import string
-import sys
-open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
-
-    test.write('SConstruct', """
-foo = Environment(LIBS = %s)
-f77 = foo.Dictionary('F77')
-bar = foo.Copy(F77 = r'%s wrapper.py ' + f77, F77FLAGS = '-Ix')
-foo.Program(target = 'foo', source = 'foo.f')
-bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
-
-    test.write('foo.f', r"""
-      PROGRAM FOO
-      PRINT *,'foo.f'
-      STOP
-      END
-""")
-
-    test.write('bar.f', r"""
-      PROGRAM BAR
-      PRINT *,'bar.f'
-      STOP
-      END
-""")
-
-
-    test.run(arguments = 'foo' + _exe, stderr = None)
-
-    test.run(program = test.workpath('foo'), stdout =  " foo.f\n")
-
-    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
-
-    test.run(arguments = 'bar' + _exe)
-
-    test.run(program = test.workpath('bar'), stdout =  " bar.f\n")
-
-    test.fail_test(test.read('wrapper.out') != "wrapper.py\n")
-
-test.pass_test()
diff --git a/test/F77PATH.py b/test/F77PATH.py
deleted file mode 100644 (file)
index 340c321..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import sys
-import TestSCons
-
-_exe = TestSCons._exe
-FTN_LIB = TestSCons.fortran_lib
-
-prog = 'prog' + _exe
-subdir_prog = os.path.join('subdir', 'prog' + _exe)
-variant_prog = os.path.join('variant', 'prog' + _exe)
-
-args = prog + ' ' + subdir_prog + ' ' + variant_prog
-
-test = TestSCons.TestSCons()
-
-if not test.detect('F77', 'g77'):
-    test.pass_test()
-    
-test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2')
-
-test.write('SConstruct', """
-env = Environment(F77PATH = ['$FOO'], LIBS = %s, FOO='include')
-obj = env.Object(target='foobar/prog', source='subdir/prog.f')
-env.Program(target='prog', source=obj)
-SConscript('subdir/SConscript', "env")
-
-BuildDir('variant', 'subdir', 0)
-include = Dir('include')
-env = Environment(F77PATH=[include], LIBS = %s)
-SConscript('variant/SConscript', "env")
-""" % (FTN_LIB, FTN_LIB))
-
-test.write(['subdir', 'SConscript'],
-"""
-Import("env")
-env.Program(target='prog', source='prog.f')
-""")
-
-test.write(['include', 'foo.f'],
-r"""
-      PRINT *, 'include/foo.f 1'
-      INCLUDE 'bar.f'
-""")
-
-test.write(['include', 'bar.f'],
-r"""
-      PRINT *, 'include/bar.f 1'
-""")
-
-test.write(['subdir', 'prog.f'],
-r"""
-      PROGRAM PROG
-      PRINT *, 'subdir/prog.f'
-      include 'foo.f'
-      STOP
-      END
-""")
-
-test.write(['subdir', 'include', 'foo.f'],
-r"""
-      PRINT *, 'subdir/include/foo.f 1'
-      INCLUDE 'bar.f'
-""")
-
-test.write(['subdir', 'include', 'bar.f'],
-r"""
-      PRINT *, 'subdir/include/bar.f 1'
-""")
-
-
-
-test.run(arguments = args)
-
-test.run(program = test.workpath(prog),
-         stdout = " subdir/prog.f\n include/foo.f 1\n include/bar.f 1\n")
-
-test.run(program = test.workpath(subdir_prog),
-         stdout = " subdir/prog.f\n subdir/include/foo.f 1\n subdir/include/bar.f 1\n")
-
-test.run(program = test.workpath(variant_prog),
-         stdout = " subdir/prog.f\n include/foo.f 1\n include/bar.f 1\n")
-
-# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.f')))
-
-test.up_to_date(arguments = args)
-
-test.write(['include', 'foo.f'],
-r"""
-      PRINT *, 'include/foo.f 2'
-      INCLUDE 'bar.f'
-""")
-
-test.run(arguments = args)
-
-test.run(program = test.workpath(prog),
-         stdout = " subdir/prog.f\n include/foo.f 2\n include/bar.f 1\n")
-
-test.run(program = test.workpath(subdir_prog),
-         stdout = " subdir/prog.f\n subdir/include/foo.f 1\n subdir/include/bar.f 1\n")
-
-test.run(program = test.workpath(variant_prog),
-         stdout = " subdir/prog.f\n include/foo.f 2\n include/bar.f 1\n")
-
-# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.f')))
-
-test.up_to_date(arguments = args)
-
-#
-test.write(['include', 'bar.f'],
-r"""
-      PRINT *, 'include/bar.f 2'
-""")
-
-test.run(arguments = args)
-
-test.run(program = test.workpath(prog),
-         stdout = " subdir/prog.f\n include/foo.f 2\n include/bar.f 2\n")
-
-test.run(program = test.workpath(subdir_prog),
-         stdout = " subdir/prog.f\n subdir/include/foo.f 1\n subdir/include/bar.f 1\n")
-
-test.run(program = test.workpath(variant_prog),
-         stdout = " subdir/prog.f\n include/foo.f 2\n include/bar.f 2\n")
-
-# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.f')))
-
-test.up_to_date(arguments = args)
-
-# Change F77PATH and make sure we don't rebuild because of it.
-test.write('SConstruct', """
-env = Environment(F77PATH = Split('inc2 include'), LIBS = %s)
-obj = env.Object(target='foobar/prog', source='subdir/prog.f')
-env.Program(target='prog', source=obj)
-SConscript('subdir/SConscript', "env")
-
-BuildDir('variant', 'subdir', 0)
-include = Dir('include')
-env = Environment(F77PATH=['inc2', include], LIBS = %s)
-SConscript('variant/SConscript', "env")
-""" % (FTN_LIB, FTN_LIB))
-
-test.up_to_date(arguments = args)
-
-#
-test.write(['inc2', 'foo.f'],
-r"""
-      PRINT *, 'inc2/foo.f 1'
-      INCLUDE 'bar.f'
-""")
-
-test.run(arguments = args)
-
-test.run(program = test.workpath(prog),
-         stdout = " subdir/prog.f\n inc2/foo.f 1\n include/bar.f 2\n")
-
-test.run(program = test.workpath(subdir_prog),
-         stdout = " subdir/prog.f\n subdir/include/foo.f 1\n subdir/include/bar.f 1\n")
-
-test.run(program = test.workpath(variant_prog),
-         stdout = " subdir/prog.f\n include/foo.f 2\n include/bar.f 2\n")
-
-test.up_to_date(arguments = args)
-
-# Check that a null-string F77PATH doesn't blow up.
-test.write('SConstruct', """
-env = Environment(F77PATH = '', LIBS = %s)
-env.Library('foo', source = 'empty.f')
-""" % FTN_LIB)
-
-test.write('empty.f', '')
-
-test.run(arguments = '.')
-
-test.pass_test()
diff --git a/test/FORTRANSUFFIXES.py b/test/FORTRANSUFFIXES.py
deleted file mode 100644 (file)
index c5047f7..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-"""
-Test the ability to scan additional filesuffixes added to $FORTRANSUFFIXES.
-"""
-
-import TestSCons
-
-python = TestSCons.python
-
-test = TestSCons.TestSCons()
-
-test.write('myfc.py', r"""
-import string
-import sys
-def do_file(outf, inf):
-    for line in open(inf, 'rb').readlines():
-        if line[:15] == "      INCLUDE '":
-            do_file(outf, line[15:-2])
-        else:
-            outf.write(line)
-outf = open(sys.argv[1], 'wb')
-for f in sys.argv[2:]:
-    do_file(outf, f)
-sys.exit(0)
-""")
-
-test.write('SConstruct', """
-env = Environment(F77PATH = ['.'],
-                  F77 = r'%s myfc.py',
-                  F77FLAGS = [],
-                  F77COM = '$F77 $TARGET $SOURCES',
-                  OBJSUFFIX = '.o')
-env.Append(FORTRANSUFFIXES = ['.x'])
-env.Object(target = 'test1', source = 'test1.f')
-env.InstallAs('test1_f', 'test1.f')
-env.InstallAs('test1_h', 'test1.h')
-env.InstallAs('test1_x', 'test1.x')
-""" % (python,))
-
-test.write('test1.f', """\
-      test1.f 1
-      INCLUDE 'test1.h'
-      INCLUDE 'test1.x'
-""")
-
-test.write('test1.h', """\
-      test1.h 1
-      INCLUDE 'foo.h'
-""")
-
-test.write('test1.x', """\
-      test1.x 1
-      INCLUDE 'foo.h'
-""")
-
-test.write('foo.h', """\
-      foo.h 1
-""")
-
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
-Install file: "test1.f" as "test1_f"
-Install file: "test1.h" as "test1_h"
-Install file: "test1.x" as "test1_x"
-""" % (python,)))
-
-test.must_match('test1.o', """\
-      test1.f 1
-      test1.h 1
-      foo.h 1
-      test1.x 1
-      foo.h 1
-""")
-
-test.up_to_date(arguments='.')
-
-test.write('foo.h', """\
-      foo.h 2
-""")
-
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
-""" % (python,)))
-
-test.must_match('test1.o', """\
-      test1.f 1
-      test1.h 1
-      foo.h 2
-      test1.x 1
-      foo.h 2
-""")
-
-test.up_to_date(arguments='.')
-
-test.write('test1.x', """\
-      test1.x 2
-      INCLUDE 'foo.h'
-""")
-
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
-Install file: "test1.x" as "test1_x"
-""" % (python,)))
-
-test.must_match('test1.o', """\
-      test1.f 1
-      test1.h 1
-      foo.h 2
-      test1.x 2
-      foo.h 2
-""")
-
-test.up_to_date(arguments='.')
-
-test.write('test1.h', """\
-      test1.h 2
-      INCLUDE 'foo.h'
-""")
-
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
-Install file: "test1.h" as "test1_h"
-""" % (python,)))
-
-test.must_match('test1.o', """\
-      test1.f 1
-      test1.h 2
-      foo.h 2
-      test1.x 2
-      foo.h 2
-""")
-
-test.up_to_date(arguments='.')
-
-test.pass_test()
diff --git a/test/SHF77.py b/test/SHF77.py
deleted file mode 100644 (file)
index 24ab0ec..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import string
-import sys
-import TestSCons
-
-python = TestSCons.python
-_obj   = TestSCons._shobj
-
-test = TestSCons.TestSCons()
-
-
-
-test.write('myg77.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'cf:o:')
-for opt, arg in opts:
-    if opt == '-o': out = arg
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
-    if l[:4] != '#g77':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-
-
-test.write('SConstruct', """
-env = Environment(SHF77 = r'%s myg77.py')
-env.SharedObject(target = 'test1', source = 'test1.f')
-env.SharedObject(target = 'test2', source = 'test2.for')
-env.SharedObject(target = 'test3', source = 'test3.FOR')
-env.SharedObject(target = 'test4', source = 'test4.F')
-env.SharedObject(target = 'test5', source = 'test5.fpp')
-env.SharedObject(target = 'test6', source = 'test6.FPP')
-""" % python)
-
-test.write('test1.f', r"""This is a .f file.
-#g77
-""")
-
-test.write('test2.for', r"""This is a .for file.
-#g77
-""")
-
-test.write('test3.FOR', r"""This is a .FOR file.
-#g77
-""")
-
-test.write('test4.F', r"""This is a .F file.
-#g77
-""")
-
-test.write('test5.fpp', r"""This is a .fpp file.
-#g77
-""")
-
-test.write('test6.FPP', r"""This is a .FPP file.
-#g77
-""")
-
-test.run(arguments = '.', stderr = None)
-
-test.fail_test(test.read('test1' + _obj) != "This is a .f file.\n")
-
-test.fail_test(test.read('test2' + _obj) != "This is a .for file.\n")
-
-test.fail_test(test.read('test3' + _obj) != "This is a .FOR file.\n")
-
-test.fail_test(test.read('test4' + _obj) != "This is a .F file.\n")
-
-test.fail_test(test.read('test5' + _obj) != "This is a .fpp file.\n")
-
-test.fail_test(test.read('test6' + _obj) != "This is a .FPP file.\n")
-
-
-
-g77 = test.detect('F77', 'g77')
-
-if g77:
-
-    test.write("wrapper.py",
-"""import os
-import string
-import sys
-open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
-
-    test.write('SConstruct', """
-foo = Environment(LIBS = 'g2c')
-shf77 = foo.Dictionary('SHF77')
-bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77)
-foo.SharedObject(target = 'foo/foo', source = 'foo.f')
-bar.SharedObject(target = 'bar/bar', source = 'bar.f')
-""" % python)
-
-    test.write('foo.f', r"""
-      PROGRAM FOO
-      PRINT *,'foo.f'
-      STOP
-      END
-""")
-
-    test.write('bar.f', r"""
-      PROGRAM BAR
-      PRINT *,'bar.f'
-      STOP
-      END
-""")
-
-
-    test.run(arguments = 'foo', stderr = None)
-
-    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
-
-    test.run(arguments = 'bar')
-
-    test.fail_test(test.read('wrapper.out') != "wrapper.py\n")
-
-test.pass_test()
diff --git a/test/SHF77FLAGS.py b/test/SHF77FLAGS.py
deleted file mode 100644 (file)
index 261f638..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import string
-import sys
-import TestSCons
-
-python = TestSCons.python
-
-if sys.platform == 'win32':
-    _obj = '.obj'
-else:
-    if string.find(sys.platform, 'irix') > -1:
-        _obj = '.o'
-    else:
-        _obj = '.os'
-
-test = TestSCons.TestSCons()
-
-
-
-test.write('myg77.py', r"""
-import getopt
-import sys
-opts, args = getopt.getopt(sys.argv[1:], 'co:x')
-optstring = ''
-for opt, arg in opts:
-    if opt == '-o': out = arg
-    else: optstring = optstring + ' ' + opt
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-outfile.write(optstring + "\n")
-for l in infile.readlines():
-    if l[:4] != '#g77':
-       outfile.write(l)
-sys.exit(0)
-""")
-
-
-
-test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
-                  SHF77 = r'%s myg77.py', SHF77FLAGS = '-x')
-env.SharedObject(target = 'test1', source = 'test1.f')
-env.SharedObject(target = 'test2', source = 'test2.for')
-env.SharedObject(target = 'test3', source = 'test3.FOR')
-env.SharedObject(target = 'test4', source = 'test4.F')
-env.SharedObject(target = 'test5', source = 'test5.fpp')
-env.SharedObject(target = 'test6', source = 'test6.FPP')
-""" % (python, python))
-
-test.write('test1.f', r"""This is a .f file.
-#g77
-""")
-
-test.write('test2.for', r"""This is a .for file.
-#g77
-""")
-
-test.write('test3.FOR', r"""This is a .FOR file.
-#g77
-""")
-
-test.write('test4.F', r"""This is a .F file.
-#g77
-""")
-
-test.write('test5.fpp', r"""This is a .fpp file.
-#g77
-""")
-
-test.write('test6.FPP', r"""This is a .FPP file.
-#g77
-""")
-
-test.run(arguments = '.', stderr = None)
-
-test.fail_test(test.read('test1' + _obj) != " -x -c\nThis is a .f file.\n")
-
-test.fail_test(test.read('test2' + _obj) != " -x -c\nThis is a .for file.\n")
-
-test.fail_test(test.read('test3' + _obj) != " -x -c\nThis is a .FOR file.\n")
-
-test.fail_test(test.read('test4' + _obj) != " -x -c\nThis is a .F file.\n")
-
-test.fail_test(test.read('test5' + _obj) != " -x -c\nThis is a .fpp file.\n")
-
-test.fail_test(test.read('test6' + _obj) != " -x -c\nThis is a .FPP file.\n")
-
-
-
-g77 = test.detect('F77', 'g77')
-FTN_LIB = TestSCons.fortran_lib
-
-if g77:
-
-    test.write("wrapper.py",
-"""import os
-import string
-import sys
-open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
-
-    test.write('SConstruct', """
-foo = Environment(LIBS = %s)
-shf77 = foo.Dictionary('SHF77')
-bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77, SHF77FLAGS = '-Ix')
-foo.SharedLibrary(target = 'foo/foo', source = 'foo.f')
-bar.SharedLibrary(target = 'bar/bar', source = 'bar.f')
-""" % (FTN_LIB, python))
-
-    test.write('foo.f', r"""
-      PROGRAM FOO
-      PRINT *,'foo.f'
-      STOP
-      END
-""")
-
-    test.write('bar.f', r"""
-      PROGRAM BAR
-      PRINT *,'bar.f'
-      STOP
-      END
-""")
-
-
-    test.run(arguments = 'foo', stderr = None)
-
-    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
-
-    test.run(arguments = 'bar')
-
-    test.fail_test(test.read('wrapper.out') != "wrapper.py\n")
-
-test.pass_test()