diff options
Diffstat (limited to 'numpy/f2py')
163 files changed, 0 insertions, 29856 deletions
diff --git a/numpy/f2py/BUGS.txt b/numpy/f2py/BUGS.txt deleted file mode 100644 index ee08863bb..000000000 --- a/numpy/f2py/BUGS.txt +++ /dev/null @@ -1,55 +0,0 @@ -December 1, 2002: - -C FILE: STRING.F - SUBROUTINE FOO - END -C END OF FILE STRING.F -does not build with - f2py -c -m string string.f -Cause: string is mapped to string_bn -************************************************************************** -August 16, 2001: -1) re in Python 2.x is **three** times slower than the re in Python 1.5. -************************************************************************** -HP-UX B.10.20 A 9000/780: -Fortran function returning character*(*) (id=7) ... failed(core dump) -Fortran function returning logical*8 (id=21) ... expected .true. but got 0 -Callback function returning real (id=45) ... expected 34.56 but got 14087495680.0 -Callback function returning real*4 (id=46) ... expected 34.56 but got 14087495680.0 -Callback function returning logical*8 (id=55) ... expected .true. but got 0 - C compiler: gcc ('gcc 2.x.x' 2.95.2) (from .f2py_get_compiler_CC) - Fortran compiler: g77 ('g77 2.x.x' 2.95.2) (from .f2py_get_compiler_FC) - Linker: ld ('HP-UX ld' 92453-07 linker linker ld B.10.24 961204) (from .f2py_get_compiler_LD) -************************************************************************** -Linux 2.2.13-0.9 #1 Thu Dec 9 17:03:57 EST 1999 alpha unknown: -Fortran function returning character*(*) (id=7) ... expected 'abcdefgh' but got 'abcdefgh \201' (o?k) -Callback function returning complex (id=48) ... failed(core dump) - Trying with -DF2PY_CB_RETURNCOMPLEX ... failed(core dump) -Callback function returning complex*8 (id=49) ... failed(core dump) - Trying with -DF2PY_CB_RETURNCOMPLEX ... failed(core dump) -Callback function returning complex*16 (id=50) ... failed(core dump) - Trying with -DF2PY_CB_RETURNCOMPLEX ... failed(core dump) - C compiler: cc ('Compaq C' V6.2-002) (from .f2py_get_compiler_CC) - Fortran compiler: fort ('Compaq Fortran' V1.0-920) (from .f2py_get_compiler_FC) - Linker: fort ('Compaq Fortran' V1.0-920) (from .f2py_get_compiler_LD) -************************************************************************** -Linux 2.2.14-15mdk #1 Tue Jan 4 22:24:20 CET 2000 i686 unknown: -Callback function returning logical*8 (id=55) ... failed - C compiler: cc ('gcc 2.x.x' 2.95.2) - Fortran compiler: f90 ('Absoft F90' 3.0) - Linker: ld ('GNU ld' 2.9.5) -************************************************************************** -IRIX64 6.5 04151556 IP30: -Testing integer, intent(inout) ...failed # not f2py problem -Testing integer, intent(inout,out) ...failed -Testing integer*1, intent(inout) ...failed -Testing integer*1, intent(inout,out) ...failed -Testing integer*8, intent(inout) ...failed -Testing integer*8, intent(inout,out) ...failed -cc-1140 cc: WARNING File = genmodule.c, Line = 114 - A value of type "void *" cannot be used to initialize an entity of type - "void (*)()". - {"foo",-1,{-1},0,(char *)F_FUNC(foo,FOO),(void *)gen_foo,doc_gen_foo}, - C compiler: cc ('MIPSpro 7 Compilers' 7.30) - Fortran compiler: f77 ('MIPSpro 7 Compilers' 7.30) - Linker: ld ('Linker for MIPSpro 7 Compilers' 7.30.) diff --git a/numpy/f2py/Makefile b/numpy/f2py/Makefile deleted file mode 100644 index 4e53ac471..000000000 --- a/numpy/f2py/Makefile +++ /dev/null @@ -1,173 +0,0 @@ -# Makefile for f2py2e -# -# Use GNU make for making. -# $Revision: 1.46 $ -# $Date: 2005/01/30 17:22:55 $ -# Pearu Peterson <pearu@ioc.ee> - -PYTHON=python -MAJOR=2 -F2PY2E_CVSROOT=:pserver:anonymous@cens.ioc.ee:/home/cvs -SCIPY_CVSROOT=:pserver:anonymous@numpy.org:/home/cvsroot - -UPLOADCMD = scp -r -UPLOADDIR = pearu@kev.ioc.ee:/net/cens/home/www/unsecure/projects/f2py2e/ - -REV=`python -c 'from __version__ import *;print version'` -SCIPY_DISTUTILS_REV=`cd numpy_distutils && $(PYTHON) -c 'from numpy_distutils_version import *;print numpy_distutils_version' && cd ..` - -SRC_FILES = F2PY-$(MAJOR)-latest.tar.gz numpy_distutils-latest.tar.gz F2PY-$(MAJOR)-latest.win32.exe numpy_distutils-latest.win32.exe - -HTML_FILES = index.html FAQ.html HISTORY.html THANKS.html TESTING.html OLDNEWS.html -FAQ_DEPS = simple.f pytest.py pyforttest.pyf simple_session.dat -README_DEPS = hello.f -UG_FILES = index.html f2py_usersguide.pdf -UG_FILES_DEP = $(shell cd docs/usersguide && ls *.{f,f90,dat,pyf,py}) - -WWW_SRC_FILES = $(SRC_FILES:%=upload/www/$(MAJOR).x/%) -WWW_WEB_FILES = $(HTML_FILES:%=upload/www/%) $(README_DEPS:%=upload/www/%) -WWW_UG_FILES = $(UG_FILES:%=upload/www/usersguide/%) $(UG_FILES_DEP:%=upload/www/usersguide/%) - -TMP_WEB_FILES = $(HTML_FILES:%=upload/tmp/%) $(README_DEPS:%=upload/tmp/%) - -############################################################################## - -all: - @echo "Use 'make install' to install f2py" - @echo "Use 'make generate' to build f2py docs to upload/tmp" -install: - $(PYTHON) setup.py install -test: - cd tests && $(PYTHON) run_all.py - -############################################################################## -# Create F2PY tar-balls -############################################################################## -f2py2e: - test -d f2py2e && (cd f2py2e && cvs -d $(F2PY2E_CVSROOT) -z7 update -Pd && cd -) || cvs -d $(F2PY2E_CVSROOT) checkout f2py2e - -upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.tar.gz: f2py2e - cd f2py2e && python setup.py sdist -f - mkdir -p upload/tmp/$(MAJOR).x - cp f2py2e/dist/F2PY-$(REV).tar.gz upload/tmp/$(MAJOR).x - ln -sf F2PY-$(REV).tar.gz F2PY-$(MAJOR)-latest.tar.gz - mv F2PY-$(MAJOR)-latest.tar.gz upload/tmp/$(MAJOR).x -upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.win32.exe: f2py2e - cd f2py2e && python setup.py bdist_wininst - mkdir -p upload/tmp/$(MAJOR).x - cp f2py2e/dist/F2PY-$(REV).win32.exe upload/tmp/$(MAJOR).x - ln -sf F2PY-$(REV).win32.exe F2PY-$(MAJOR)-latest.win32.exe - mv F2PY-$(MAJOR)-latest.win32.exe upload/tmp/$(MAJOR).x -f2py2e_latest: upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.tar.gz upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.win32.exe - -############################################################################## -# Create Scipy_distutils tar-balls -############################################################################## - -numpy_distutils: - test -d numpy_distutils && (cd numpy_distutils && cvs -d $(SCIPY_CVSROOT) -z7 update -Pd && cd -) || cvs -d $(SCIPY_CVSROOT) checkout numpy_distutils - -upload/tmp/$(MAJOR).x/numpy_distutils-latest.tar.gz: numpy_distutils - cd numpy_distutils && python setup.py sdist -f - mkdir -p upload/tmp/$(MAJOR).x - cp numpy_distutils/dist/numpy_distutils-$(SCIPY_DISTUTILS_REV).tar.gz upload/tmp/$(MAJOR).x - ln -sf numpy_distutils-$(SCIPY_DISTUTILS_REV).tar.gz numpy_distutils-latest.tar.gz - mv numpy_distutils-latest.tar.gz upload/tmp/$(MAJOR).x -upload/tmp/$(MAJOR).x/numpy_distutils-latest.win32.exe: numpy_distutils - cd numpy_distutils && python setup.py bdist_wininst - mkdir -p upload/tmp/$(MAJOR).x - cp numpy_distutils/dist/numpy_distutils-$(SCIPY_DISTUTILS_REV).win32.exe upload/tmp/$(MAJOR).x - ln -sf numpy_distutils-$(SCIPY_DISTUTILS_REV).win32.exe numpy_distutils-latest.win32.exe - mv numpy_distutils-latest.win32.exe upload/tmp/$(MAJOR).x - -numpy_distutils_latest: upload/tmp/$(MAJOR).x/numpy_distutils-latest.tar.gz upload/tmp/$(MAJOR).x/numpy_distutils-latest.win32.exe - -latest: f2py2e_latest numpy_distutils_latest - -############################################################################## -# Upload files. -############################################################################## - -upload/www/$(MAJOR).x/F2PY-$(MAJOR)-latest.tar.gz: upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.tar.gz - -mkdir -p `dirname $@` - cp -P upload/tmp/$(MAJOR).x/F2PY-{$(MAJOR)-latest,$(REV)}.tar.gz upload/www/$(MAJOR).x - $(UPLOADCMD) upload/tmp/$(MAJOR).x/F2PY-{$(MAJOR)-latest,$(REV)}.tar.gz $(UPLOADDIR)/$(MAJOR).x/ -upload/www/$(MAJOR).x/numpy_distutils-latest.tar.gz: upload/tmp/$(MAJOR).x/numpy_distutils-latest.tar.gz - -mkdir -p `dirname $@` - cp -P upload/tmp/$(MAJOR).x/numpy_distutils-{latest,$(SCIPY_DISTUTILS_REV)}.tar.gz upload/www/$(MAJOR).x/ - $(UPLOADCMD) upload/tmp/$(MAJOR).x/numpy_distutils-{latest,$(SCIPY_DISTUTILS_REV)}.tar.gz $(UPLOADDIR)/$(MAJOR).x -upload/www/$(MAJOR).x/F2PY-$(MAJOR)-latest.win32.exe: upload/tmp/$(MAJOR).x/F2PY-$(MAJOR)-latest.win32.exe - -mkdir -p `dirname $@` - cp -P upload/tmp/$(MAJOR).x/F2PY-{$(MAJOR)-latest,$(REV)}.win32.exe upload/www/$(MAJOR).x - $(UPLOADCMD) upload/tmp/$(MAJOR).x/F2PY-{$(MAJOR)-latest,$(REV)}.win32.exe $(UPLOADDIR)/$(MAJOR).x/ -upload/www/$(MAJOR).x/numpy_distutils-latest.win32.exe: upload/tmp/$(MAJOR).x/numpy_distutils-latest.win32.exe - -mkdir -p `dirname $@` - cp -P upload/tmp/$(MAJOR).x/numpy_distutils-{latest,$(SCIPY_DISTUTILS_REV)}.win32.exe upload/www/$(MAJOR).x - $(UPLOADCMD) upload/tmp/$(MAJOR).x/numpy_distutils-{latest,$(SCIPY_DISTUTILS_REV)}.win32.exe $(UPLOADDIR)/$(MAJOR).x/ - -upload/tmp/usersguide/index.html: docs/usersguide/index.txt $(UG_FILES_DEP:%=upload/www/usersguide/%) - -mkdir -p upload/tmp/usersguide - rest2html $< $@ -upload/tmp/usersguide/f2py_usersguide.tex: docs/usersguide/index.txt $(UG_FILES_DEP:%=upload/www/usersguide/%) - -mkdir -p upload/tmp/usersguide - rest2latex $< $@ -upload/tmp/usersguide/f2py_usersguide.pdf: upload/tmp/usersguide/f2py_usersguide.tex - cd `dirname $@` && pdflatex `basename $<` -upload/tmp/usersguide/%.f: docs/usersguide/%.f - -mkdir -p upload/tmp/usersguide - cp $< $@ -upload/tmp/usersguide/%.f90: docs/usersguide/%.f90 - -mkdir -p upload/tmp/usersguide - cp $< $@ -upload/tmp/usersguide/%.dat: docs/usersguide/%.dat - -mkdir -p upload/tmp/usersguide - cp $< $@ -upload/tmp/usersguide/%.pyf: docs/usersguide/%.pyf - -mkdir -p upload/tmp/usersguide - cp $< $@ -upload/tmp/usersguide/%.py: docs/usersguide/%.py - -mkdir -p upload/tmp/usersguide - cp $< $@ -upload/www/usersguide/%: upload/tmp/usersguide/% - -mkdir -p `dirname $@` - cp -P $< $@ - $(UPLOADCMD) $@ $(UPLOADDIR)/usersguide - -upload/tmp/FAQ.html: docs/FAQ.txt $(FAQ_DEPS:%=docs/%) - -mkdir -p upload/tmp - rest2html $< $@ -upload/tmp/index.html: docs/README.txt $(README_DEPS:%=docs/%) - -mkdir -p upload/tmp - rest2html $< $@ -upload/tmp/%.f: docs/%.f - -mkdir -p upload/tmp - cp $< $@ -upload/tmp/%.html: docs/%.txt - -mkdir -p upload/tmp - rest2html $< $@ -upload/www/%: upload/tmp/% - -mkdir -p `dirname $@` - cp -P $< $@ - $(UPLOADCMD) $@ $(UPLOADDIR)/ - -upload_web: $(WWW_WEB_FILES) -upload_ug: $(WWW_UG_FILES) -upload_src: $(WWW_SRC_FILES) -upload: upload_src upload_ug upload_web - -generate_web: $(TMP_WEB_FILES) -generate: generate_web - -############################################################################## -# Clean up -############################################################################## -clean: - rm -f {tests/,tests/{f77,f90,mixed}/,docs/,docs/usersguide/,}*.{o,a,so,sl,pyc} - rm -f {tests/,tests/{f77,f90,mixed}/,docs/,docs/usersguide/,}*~ -distclean: clean - rm -f {tests/,src/,}*~ - rm -f tests/*.{f,f90} - rm -rf dist {docs/,docs/usersguide/,}build f2py2e numpy_distutils upload - rm -f MANIFEST f2py?.? f2py - -.PHONY: install test diff --git a/numpy/f2py/NEWS.txt b/numpy/f2py/NEWS.txt deleted file mode 100644 index a4a254405..000000000 --- a/numpy/f2py/NEWS.txt +++ /dev/null @@ -1,2 +0,0 @@ - -Read docs/HISTORY.txt
\ No newline at end of file diff --git a/numpy/f2py/README.txt b/numpy/f2py/README.txt deleted file mode 100644 index ebe7e8c88..000000000 --- a/numpy/f2py/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -====================================================================== - F2PY - Fortran to Python Interface Generator -====================================================================== - -Read docs/README.txt diff --git a/numpy/f2py/TODO.txt b/numpy/f2py/TODO.txt deleted file mode 100644 index 093f0119e..000000000 --- a/numpy/f2py/TODO.txt +++ /dev/null @@ -1,67 +0,0 @@ -Determine fixed/free format Fortran 90 dialect from the -contents of Fortran files. See numpy_distutils/command/build_flib.py. - -[DONE] -======================================================================== -Wrapping F90 code as follows: - -subroutine foo -print*,"In foo" -end subroutine foo -subroutine bar(func) - interface aa ! bug: this interface block is ignored - subroutine foo - end subroutine foo - end interface - !external foo - external func - call func(foo) -end subroutine bar -subroutine gun(a) - external a - call a() -end subroutine gun -subroutine fun - call bar(gun) -end subroutine fun - -========================================================================= -Users Guide needs major revision. - -[DONE] -========================================================================= -On Thu, 27 Sep 2001, José Luis Gómez Dans wrote: - -> Hi, -> just one question: does f2py supporte derived types in F90 code? -> Stuff like something%or and things like that. - -Not yet. - -========================================================================= -Date: Tue, 28 Aug 2001 22:23:04 -0700 -From: Patrick LeGresley <plegresl@ape.stanford.edu> -To: f2py-users@cens.ioc.ee -Subject: [f2py] Strange initialization of allocatable arrays - -I've noticed an odd behavior when setting an allocatable, multidimensional -array in a module. If the rank of the array is odd, the initialization is -fine. However, if the rank is even only the first element of the array is -set properly. See the attached sample code for example. - -========================================================================= -On Wed, 22 Aug 2001, Patrick LeGresley wrote: - -> I've noticed that if a parameter is defined in terms of another parameter, -> that the parameter is replaced not by a number but by another parameter -> (try the attached subroutine for example). Is there any way to have f2py -> automatically recognize the dependencies and generate a signature file -> without parameter variables ? - -It is certainly possible. In fact, f2py has only a basic support for -PARAMETER statements and it fails in your 'advanced' example to produce a -robust signature file. -I am sorry but you have to wait until I'll get back from my travel tour -(somewhere in the middle of September) and get a chance to work on it. - -[DONE] diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py deleted file mode 100644 index 09b0c6e65..000000000 --- a/numpy/f2py/__init__.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -__all__ = ['run_main','compile','f2py_testing'] - -import os -import sys -import commands - -from info import __doc__ - -import f2py2e -run_main = f2py2e.run_main -main = f2py2e.main -import f2py_testing - -def compile(source, - modulename = 'untitled', - extra_args = '', - verbose = 1, - source_fn = None - ): - ''' Build extension module from processing source with f2py. - Read the source of this function for more information. - ''' - from numpy.distutils.exec_command import exec_command - import tempfile - if source_fn is None: - fname = os.path.join(tempfile.mktemp()+'.f') - else: - fname = source_fn - - f = open(fname,'w') - f.write(source) - f.close() - - args = ' -c -m %s %s %s'%(modulename,fname,extra_args) - c = '%s -c "import numpy.f2py as f2py2e;f2py2e.main()" %s' %(sys.executable,args) - s,o = exec_command(c) - if source_fn is None: - try: os.remove(fname) - except OSError: pass - return s diff --git a/numpy/f2py/__version__.py b/numpy/f2py/__version__.py deleted file mode 100644 index 11fb7b3d2..000000000 --- a/numpy/f2py/__version__.py +++ /dev/null @@ -1,9 +0,0 @@ -major = 2 - -try: - from __svn_version__ import version - version_info = (major,version) - version = '%s_%s' % version_info -except Exception,msg: - print msg - version = '%s_?' % (major) diff --git a/numpy/f2py/auxfuncs.py b/numpy/f2py/auxfuncs.py deleted file mode 100644 index b7e5aec68..000000000 --- a/numpy/f2py/auxfuncs.py +++ /dev/null @@ -1,488 +0,0 @@ -#!/usr/bin/env python -""" - -Auxiliary functions for f2py2e. - -Copyright 1999,2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy (BSD style) LICENSE. - - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/07/24 19:01:55 $ -Pearu Peterson -""" -__version__ = "$Revision: 1.65 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import pprint -import sys,string,time,types,os -import cfuncs - - -errmess=sys.stderr.write -#outmess=sys.stdout.write -show=pprint.pprint - -options={} -debugoptions=[] -wrapfuncs = 1 - -def outmess(t): - if options.get('verbose',1): - sys.stdout.write(t) - -def debugcapi(var): return 'capi' in debugoptions -def _isstring(var): - return var.has_key('typespec') and var['typespec']=='character' and (not isexternal(var)) -def isstring(var): - return _isstring(var) and not isarray(var) -def ischaracter(var): - return isstring(var) and not (var.has_key('charselector')) -def isstringarray(var): - return isarray(var) and _isstring(var) -def isarrayofstrings(var): - # leaving out '*' for now so that - # `character*(*) a(m)` and `character a(m,*)` - # are treated differently. Luckily `character**` is illegal. - return isstringarray(var) and var['dimension'][-1]=='(*)' -def isarray(var): return var.has_key('dimension') and (not isexternal(var)) -def isscalar(var): return not (isarray(var) or isstring(var) or isexternal(var)) -def iscomplex(var): - return isscalar(var) and var.get('typespec') in ['complex','double complex'] -def islogical(var): - return isscalar(var) and var.get('typespec')=='logical' -def isinteger(var): - return isscalar(var) and var.get('typespec')=='integer' -def isreal(var): - return isscalar(var) and var.get('typespec')=='real' -def get_kind(var): - try: return var['kindselector']['*'] - except KeyError: - try: return var['kindselector']['kind'] - except KeyError: pass -def islong_long(var): - if not isscalar(var): return 0 - if var.get('typespec') not in ['integer','logical']: return 0 - return get_kind(var)=='8' -def isunsigned_char(var): - if not isscalar(var): return 0 - if var.get('typespec') != 'integer': return 0 - return get_kind(var)=='-1' -def isunsigned_short(var): - if not isscalar(var): return 0 - if var.get('typespec') != 'integer': return 0 - return get_kind(var)=='-2' -def isunsigned(var): - if not isscalar(var): return 0 - if var.get('typespec') != 'integer': return 0 - return get_kind(var)=='-4' -def isunsigned_long_long(var): - if not isscalar(var): return 0 - if var.get('typespec') != 'integer': return 0 - return get_kind(var)=='-8' -def isdouble(var): - if not isscalar(var): return 0 - if not var.get('typespec')=='real': return 0 - return get_kind(var)=='8' -def islong_double(var): - if not isscalar(var): return 0 - if not var.get('typespec')=='real': return 0 - return get_kind(var)=='16' -def islong_complex(var): - if not iscomplex(var): return 0 - return get_kind(var)=='32' - -def iscomplexarray(var): return isarray(var) and var.get('typespec') in ['complex','double complex'] -def isint1array(var): return isarray(var) and var.get('typespec')=='integer' \ - and get_kind(var)=='1' -def isunsigned_chararray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-1' -def isunsigned_shortarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-2' -def isunsignedarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-4' -def isunsigned_long_longarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-8' -def isallocatable(var): - return var.has_key('attrspec') and 'allocatable' in var['attrspec'] -def ismutable(var): return not (not var.has_key('dimension') or isstring(var)) -def ismoduleroutine(rout): return rout.has_key('modulename') -def ismodule(rout): return (rout.has_key('block') and 'module'==rout['block']) -def isfunction(rout): return (rout.has_key('block') and 'function'==rout['block']) -#def isfunction_wrap(rout): -# return wrapfuncs and (iscomplexfunction(rout) or isstringfunction(rout)) and (not isexternal(rout)) -def isfunction_wrap(rout): - if isintent_c(rout): return 0 - return wrapfuncs and isfunction(rout) and (not isexternal(rout)) -def issubroutine(rout): return (rout.has_key('block') and 'subroutine'==rout['block']) -def isroutine(rout): return isfunction(rout) or issubroutine(rout) -def islogicalfunction(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return islogical(rout['vars'][a]) - return 0 -def islong_longfunction(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return islong_long(rout['vars'][a]) - return 0 -def islong_doublefunction(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return islong_double(rout['vars'][a]) - return 0 -def iscomplexfunction(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return iscomplex(rout['vars'][a]) - return 0 -def iscomplexfunction_warn(rout): - if iscomplexfunction(rout): - outmess("""\ - ************************************************************** - Warning: code with a function returning complex value - may not work correctly with your Fortran compiler. - Run the following test before using it in your applications: - $(f2py install dir)/test-site/{b/runme_scalar,e/runme} - When using GNU gcc/g77 compilers, codes should work correctly. - **************************************************************\n""") - return 1 - return 0 -def isstringfunction(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return isstring(rout['vars'][a]) - return 0 -def hasexternals(rout): return rout.has_key('externals') and rout['externals'] -def isthreadsafe(rout): return rout.has_key('f2pyenhancements') and rout['f2pyenhancements'].has_key('threadsafe') -def hasvariables(rout): return rout.has_key('vars') and rout['vars'] -def isoptional(var): return (var.has_key('attrspec') and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var) -def isexternal(var): return (var.has_key('attrspec') and 'external' in var['attrspec']) -def isrequired(var): return not isoptional(var) and isintent_nothide(var) -def isintent_in(var): - if not var.has_key('intent'): return 1 - if 'hide' in var['intent']: return 0 - if 'inplace' in var['intent']: return 0 - if 'in' in var['intent']: return 1 - if 'out' in var['intent']: return 0 - if 'inout' in var['intent']: return 0 - if 'outin' in var['intent']: return 0 - return 1 -def isintent_inout(var): return var.has_key('intent') and ('inout' in var['intent'] or 'outin' in var['intent']) and 'in' not in var['intent'] and 'hide' not in var['intent'] and 'inplace' not in var['intent'] -def isintent_out(var): - return 'out' in var.get('intent',[]) -def isintent_hide(var): return (var.has_key('intent') and ('hide' in var['intent'] or ('out' in var['intent'] and 'in' not in var['intent'] and (not l_or(isintent_inout,isintent_inplace)(var))))) -def isintent_nothide(var): return not isintent_hide(var) -def isintent_c(var): - return 'c' in var.get('intent',[]) -# def isintent_f(var): -# return not isintent_c(var) -def isintent_cache(var): - return 'cache' in var.get('intent',[]) -def isintent_copy(var): - return 'copy' in var.get('intent',[]) -def isintent_overwrite(var): - return 'overwrite' in var.get('intent',[]) -def isintent_callback(var): - return 'callback' in var.get('intent',[]) -def isintent_inplace(var): - return 'inplace' in var.get('intent',[]) -def isintent_aux(var): - return 'aux' in var.get('intent',[]) - -isintent_dict = {isintent_in:'INTENT_IN',isintent_inout:'INTENT_INOUT', - isintent_out:'INTENT_OUT',isintent_hide:'INTENT_HIDE', - isintent_cache:'INTENT_CACHE', - isintent_c:'INTENT_C',isoptional:'OPTIONAL', - isintent_inplace:'INTENT_INPLACE' - } - -def isprivate(var): - return var.has_key('attrspec') and 'private' in var['attrspec'] - -def hasinitvalue(var): return var.has_key('=') -def hasinitvalueasstring(var): - if not hasinitvalue(var): return 0 - return var['='][0] in ['"',"'"] -def hasnote(var): - return var.has_key('note') -def hasresultnote(rout): - if not isfunction(rout): return 0 - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if rout['vars'].has_key(a): return hasnote(rout['vars'][a]) - return 0 -def hascommon(rout): - return rout.has_key('common') -def containscommon(rout): - if hascommon(rout): return 1 - if hasbody(rout): - for b in rout['body']: - if containscommon(b): return 1 - return 0 -def containsmodule(block): - if ismodule(block): return 1 - if not hasbody(block): return 0 - ret = [] - for b in block['body']: - if containsmodule(b): return 1 - return 0 -def hasbody(rout): - return rout.has_key('body') -def hascallstatement(rout): - return getcallstatement(rout) is not None - -def istrue(var): return 1 -def isfalse(var): return 0 - -class F2PYError(Exception): - pass - -class throw_error: - def __init__(self,mess): - self.mess = mess - def __call__(self,var): - mess = '\n\n var = %s\n Message: %s\n' % (var,self.mess) - raise F2PYError,mess - -def l_and(*f): - l,l2='lambda v',[] - for i in range(len(f)): - l='%s,f%d=f[%d]'%(l,i,i) - l2.append('f%d(v)'%(i)) - return eval('%s:%s'%(l,string.join(l2,' and '))) -def l_or(*f): - l,l2='lambda v',[] - for i in range(len(f)): - l='%s,f%d=f[%d]'%(l,i,i) - l2.append('f%d(v)'%(i)) - return eval('%s:%s'%(l,string.join(l2,' or '))) -def l_not(f): - return eval('lambda v,f=f:not f(v)') - -def isdummyroutine(rout): - try: - return rout['f2pyenhancements']['fortranname']=='' - except KeyError: - return 0 - -def getfortranname(rout): - try: - name = rout['f2pyenhancements']['fortranname'] - if name=='': - raise KeyError - if not name: - errmess('Failed to use fortranname from %s\n'%(rout['f2pyenhancements'])) - raise KeyError - except KeyError: - name = rout['name'] - return name - -def getmultilineblock(rout,blockname,comment=1,counter=0): - try: - r = rout['f2pyenhancements'].get(blockname) - except KeyError: - return - if not r: return - if counter>0 and type(r) is type(''): - return - if type(r) is type([]): - if counter>=len(r): return - r = r[counter] - if r[:3]=="'''": - if comment: - r = '\t/* start ' + blockname + ' multiline ('+`counter`+') */\n' + r[3:] - else: - r = r[3:] - if r[-3:]=="'''": - if comment: - r = r[:-3] + '\n\t/* end multiline ('+`counter`+')*/' - else: - r = r[:-3] - else: - errmess("%s multiline block should end with `'''`: %s\n" \ - % (blockname,repr(r))) - return r - -def getcallstatement(rout): - return getmultilineblock(rout,'callstatement') - -def getcallprotoargument(rout,cb_map={}): - r = getmultilineblock(rout,'callprotoargument',comment=0) - if r: return r - if hascallstatement(rout): - outmess('warning: callstatement is defined without callprotoargument\n') - return - from capi_maps import getctype - arg_types,arg_types2 = [],[] - if l_and(isstringfunction,l_not(isfunction_wrap))(rout): - arg_types.extend(['char*','size_t']) - for n in rout['args']: - var = rout['vars'][n] - if isintent_callback(var): - continue - if cb_map.has_key(n): - ctype = cb_map[n]+'_typedef' - else: - ctype = getctype(var) - if l_and(isintent_c,l_or(isscalar,iscomplex))(var): - pass - elif isstring(var): - pass - #ctype = 'void*' - else: - ctype = ctype+'*' - if isstring(var) or isarrayofstrings(var): - arg_types2.append('size_t') - arg_types.append(ctype) - - proto_args = string.join(arg_types+arg_types2,',') - if not proto_args: - proto_args = 'void' - #print proto_args - return proto_args - -def getusercode(rout): - return getmultilineblock(rout,'usercode') -def getusercode1(rout): - return getmultilineblock(rout,'usercode',counter=1) - -def getpymethoddef(rout): - return getmultilineblock(rout,'pymethoddef') - -def getargs(rout): - sortargs,args=[],[] - if rout.has_key('args'): - args=rout['args'] - if rout.has_key('sortvars'): - for a in rout['sortvars']: - if a in args: sortargs.append(a) - for a in args: - if a not in sortargs: - sortargs.append(a) - else: sortargs=rout['args'] - return args,sortargs - -def getargs2(rout): - sortargs,args=[],rout.get('args',[]) - auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])\ - and a not in args] - args = auxvars + args - if rout.has_key('sortvars'): - for a in rout['sortvars']: - if a in args: sortargs.append(a) - for a in args: - if a not in sortargs: - sortargs.append(a) - else: sortargs=auxvars + rout['args'] - return args,sortargs - -def getrestdoc(rout): - if not rout.has_key('f2pymultilines'): - return None - k = None - if rout['block']=='python module': - k = rout['block'],rout['name'] - return rout['f2pymultilines'].get(k,None) - -def gentitle(name): - l=(80-len(name)-6)/2 - return '/*%s %s %s*/'%(l*'*',name,l*'*') -def flatlist(l): - if type(l)==types.ListType: - return reduce(lambda x,y,f=flatlist:x+f(y),l,[]) - return [l] -def stripcomma(s): - if s and s[-1]==',': return s[:-1] - return s -def replace(str,dict,defaultsep=''): - if type(dict)==types.ListType: - return map(lambda d,f=replace,sep=defaultsep,s=str:f(s,d,sep),dict) - if type(str)==types.ListType: - return map(lambda s,f=replace,sep=defaultsep,d=dict:f(s,d,sep),str) - for k in 2*dict.keys(): - if k=='separatorsfor': continue - if dict.has_key('separatorsfor') and dict['separatorsfor'].has_key(k): - sep=dict['separatorsfor'][k] - else: - sep=defaultsep - if type(dict[k])==types.ListType: - str=string.replace(str,'#%s#'%(k),string.join(flatlist(dict[k]),sep)) - else: - str=string.replace(str,'#%s#'%(k),dict[k]) - return str - -def dictappend(rd,ar): - if type(ar)==types.ListType: - for a in ar: rd=dictappend(rd,a) - return rd - for k in ar.keys(): - if k[0]=='_': continue - if rd.has_key(k): - if type(rd[k])==types.StringType: rd[k]=[rd[k]] - if type(rd[k])==types.ListType: - if type(ar[k])==types.ListType: rd[k]=rd[k]+ar[k] - else: rd[k].append(ar[k]) - elif type(rd[k])==types.DictType: - if type(ar[k])==types.DictType: - if k=='separatorsfor': - for k1 in ar[k].keys(): - if not rd[k].has_key(k1): rd[k][k1]=ar[k][k1] - else: rd[k]=dictappend(rd[k],ar[k]) - else: rd[k]=ar[k] - return rd - -def applyrules(rules,dict,var={}): - ret={} - if type(rules)==types.ListType: - for r in rules: - rr=applyrules(r,dict,var) - ret=dictappend(ret,rr) - if rr.has_key('_break'): break - return ret - if rules.has_key('_check') and (not rules['_check'](var)): return ret - if rules.has_key('need'): - res = applyrules({'needs':rules['need']},dict,var) - if res.has_key('needs'): - cfuncs.append_needs(res['needs']) - - for k in rules.keys(): - if k=='separatorsfor': ret[k]=rules[k]; continue - if type(rules[k])==types.StringType: - ret[k]=replace(rules[k],dict) - elif type(rules[k])==types.ListType: - ret[k]=[] - for i in rules[k]: - ar=applyrules({k:i},dict,var) - if ar.has_key(k): ret[k].append(ar[k]) - elif k[0]=='_': - continue - elif type(rules[k])==types.DictType: - ret[k]=[] - for k1 in rules[k].keys(): - if type(k1)==types.FunctionType and k1(var): - if type(rules[k][k1])==types.ListType: - for i in rules[k][k1]: - if type(i)==types.DictType: - res=applyrules({'supertext':i},dict,var) - if res.has_key('supertext'): i=res['supertext'] - else: i='' - ret[k].append(replace(i,dict)) - else: - i=rules[k][k1] - if type(i)==types.DictType: - res=applyrules({'supertext':i},dict) - if res.has_key('supertext'): i=res['supertext'] - else: i='' - ret[k].append(replace(i,dict)) - else: - errmess('applyrules: ignoring rule %s.\n'%`rules[k]`) - if type(ret[k])==types.ListType: - if len(ret[k])==1: ret[k]=ret[k][0] - if ret[k]==[]: del ret[k] - return ret diff --git a/numpy/f2py/capi_maps.py b/numpy/f2py/capi_maps.py deleted file mode 100644 index 2cd42b04a..000000000 --- a/numpy/f2py/capi_maps.py +++ /dev/null @@ -1,721 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 1999,2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/05/06 10:57:33 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.60 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import string,copy,re,os -from auxfuncs import * -from crackfortran import markoutercomma -import cb_rules - -# Numarray and Numeric users should set this False -using_newcore = True - -depargs=[] -lcb_map={} -lcb2_map={} -# forced casting: mainly caused by the fact that Python or Numeric -# C/APIs do not support the corresponding C types. -c2py_map={'double':'float', - 'float':'float', # forced casting - 'long_double':'float', # forced casting - 'char':'int', # forced casting - 'signed_char':'int', # forced casting - 'unsigned_char':'int', # forced casting - 'short':'int', # forced casting - 'unsigned_short':'int', # forced casting - 'int':'int', # (forced casting) - 'long':'int', - 'long_long':'long', - 'unsigned':'int', # forced casting - 'complex_float':'complex', # forced casting - 'complex_double':'complex', - 'complex_long_double':'complex', # forced casting - 'string':'string', - } -c2capi_map={'double':'PyArray_DOUBLE', - 'float':'PyArray_FLOAT', - 'long_double':'PyArray_DOUBLE', # forced casting - 'char':'PyArray_CHAR', - 'unsigned_char':'PyArray_UBYTE', - 'signed_char':'PyArray_SBYTE', - 'short':'PyArray_SHORT', - 'unsigned_short':'PyArray_USHORT', - 'int':'PyArray_INT', - 'unsigned':'PyArray_UINT', - 'long':'PyArray_LONG', - 'long_long':'PyArray_LONG', # forced casting - 'complex_float':'PyArray_CFLOAT', - 'complex_double':'PyArray_CDOUBLE', - 'complex_long_double':'PyArray_CDOUBLE', # forced casting - 'string':'PyArray_CHAR'} - -#These new maps aren't used anyhere yet, but should be by default -# unless building numeric or numarray extensions. -if using_newcore: - c2capi_map={'double':'PyArray_DOUBLE', - 'float':'PyArray_FLOAT', - 'long_double':'PyArray_LONGDOUBLE', - 'char':'PyArray_BYTE', - 'unsigned_char':'PyArray_UBYTE', - 'signed_char':'PyArray_BYTE', - 'short':'PyArray_SHORT', - 'unsigned_short':'PyArray_USHORT', - 'int':'PyArray_INT', - 'unsigned':'PyArray_UINT', - 'long':'PyArray_LONG', - 'unsigned_long':'PyArray_ULONG', - 'long_long':'PyArray_LONGLONG', - 'unsigned_long_long':'Pyarray_ULONGLONG', - 'complex_float':'PyArray_CFLOAT', - 'complex_double':'PyArray_CDOUBLE', - 'complex_long_double':'PyArray_CDOUBLE', - 'string':'PyArray_STRING'} -c2pycode_map={'double':'d', - 'float':'f', - 'long_double':'d', # forced casting - 'char':'1', - 'signed_char':'1', - 'unsigned_char':'b', - 'short':'s', - 'unsigned_short':'w', - 'int':'i', - 'unsigned':'u', - 'long':'l', - 'long_long':'L', - 'complex_float':'F', - 'complex_double':'D', - 'complex_long_double':'D', # forced casting - 'string':'c' - } -if using_newcore: - c2pycode_map={'double':'d', - 'float':'f', - 'long_double':'g', - 'char':'b', - 'unsigned_char':'B', - 'signed_char':'b', - 'short':'h', - 'unsigned_short':'H', - 'int':'i', - 'unsigned':'I', - 'long':'l', - 'unsigned_long':'L', - 'long_long':'q', - 'unsigned_long_long':'Q', - 'complex_float':'F', - 'complex_double':'D', - 'complex_long_double':'G', - 'string':'S'} -c2buildvalue_map={'double':'d', - 'float':'f', - 'char':'b', - 'signed_char':'b', - 'short':'h', - 'int':'i', - 'long':'l', - 'long_long':'L', - 'complex_float':'N', - 'complex_double':'N', - 'complex_long_double':'N', - 'string':'z'} -if using_newcore: - #c2buildvalue_map=??? - pass - -f2cmap_all={'real':{'':'float','4':'float','8':'double','12':'long_double','16':'long_double'}, - 'integer':{'':'int','1':'signed_char','2':'short','4':'int','8':'long_long', - '-1':'unsigned_char','-2':'unsigned_short','-4':'unsigned', - '-8':'unsigned_long_long'}, - 'complex':{'':'complex_float','8':'complex_float', - '16':'complex_double','24':'complex_long_double', - '32':'complex_long_double'}, - 'complexkind':{'':'complex_float','4':'complex_float', - '8':'complex_double','12':'complex_long_double', - '16':'complex_long_double'}, - 'logical':{'':'int','1':'char','2':'short','4':'int','8':'long_long'}, - 'double complex':{'':'complex_double'}, - 'double precision':{'':'double'}, - 'byte':{'':'char'}, - 'character':{'':'string'} - } - -if os.path.isfile('.f2py_f2cmap'): - # User defined additions to f2cmap_all. - # .f2py_f2cmap must contain a dictionary of dictionaries, only. - # For example, {'real':{'low':'float'}} means that Fortran 'real(low)' is - # interpreted as C 'float'. - # This feature is useful for F90/95 users if they use PARAMETERSs - # in type specifications. - try: - outmess('Reading .f2py_f2cmap ...\n') - f = open('.f2py_f2cmap','r') - d = eval(f.read(),{},{}) - f.close() - for k,d1 in d.items(): - for k1 in d1.keys(): - d1[string.lower(k1)] = d1[k1] - d[string.lower(k)] = d[k] - for k in d.keys(): - if not f2cmap_all.has_key(k): f2cmap_all[k]={} - for k1 in d[k].keys(): - if c2py_map.has_key(d[k][k1]): - if f2cmap_all[k].has_key(k1): - outmess("\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n"%(k,k1,f2cmap_all[k][k1],d[k][k1])) - f2cmap_all[k][k1] = d[k][k1] - outmess('\tMapping "%s(kind=%s)" to "%s"\n' % (k,k1,d[k][k1])) - else: - errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n"%(k,k1,d[k][k1],d[k][k1],c2py_map.keys())) - outmess('Succesfully applied user defined changes from .f2py_f2cmap\n') - except: - errmess('Failed to apply user defined changes from .f2py_f2cmap. Skipping.\n') -cformat_map={'double':'%g', - 'float':'%g', - 'long_double':'%Lg', - 'char':'%d', - 'signed_char':'%d', - 'unsigned_char':'%hhu', - 'short':'%hd', - 'unsigned_short':'%hu', - 'int':'%d', - 'unsigned':'%u', - 'long':'%ld', - 'unsigned_long':'%lu', - 'long_long':'%ld', - 'complex_float':'(%g,%g)', - 'complex_double':'(%g,%g)', - 'complex_long_double':'(%Lg,%Lg)', - 'string':'%s', - } - -############### Auxiliary functions -def getctype(var): - """ - Determines C type - """ - ctype='void' - if isfunction(var): - if var.has_key('result'): a=var['result'] - else: a=var['name'] - if var['vars'].has_key(a): return getctype(var['vars'][a]) - else: errmess('getctype: function %s has no return value?!\n'%a) - elif issubroutine(var): - return ctype - elif var.has_key('typespec') and f2cmap_all.has_key(string.lower(var['typespec'])): - typespec = string.lower(var['typespec']) - f2cmap=f2cmap_all[typespec] - ctype=f2cmap[''] # default type - if var.has_key('kindselector'): - if var['kindselector'].has_key('*'): - try: - ctype=f2cmap[var['kindselector']['*']] - except KeyError: - errmess('getctype: "%s %s %s" not supported.\n'%(var['typespec'],'*',var['kindselector']['*'])) - elif var['kindselector'].has_key('kind'): - if f2cmap_all.has_key(typespec+'kind'): - f2cmap=f2cmap_all[typespec+'kind'] - try: - ctype=f2cmap[var['kindselector']['kind']] - except KeyError: - if f2cmap_all.has_key(typespec): - f2cmap=f2cmap_all[typespec] - try: - ctype=f2cmap[str(var['kindselector']['kind'])] - except KeyError: - errmess('getctype: "%s(kind=%s)" not supported (use .f2py_f2cmap).\n'\ - %(typespec,var['kindselector']['kind'])) - - else: - if not isexternal(var): - errmess('getctype: No C-type found in "%s", assuming void.\n'%var) - return ctype -def getstrlength(var): - if isstringfunction(var): - if var.has_key('result'): a=var['result'] - else: a=var['name'] - if var['vars'].has_key(a): return getstrlength(var['vars'][a]) - else: errmess('getstrlength: function %s has no return value?!\n'%a) - if not isstring(var): - errmess('getstrlength: expected a signature of a string but got: %s\n'%(`var`)) - len='1' - if var.has_key('charselector'): - a=var['charselector'] - if a.has_key('*'): len=a['*'] - elif a.has_key('len'): len=a['len'] - if re.match(r'\(\s*([*]|[:])\s*\)',len) or re.match(r'([*]|[:])',len): - #if len in ['(*)','*','(:)',':']: - if isintent_hide(var): - errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n'%(`var`)) - len='-1' - return len -def getarrdims(a,var,verbose=0): - global depargs - ret={} - if isstring(var) and not isarray(var): - ret['dims']=getstrlength(var) - ret['size']=ret['dims'] - ret['rank']='1' - elif isscalar(var): - ret['size']='1' - ret['rank']='0' - ret['dims']='' - elif isarray(var): -# if not isintent_c(var): -# var['dimension'].reverse() - dim=copy.copy(var['dimension']) - ret['size']=string.join(dim,'*') - try: ret['size']=`eval(ret['size'])` - except: pass - ret['dims']=string.join(dim,',') - ret['rank']=`len(dim)` - ret['rank*[-1]']=`len(dim)*[-1]`[1:-1] - for i in range(len(dim)): # solve dim for dependecies - v=[] - if dim[i] in depargs: v=[dim[i]] - else: - for va in depargs: - if re.match(r'.*?\b%s\b.*'%va,dim[i]): - v.append(va) - for va in v: - if depargs.index(va)>depargs.index(a): - dim[i]='*' - break - ret['setdims'],i='',-1 - for d in dim: - i=i+1 - if d not in ['*',':','(*)','(:)']: - ret['setdims']='%s#varname#_Dims[%d]=%s,'%(ret['setdims'],i,d) - if ret['setdims']: ret['setdims']=ret['setdims'][:-1] - ret['cbsetdims'],i='',-1 - for d in var['dimension']: - i=i+1 - if d not in ['*',':','(*)','(:)']: - ret['cbsetdims']='%s#varname#_Dims[%d]=%s,'%(ret['cbsetdims'],i,d) - elif verbose : - errmess('getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n'%(`a`,`d`)) - if ret['cbsetdims']: ret['cbsetdims']=ret['cbsetdims'][:-1] -# if not isintent_c(var): -# var['dimension'].reverse() - return ret -def getpydocsign(a,var): - global lcb_map - if isfunction(var): - if var.has_key('result'): af=var['result'] - else: af=var['name'] - if var['vars'].has_key(af): return getpydocsign(af,var['vars'][af]) - else: errmess('getctype: function %s has no return value?!\n'%af) - return '','' - sig,sigout=a,a - opt='' - if isintent_in(var): opt='input' - elif isintent_inout(var): opt='in/output' - out_a = a - if isintent_out(var): - for k in var['intent']: - if k[:4]=='out=': - out_a = k[4:] - break - init='' - ctype=getctype(var) - - if hasinitvalue(var): - init,showinit=getinit(a,var) - init='= %s'%(showinit) - if isscalar(var): - if isintent_inout(var): - sig='%s :%s %s rank-0 array(%s,\'%s\')'%(a,init,opt,c2py_map[ctype], - c2pycode_map[ctype],) - else: - sig='%s :%s %s %s'%(a,init,opt,c2py_map[ctype]) - sigout='%s : %s'%(out_a,c2py_map[ctype]) - elif isstring(var): - if isintent_inout(var): - sig='%s :%s %s rank-0 array(string(len=%s),\'c\')'%(a,init,opt,getstrlength(var)) - else: - sig='%s :%s %s string(len=%s)'%(a,init,opt,getstrlength(var)) - sigout='%s : string(len=%s)'%(out_a,getstrlength(var)) - elif isarray(var): - dim=var['dimension'] - rank=`len(dim)` - sig='%s :%s %s rank-%s array(\'%s\') with bounds (%s)'%(a,init,opt,rank, - c2pycode_map[ctype], - string.join(dim,',')) - if a==out_a: - sigout='%s : rank-%s array(\'%s\') with bounds (%s)'\ - %(a,rank,c2pycode_map[ctype],string.join(dim,',')) - else: - sigout='%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\ - %(out_a,rank,c2pycode_map[ctype],string.join(dim,','),a) - elif isexternal(var): - ua='' - if lcb_map.has_key(a) and lcb2_map.has_key(lcb_map[a]) and lcb2_map[lcb_map[a]].has_key('argname'): - ua=lcb2_map[lcb_map[a]]['argname'] - if not ua==a: ua=' => %s'%ua - else: ua='' - sig='%s : call-back function%s'%(a,ua) - sigout=sig - else: - errmess('getpydocsign: Could not resolve docsignature for "%s".\\n'%a) - return sig,sigout -def getarrdocsign(a,var): - ctype=getctype(var) - if isstring(var) and (not isarray(var)): - sig='%s : rank-0 array(string(len=%s),\'c\')'%(a,getstrlength(var)) - elif isscalar(var): - sig='%s : rank-0 array(%s,\'%s\')'%(a,c2py_map[ctype], - c2pycode_map[ctype],) - elif isarray(var): - dim=var['dimension'] - rank=`len(dim)` - sig='%s : rank-%s array(\'%s\') with bounds (%s)'%(a,rank, - c2pycode_map[ctype], - string.join(dim,',')) - return sig - -def getinit(a,var): - if isstring(var): init,showinit='""',"''" - else: init,showinit='','' - if hasinitvalue(var): - init=var['='] - showinit=init - if iscomplex(var) or iscomplexarray(var): - ret={} - - try: - v = var["="] - if ',' in v: - ret['init.r'],ret['init.i']=string.split(markoutercomma(v[1:-1]),'@,@') - else: - v = eval(v,{},{}) - ret['init.r'],ret['init.i']=str(v.real),str(v.imag) - except: raise 'sign2map: expected complex number `(r,i)\' but got `%s\' as initial value of %s.'%(init,`a`) - if isarray(var): - init='(capi_c.r=%s,capi_c.i=%s,capi_c)'%(ret['init.r'],ret['init.i']) - elif isstring(var): - if not init: init,showinit='""',"''" - if init[0]=="'": - init='"%s"'%(string.replace(init[1:-1],'"','\\"')) - if init[0]=='"': showinit="'%s'"%(init[1:-1]) - return init,showinit - -def sign2map(a,var): - """ - varname,ctype,atype - init,init.r,init.i,pytype - vardebuginfo,vardebugshowvalue,varshowvalue - varrfromat - intent - """ - global lcb_map,cb_map - out_a = a - if isintent_out(var): - for k in var['intent']: - if k[:4]=='out=': - out_a = k[4:] - break - ret={'varname':a,'outvarname':out_a} - ret['ctype']=getctype(var) - intent_flags = [] - for f,s in isintent_dict.items(): - if f(var): intent_flags.append('F2PY_%s'%s) - if intent_flags: - #XXX: Evaluate intent_flags here. - ret['intent'] = string.join(intent_flags,'|') - else: - ret['intent'] = 'F2PY_INTENT_IN' - if isarray(var): ret['varrformat']='N' - elif c2buildvalue_map.has_key(ret['ctype']): - ret['varrformat']=c2buildvalue_map[ret['ctype']] - else: ret['varrformat']='O' - ret['init'],ret['showinit']=getinit(a,var) - if hasinitvalue(var) and iscomplex(var) and not isarray(var): - ret['init.r'],ret['init.i'] = string.split(markoutercomma(ret['init'][1:-1]),'@,@') - if isexternal(var): - ret['cbnamekey']=a - if lcb_map.has_key(a): - ret['cbname']=lcb_map[a] - ret['maxnofargs']=lcb2_map[lcb_map[a]]['maxnofargs'] - ret['nofoptargs']=lcb2_map[lcb_map[a]]['nofoptargs'] - ret['cbdocstr']=lcb2_map[lcb_map[a]]['docstr'] - ret['cblatexdocstr']=lcb2_map[lcb_map[a]]['latexdocstr'] - else: - ret['cbname']=a - errmess('sign2map: Confused: external %s is not in lcb_map%s.\n'%(a,lcb_map.keys())) - if isstring(var): - ret['length']=getstrlength(var) - if isarray(var): - ret=dictappend(ret,getarrdims(a,var)) - dim=copy.copy(var['dimension']) - if c2capi_map.has_key(ret['ctype']): ret['atype']=c2capi_map[ret['ctype']] - # Debug info - if debugcapi(var): - il=[isintent_in,'input',isintent_out,'output', - isintent_inout,'inoutput',isrequired,'required', - isoptional,'optional',isintent_hide,'hidden', - iscomplex,'complex scalar', - l_and(isscalar,l_not(iscomplex)),'scalar', - isstring,'string',isarray,'array', - iscomplexarray,'complex array',isstringarray,'string array', - iscomplexfunction,'complex function', - l_and(isfunction,l_not(iscomplexfunction)),'function', - isexternal,'callback', - isintent_callback,'callback', - isintent_aux,'auxiliary', - #ismutable,'mutable',l_not(ismutable),'immutable', - ] - rl=[] - for i in range(0,len(il),2): - if il[i](var): rl.append(il[i+1]) - if isstring(var): - rl.append('slen(%s)=%s'%(a,ret['length'])) - if isarray(var): -# if not isintent_c(var): -# var['dimension'].reverse() - ddim=string.join(map(lambda x,y:'%s|%s'%(x,y),var['dimension'],dim),',') - rl.append('dims(%s)'%ddim) -# if not isintent_c(var): -# var['dimension'].reverse() - if isexternal(var): - ret['vardebuginfo']='debug-capi:%s=>%s:%s'%(a,ret['cbname'],string.join(rl,',')) - else: - ret['vardebuginfo']='debug-capi:%s %s=%s:%s'%(ret['ctype'],a,ret['showinit'],string.join(rl,',')) - if isscalar(var): - if cformat_map.has_key(ret['ctype']): - ret['vardebugshowvalue']='debug-capi:%s=%s'%(a,cformat_map[ret['ctype']]) - if isstring(var): - ret['vardebugshowvalue']='debug-capi:slen(%s)=%%d %s=\\"%%s\\"'%(a,a) - if isexternal(var): - ret['vardebugshowvalue']='debug-capi:%s=%%p'%(a) - if cformat_map.has_key(ret['ctype']): - ret['varshowvalue']='#name#:%s=%s'%(a,cformat_map[ret['ctype']]) - ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) - if isstring(var): - ret['varshowvalue']='#name#:slen(%s)=%%d %s=\\"%%s\\"'%(a,a) - ret['pydocsign'],ret['pydocsignout']=getpydocsign(a,var) - if hasnote(var): - ret['note']=var['note'] - return ret - -def routsign2map(rout): - """ - name,NAME,begintitle,endtitle - rname,ctype,rformat - routdebugshowvalue - """ - global lcb_map - name = rout['name'] - fname = getfortranname(rout) - ret={'name':name, - 'texname':string.replace(name,'_','\\_'), - 'name_lower':string.lower(name), - 'NAME':string.upper(name), - 'begintitle':gentitle(name), - 'endtitle':gentitle('end of %s'%name), - 'fortranname':fname, - 'FORTRANNAME':string.upper(fname), - 'callstatement':getcallstatement(rout) or '', - 'usercode':getusercode(rout) or '', - 'usercode1':getusercode1(rout) or '', - } - if '_' in fname: - ret['F_FUNC'] = 'F_FUNC_US' - else: - ret['F_FUNC'] = 'F_FUNC' - if '_' in name: - ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US' - else: - ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC' - lcb_map={} - if rout.has_key('use'): - for u in rout['use'].keys(): - if cb_rules.cb_map.has_key(u): - for un in cb_rules.cb_map[u]: - ln=un[0] - if rout['use'][u].has_key('map'): - for k in rout['use'][u]['map'].keys(): - if rout['use'][u]['map'][k]==un[0]: ln=k;break - lcb_map[ln]=un[1] - #else: - # errmess('routsign2map: cb_map does not contain module "%s" used in "use" statement.\n'%(u)) - elif rout.has_key('externals') and rout['externals']: - errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n'%(ret['name'],`rout['externals']`)) - ret['callprotoargument'] = getcallprotoargument(rout,lcb_map) or '' - if isfunction(rout): - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - ret['rname']=a - ret['pydocsign'],ret['pydocsignout']=getpydocsign(a,rout) - ret['ctype']=getctype(rout['vars'][a]) - if hasresultnote(rout): - ret['resultnote']=rout['vars'][a]['note'] - rout['vars'][a]['note']=['See elsewhere.'] - if c2buildvalue_map.has_key(ret['ctype']): - ret['rformat']=c2buildvalue_map[ret['ctype']] - else: - ret['rformat']='O' - errmess('routsign2map: no c2buildvalue key for type %s\n'%(`ret['ctype']`)) - if debugcapi(rout): - if cformat_map.has_key(ret['ctype']): - ret['routdebugshowvalue']='debug-capi:%s=%s'%(a,cformat_map[ret['ctype']]) - if isstringfunction(rout): - ret['routdebugshowvalue']='debug-capi:slen(%s)=%%d %s=\\"%%s\\"'%(a,a) - if isstringfunction(rout): - ret['rlength']=getstrlength(rout['vars'][a]) - if ret['rlength']=='-1': - errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n'%(`rout['name']`)) - ret['rlength']='10' - if hasnote(rout): - ret['note']=rout['note'] - rout['note']=['See elsewhere.'] - return ret - -def modsign2map(m): - """ - modulename - """ - if ismodule(m): - ret={'f90modulename':m['name'], - 'F90MODULENAME':string.upper(m['name']), - 'texf90modulename':string.replace(m['name'],'_','\\_')} - else: - ret={'modulename':m['name'], - 'MODULENAME':string.upper(m['name']), - 'texmodulename':string.replace(m['name'],'_','\\_')} - ret['restdoc'] = getrestdoc(m) or [] - if hasnote(m): - ret['note']=m['note'] - #m['note']=['See elsewhere.'] - ret['usercode'] = getusercode(m) or '' - ret['usercode1'] = getusercode1(m) or '' - if m['body']: - ret['interface_usercode'] = getusercode(m['body'][0]) or '' - else: - ret['interface_usercode'] = '' - ret['pymethoddef'] = getpymethoddef(m) or '' - return ret - -def cb_sign2map(a,var): - ret={'varname':a} - ret['ctype']=getctype(var) - if c2capi_map.has_key(ret['ctype']): - ret['atype']=c2capi_map[ret['ctype']] - if cformat_map.has_key(ret['ctype']): - ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) - if isarray(var): - ret=dictappend(ret,getarrdims(a,var)) - ret['pydocsign'],ret['pydocsignout']=getpydocsign(a,var) - if hasnote(var): - ret['note']=var['note'] - var['note']=['See elsewhere.'] - return ret - -def cb_routsign2map(rout,um): - """ - name,begintitle,endtitle,argname - ctype,rctype,maxnofargs,nofoptargs,returncptr - """ - ret={'name':'cb_%s_in_%s'%(rout['name'],um), - 'returncptr':''} - if isintent_callback(rout): - if '_' in rout['name']: - F_FUNC='F_FUNC_US' - else: - F_FUNC='F_FUNC' - ret['callbackname'] = '%s(%s,%s)' \ - % (F_FUNC, - rout['name'].lower(), - rout['name'].upper(), - ) - ret['static'] = 'extern' - else: - ret['callbackname'] = ret['name'] - ret['static'] = 'static' - ret['argname']=rout['name'] - ret['begintitle']=gentitle(ret['name']) - ret['endtitle']=gentitle('end of %s'%ret['name']) - ret['ctype']=getctype(rout) - ret['rctype']='void' - if ret['ctype']=='string': ret['rctype']='void' - else: - ret['rctype']=ret['ctype'] - if ret['rctype']!='void': - if iscomplexfunction(rout): - ret['returncptr'] = """ -#ifdef F2PY_CB_RETURNCOMPLEX -return_value= -#endif -""" - else: - ret['returncptr'] = 'return_value=' - if cformat_map.has_key(ret['ctype']): - ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) - if isstringfunction(rout): - ret['strlength']=getstrlength(rout) - if isfunction(rout): - if rout.has_key('result'): a=rout['result'] - else: a=rout['name'] - if hasnote(rout['vars'][a]): - ret['note']=rout['vars'][a]['note'] - rout['vars'][a]['note']=['See elsewhere.'] - ret['rname']=a - ret['pydocsign'],ret['pydocsignout']=getpydocsign(a,rout) - if iscomplexfunction(rout): - ret['rctype']=""" -#ifdef F2PY_CB_RETURNCOMPLEX -#ctype# -#else -void -#endif -""" - else: - if hasnote(rout): - ret['note']=rout['note'] - rout['note']=['See elsewhere.'] - nofargs=0 - nofoptargs=0 - if rout.has_key('args') and rout.has_key('vars'): - for a in rout['args']: - var=rout['vars'][a] - if l_or(isintent_in,isintent_inout)(var): - nofargs=nofargs+1 - if isoptional(var): - nofoptargs=nofoptargs+1 - ret['maxnofargs']=`nofargs` - ret['nofoptargs']=`nofoptargs` - if hasnote(rout) and isfunction(rout) and rout.has_key('result'): - ret['routnote']=rout['note'] - rout['note']=['See elsewhere.'] - return ret - -def common_sign2map(a,var): # obsolute - ret={'varname':a} - ret['ctype']=getctype(var) - if isstringarray(var): ret['ctype']='char' - if c2capi_map.has_key(ret['ctype']): - ret['atype']=c2capi_map[ret['ctype']] - if cformat_map.has_key(ret['ctype']): - ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) - if isarray(var): - ret=dictappend(ret,getarrdims(a,var)) - elif isstring(var): - ret['size']=getstrlength(var) - ret['rank']='1' - ret['pydocsign'],ret['pydocsignout']=getpydocsign(a,var) - if hasnote(var): - ret['note']=var['note'] - var['note']=['See elsewhere.'] - ret['arrdocstr']=getarrdocsign(a,var) # for strings this returns 0-rank but actually is 1-rank - return ret diff --git a/numpy/f2py/cb_rules.py b/numpy/f2py/cb_rules.py deleted file mode 100644 index df74703ba..000000000 --- a/numpy/f2py/cb_rules.py +++ /dev/null @@ -1,529 +0,0 @@ -#!/usr/bin/env python -""" - -Build call-back mechanism for f2py2e. - -Copyright 2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/07/20 11:27:58 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.53 $"[10:-1] - -import __version__ -f2py_version = __version__.version - - -import pprint -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -import capi_maps -#from capi_maps import * -import cfuncs - -################## Rules for callback function ############## - -cb_routine_rules={ - 'cbtypedefs':'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);', - 'body':""" -#begintitle# -PyObject *#name#_capi = NULL;/*was Py_None*/ -PyTupleObject *#name#_args_capi = NULL; -int #name#_nofargs = 0; -jmp_buf #name#_jmpbuf; -/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/ -#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) { -\tPyTupleObject *capi_arglist = #name#_args_capi; -\tPyObject *capi_return = NULL; -\tPyObject *capi_tmp = NULL; -\tint capi_j,capi_i = 0; -\tint capi_longjmp_ok = 1; -#decl# -#ifdef F2PY_REPORT_ATEXIT -f2py_cb_start_clock(); -#endif -\tCFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\"); -\tCFUNCSMESSPY(\"cb:#name#_capi=\",#name#_capi); -\tif (#name#_capi==NULL) { -\t\tcapi_longjmp_ok = 0; -\t\t#name#_capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\"); -\t} -\tif (#name#_capi==NULL) { -\t\tPyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\"); -\t\tgoto capi_fail; -\t} -\tif (PyCObject_Check(#name#_capi)) { -\t#name#_typedef #name#_cptr; -\t#name#_cptr = PyCObject_AsVoidPtr(#name#_capi); -\t#returncptr#(*#name#_cptr)(#optargs_nm##args_nm#); -\t#return# -\t} -\tif (capi_arglist==NULL) { -\t\tcapi_longjmp_ok = 0; -\t\tcapi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\"); -\t\tif (capi_tmp) { -\t\t\tcapi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp); -\t\t\tif (capi_arglist==NULL) { -\t\t\t\tPyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\"); -\t\t\t\tgoto capi_fail; -\t\t\t} -\t\t} else { -\t\t\tPyErr_Clear(); -\t\t\tcapi_arglist = (PyTupleObject *)Py_BuildValue(\"()\"); -\t\t} -\t} -\tif (capi_arglist == NULL) { -\t\tPyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\"); -\t\tgoto capi_fail; -\t} -#setdims# -#pyobjfrom# -\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist); -\tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\"); -#ifdef F2PY_REPORT_ATEXIT -f2py_cb_start_call_clock(); -#endif -\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist); -#ifdef F2PY_REPORT_ATEXIT -f2py_cb_stop_call_clock(); -#endif -\tCFUNCSMESSPY(\"cb:capi_return=\",capi_return); -\tif (capi_return == NULL) { -\t\tfprintf(stderr,\"capi_return is NULL\\n\"); -\t\tgoto capi_fail; -\t} -\tif (capi_return == Py_None) { -\t\tPy_DECREF(capi_return); -\t\tcapi_return = Py_BuildValue(\"()\"); -\t} -\telse if (!PyTuple_Check(capi_return)) { -\t\tcapi_return = Py_BuildValue(\"(N)\",capi_return); -\t} -\tcapi_j = PyTuple_Size(capi_return); -\tcapi_i = 0; -#frompyobj# -\tCFUNCSMESS(\"cb:#name#:successful\\n\"); -\tPy_DECREF(capi_return); -#ifdef F2PY_REPORT_ATEXIT -f2py_cb_stop_clock(); -#endif -\tgoto capi_return_pt; -capi_fail: -\tfprintf(stderr,\"Call-back #name# failed.\\n\"); -\tPy_XDECREF(capi_return); -\tif (capi_longjmp_ok) -\t\tlongjmp(#name#_jmpbuf,-1); -capi_return_pt: -\t; -#return# -} -#endtitle# -""", - 'need':['setjmp.h','CFUNCSMESS'], - 'maxnofargs':'#maxnofargs#', - 'nofoptargs':'#nofoptargs#', - 'docstr':"""\ -\tdef #argname#(#docsignature#): return #docreturn#\\n\\ -#docstrsigns#""", - 'latexdocstr':""" -{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}} -#routnote# - -#latexdocstrsigns#""", - 'docstrshort':'def #argname#(#docsignature#): return #docreturn#' - } -cb_rout_rules=[ - {# Init - 'separatorsfor':{'decl':'\n', - 'args':',','optargs':'','pyobjfrom':'\n','freemem':'\n', - 'args_td':',','optargs_td':'', - 'args_nm':',','optargs_nm':'', - 'frompyobj':'\n','setdims':'\n', - 'docstrsigns':'\\n"\n"', - 'latexdocstrsigns':'\n', - 'latexdocstrreq':'\n','latexdocstropt':'\n', - 'latexdocstrout':'\n','latexdocstrcbs':'\n', - }, - 'decl':'/*decl*/','pyobjfrom':'/*pyobjfrom*/','frompyobj':'/*frompyobj*/', - 'args':[],'optargs':'','return':'','strarglens':'','freemem':'/*freemem*/', - 'args_td':[],'optargs_td':'','strarglens_td':'', - 'args_nm':[],'optargs_nm':'','strarglens_nm':'', - 'noargs':'', - 'setdims':'/*setdims*/', - 'docstrsigns':'','latexdocstrsigns':'', - 'docstrreq':'\tRequired arguments:', - 'docstropt':'\tOptional arguments:', - 'docstrout':'\tReturn objects:', - 'docstrcbs':'\tCall-back functions:', - 'docreturn':'','docsign':'','docsignopt':'', - 'latexdocstrreq':'\\noindent Required arguments:', - 'latexdocstropt':'\\noindent Optional arguments:', - 'latexdocstrout':'\\noindent Return objects:', - 'latexdocstrcbs':'\\noindent Call-back functions:', - 'routnote':{hasnote:'--- #note#',l_not(hasnote):''}, - },{ # Function - 'decl':'\t#ctype# return_value;', - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->");'}, - '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");', - {debugcapi:'\tfprintf(stderr,"#showvalueformat#.\\n",return_value);'} - ], - 'need':['#ctype#_from_pyobj',{debugcapi:'CFUNCSMESS'},'GETSCALARFROMPYTUPLE'], - 'return':'\treturn return_value;', - '_check':l_and(isfunction,l_not(isstringfunction),l_not(iscomplexfunction)) - }, - {# String function - 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'}, - 'args':'#ctype# return_value,int return_value_len', - 'args_nm':'return_value,&return_value_len', - 'args_td':'#ctype# ,int', - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->\\"");'}, - """\tif (capi_j>capi_i) -\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""", - {debugcapi:'\tfprintf(stderr,"#showvalueformat#\\".\\n",return_value);'} - ], - 'need':['#ctype#_from_pyobj',{debugcapi:'CFUNCSMESS'}, - 'string.h','GETSTRFROMPYTUPLE'], - 'return':'return;', - '_check':isstringfunction - }, - {# Complex function - 'optargs':""" -#ifndef F2PY_CB_RETURNCOMPLEX -#ctype# *return_value -#endif -""", - 'optargs_nm':""" -#ifndef F2PY_CB_RETURNCOMPLEX -return_value -#endif -""", - 'optargs_td':""" -#ifndef F2PY_CB_RETURNCOMPLEX -#ctype# * -#endif -""", - 'decl':""" -#ifdef F2PY_CB_RETURNCOMPLEX -\t#ctype# return_value; -#endif -""", - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->");'}, - """\ -\tif (capi_j>capi_i) -#ifdef F2PY_CB_RETURNCOMPLEX -\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); -#else -\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); -#endif -""", - {debugcapi:""" -#ifdef F2PY_CB_RETURNCOMPLEX -\tfprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i); -#else -\tfprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i); -#endif - -"""} - ], - 'return':""" -#ifdef F2PY_CB_RETURNCOMPLEX -\treturn return_value; -#else -\treturn; -#endif -""", - 'need':['#ctype#_from_pyobj',{debugcapi:'CFUNCSMESS'}, - 'string.h','GETSCALARFROMPYTUPLE','#ctype#'], - '_check':iscomplexfunction - }, - {'docstrout':'\t\t#pydocsignout#', - 'latexdocstrout':['\\item[]{{}\\verb@#pydocsignout#@{}}', - {hasnote:'--- #note#'}], - 'docreturn':'#rname#,', - '_check':isfunction}, - {'_check':issubroutine,'return':'return;'} - ] - -cb_arg_rules=[ - { # Doc - 'docstropt':{l_and(isoptional,isintent_nothide):'\t\t#pydocsign#'}, - 'docstrreq':{l_and(isrequired,isintent_nothide):'\t\t#pydocsign#'}, - 'docstrout':{isintent_out:'\t\t#pydocsignout#'}, - 'latexdocstropt':{l_and(isoptional,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}', - {hasnote:'--- #note#'}]}, - 'latexdocstrreq':{l_and(isrequired,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}', - {hasnote:'--- #note#'}]}, - 'latexdocstrout':{isintent_out:['\\item[]{{}\\verb@#pydocsignout#@{}}', - {l_and(hasnote,isintent_hide):'--- #note#', - l_and(hasnote,isintent_nothide):'--- See above.'}]}, - 'docsign':{l_and(isrequired,isintent_nothide):'#varname#,'}, - 'docsignopt':{l_and(isoptional,isintent_nothide):'#varname#,'}, - 'depend':'' - }, - { - 'args':{ - l_and (isscalar,isintent_c):'#ctype# #varname#', - l_and (isscalar,l_not(isintent_c)):'#ctype# *#varname#_cb_capi', - isarray:'#ctype# *#varname#', - isstring:'#ctype# #varname#' - }, - 'args_nm':{ - l_and (isscalar,isintent_c):'#varname#', - l_and (isscalar,l_not(isintent_c)):'#varname#_cb_capi', - isarray:'#varname#', - isstring:'#varname#' - }, - 'args_td':{ - l_and (isscalar,isintent_c):'#ctype#', - l_and (isscalar,l_not(isintent_c)):'#ctype# *', - isarray:'#ctype# *', - isstring:'#ctype#' - }, - 'strarglens':{isstring:',int #varname#_cb_len'}, # untested with multiple args - 'strarglens_td':{isstring:',int'}, # untested with multiple args - - }, - { # Scalars - 'decl':{l_not(isintent_c):'\t#ctype# #varname#=(*#varname#_cb_capi);'}, - 'error': {l_and(isintent_c,isintent_out, - throw_error('intent(c,out) is forbidden for callback scalar arguments')):\ - ''}, - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->");'}, - {isintent_out:'\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'}, - {l_and(debugcapi,l_and(l_not(iscomplex),isintent_c)):'\tfprintf(stderr,"#showvalueformat#.\\n",#varname#);'}, - {l_and(debugcapi,l_and(l_not(iscomplex),l_not(isintent_c))):'\tfprintf(stderr,"#showvalueformat#.\\n",*#varname#_cb_capi);'}, - {l_and(debugcapi,l_and(iscomplex,isintent_c)):'\tfprintf(stderr,"#showvalueformat#.\\n",(#varname#).r,(#varname#).i);'}, - {l_and(debugcapi,l_and(iscomplex,l_not(isintent_c))):'\tfprintf(stderr,"#showvalueformat#.\\n",(*#varname#_cb_capi).r,(*#varname#_cb_capi).i);'}, - ], - 'need':[{isintent_out:['#ctype#_from_pyobj','GETSCALARFROMPYTUPLE']}, - {debugcapi:'CFUNCSMESS'}], - '_check':isscalar - },{ - 'pyobjfrom':[{isintent_in:"""\ -\tif (#name#_nofargs>capi_i) -\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname#))) -\t\t\tgoto capi_fail;"""}, - {isintent_inout:"""\ -\tif (#name#_nofargs>capi_i) -\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname#_cb_capi))) -\t\t\tgoto capi_fail;"""}], - 'need':[{isintent_in:'pyobj_from_#ctype#1'}, - {isintent_inout:'pyarr_from_p_#ctype#1'}, - {iscomplex:'#ctype#'}], - '_check':l_and(isscalar,isintent_nothide), - '_optional':'' - },{# String - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->\\"");'}, - """\tif (capi_j>capi_i) -\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,#varname#,#varname#_cb_len);""", - {debugcapi:'\tfprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname#,#varname#_cb_len);'}, - ], - 'need':['#ctype#','GETSTRFROMPYTUPLE', - {debugcapi:'CFUNCSMESS'},'string.h'], - '_check':l_and(isstring,isintent_out) - },{ - 'pyobjfrom':[{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname#,#varname#_cb_len);'}, - {isintent_in:"""\ -\tif (#name#_nofargs>capi_i) -\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname#))) -\t\t\tgoto capi_fail;"""}, - {isintent_inout:"""\ -\tif (#name#_nofargs>capi_i) { -\t\tint #varname#_cb_dims[] = {#varname#_cb_len}; -\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname#,#varname#_cb_dims))) -\t\t\tgoto capi_fail; -\t}"""}], - 'need':[{isintent_in:'pyobj_from_#ctype#1'}, - {isintent_inout:'pyarr_from_p_#ctype#1'}], - '_check':l_and(isstring,isintent_nothide), - '_optional':'' - }, -# Array ... - { - 'decl':'\tintp #varname#_Dims[#rank#] = {#rank*[-1]#};', - 'setdims':'\t#cbsetdims#;', - '_check':isarray, - '_depend':'' - }, - { - 'pyobjfrom':[{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'}, - {isintent_c:"""\ -\tif (#name#_nofargs>capi_i) { -\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname#_Dims,#atype#,NULL,(char*)#varname#,0,CARRAY_FLAGS,NULL); /*XXX: Hmm, what will destroy this array??? */ -""", - l_not(isintent_c):"""\ -\tif (#name#_nofargs>capi_i) { -\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname#_Dims,#atype#,NULL,(char*)#varname#,0,FARRAY_FLAGS,NULL); /*XXX: Hmm, what will destroy this array??? */ -""", - }, - """ -\t\tif (tmp_arr==NULL) -\t\t\tgoto capi_fail; -\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,(PyObject *)tmp_arr)) -\t\t\tgoto capi_fail; -}"""], - '_check':l_and(isarray,isintent_nothide,l_or(isintent_in,isintent_inout)), - '_optional':'', - },{ - 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->");'}, - """\tif (capi_j>capi_i) { -\t\tPyArrayObject *rv_cb_arr = NULL; -\t\tif ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail; -\t\trv_cb_arr = array_from_pyobj(#atype#,#varname#_Dims,#rank#,F2PY_INTENT_IN""", - {isintent_c:'|F2PY_INTENT_C'}, - """,capi_tmp); -\t\tif (rv_cb_arr == NULL) { -\t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\"); -\t\t\tgoto capi_fail; -\t\t} -\t\tMEMCOPY(#varname#,rv_cb_arr->data,PyArray_NBYTES(rv_cb_arr)); -\t\tif (capi_tmp != (PyObject *)rv_cb_arr) { -\t\t\tPy_DECREF(rv_cb_arr); -\t\t} -\t}""", - {debugcapi:'\tfprintf(stderr,"<-.\\n");'}, - ], - 'need':['MEMCOPY',{iscomplexarray:'#ctype#'}], - '_check':l_and(isarray,isintent_out) - },{ - 'docreturn':'#varname#,', - '_check':isintent_out - } - ] - -################## Build call-back module ############# -cb_map={} -def buildcallbacks(m): - global cb_map - cb_map[m['name']]=[] - for bi in m['body']: - if bi['block']=='interface': - for b in bi['body']: - if b: - buildcallback(b,m['name']) - else: - errmess('warning: empty body for %s\n' % (m['name'])) - -def buildcallback(rout,um): - global cb_map - outmess('\tConstructing call-back function "cb_%s_in_%s"\n'%(rout['name'],um)) - args,depargs=getargs(rout) - capi_maps.depargs=depargs - var=rout['vars'] - vrd=capi_maps.cb_routsign2map(rout,um) - rd=dictappend({},vrd) - cb_map[um].append([rout['name'],rd['name']]) - for r in cb_rout_rules: - if (r.has_key('_check') and r['_check'](rout)) or (not r.has_key('_check')): - ar=applyrules(r,vrd,rout) - rd=dictappend(rd,ar) - savevrd={} - for a in args: - vrd=capi_maps.cb_sign2map(a,var[a]) - savevrd[a]=vrd - for r in cb_arg_rules: - if r.has_key('_depend'): continue - if r.has_key('_optional') and isoptional(var[a]): continue - if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): - ar=applyrules(r,vrd,var[a]) - rd=dictappend(rd,ar) - if r.has_key('_break'): break - for a in args: - vrd=savevrd[a] - for r in cb_arg_rules: - if r.has_key('_depend'): continue - if (not r.has_key('_optional')) or (r.has_key('_optional') and isrequired(var[a])): continue - if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): - ar=applyrules(r,vrd,var[a]) - rd=dictappend(rd,ar) - if r.has_key('_break'): break - for a in depargs: - vrd=savevrd[a] - for r in cb_arg_rules: - if not r.has_key('_depend'): continue - if r.has_key('_optional'): continue - if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): - ar=applyrules(r,vrd,var[a]) - rd=dictappend(rd,ar) - if r.has_key('_break'): break - if rd.has_key('args') and rd.has_key('optargs'): - if type(rd['optargs'])==type([]): - rd['optargs']=rd['optargs']+[""" -#ifndef F2PY_CB_RETURNCOMPLEX -, -#endif -"""] - rd['optargs_nm']=rd['optargs_nm']+[""" -#ifndef F2PY_CB_RETURNCOMPLEX -, -#endif -"""] - rd['optargs_td']=rd['optargs_td']+[""" -#ifndef F2PY_CB_RETURNCOMPLEX -, -#endif -"""] - if type(rd['docreturn'])==types.ListType: - rd['docreturn']=stripcomma(replace('#docreturn#',{'docreturn':rd['docreturn']})) - optargs=stripcomma(replace('#docsignopt#', - {'docsignopt':rd['docsignopt']} - )) - if optargs=='': - rd['docsignature']=stripcomma(replace('#docsign#',{'docsign':rd['docsign']})) - else: - rd['docsignature']=replace('#docsign#[#docsignopt#]', - {'docsign':rd['docsign'], - 'docsignopt':optargs, - }) - rd['latexdocsignature']=string.replace(rd['docsignature'],'_','\\_') - rd['latexdocsignature']=string.replace(rd['latexdocsignature'],',',', ') - rd['docstrsigns']=[] - rd['latexdocstrsigns']=[] - for k in ['docstrreq','docstropt','docstrout','docstrcbs']: - if rd.has_key(k) and type(rd[k])==types.ListType: - rd['docstrsigns']=rd['docstrsigns']+rd[k] - k='latex'+k - if rd.has_key(k) and type(rd[k])==types.ListType: - rd['latexdocstrsigns']=rd['latexdocstrsigns']+rd[k][0:1]+\ - ['\\begin{description}']+rd[k][1:]+\ - ['\\end{description}'] - if not rd.has_key('args'): - rd['args']='' - rd['args_td']='' - rd['args_nm']='' - if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')): - rd['noargs'] = 'void' - - ar=applyrules(cb_routine_rules,rd) - cfuncs.callbacks[rd['name']]=ar['body'] - if type(ar['need'])==types.StringType: - ar['need']=[ar['need']] - - if rd.has_key('need'): - for t in cfuncs.typedefs.keys(): - if t in rd['need']: - ar['need'].append(t) - - cfuncs.typedefs_generated[rd['name']+'_typedef'] = ar['cbtypedefs'] - ar['need'].append(rd['name']+'_typedef') - cfuncs.needs[rd['name']]=ar['need'] - - capi_maps.lcb2_map[rd['name']]={'maxnofargs':ar['maxnofargs'], - 'nofoptargs':ar['nofoptargs'], - 'docstr':ar['docstr'], - 'latexdocstr':ar['latexdocstr'], - 'argname':rd['argname'] - } - outmess('\t %s\n'%(ar['docstrshort'])) - #print ar['body'] - return -################## Build call-back function ############# diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py deleted file mode 100644 index 81829f02c..000000000 --- a/numpy/f2py/cfuncs.py +++ /dev/null @@ -1,1141 +0,0 @@ -#!/usr/bin/env python -""" - -C declarations, CPP macros, and C functions for f2py2e. -Only required declarations/macros/functions will be used. - -Copyright 1999,2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/05/06 11:42:34 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.75 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import types,sys,copy,os -errmess=sys.stderr.write - -##################### Definitions ################## - -outneeds={'includes0':[],'includes':[],'typedefs':[],'typedefs_generated':[], - 'userincludes':[], - 'cppmacros':[],'cfuncs':[],'callbacks':[],'f90modhooks':[], - 'commonhooks':[]} -needs={} -includes0={'includes0':'/*need_includes0*/'} -includes={'includes':'/*need_includes*/'} -userincludes={'userincludes':'/*need_userincludes*/'} -typedefs={'typedefs':'/*need_typedefs*/'} -typedefs_generated={'typedefs_generated':'/*need_typedefs_generated*/'} -cppmacros={'cppmacros':'/*need_cppmacros*/'} -cfuncs={'cfuncs':'/*need_cfuncs*/'} -callbacks={'callbacks':'/*need_callbacks*/'} -f90modhooks={'f90modhooks':'/*need_f90modhooks*/', - 'initf90modhooksstatic':'/*initf90modhooksstatic*/', - 'initf90modhooksdynamic':'/*initf90modhooksdynamic*/', - } -commonhooks={'commonhooks':'/*need_commonhooks*/', - 'initcommonhooks':'/*need_initcommonhooks*/', - } - -############ Includes ################### - -includes0['math.h']='#include <math.h>' -includes0['string.h']='#include <string.h>' -includes0['setjmp.h']='#include <setjmp.h>' - -includes['Python.h']='#include "Python.h"' -needs['arrayobject.h']=['Python.h'] -includes['arrayobject.h']='''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API -#include "arrayobject.h"''' - -includes['arrayobject.h']='#include "fortranobject.h"' - -############# Type definitions ############### - -typedefs['unsigned_char']='typedef unsigned char unsigned_char;' -typedefs['unsigned_short']='typedef unsigned short unsigned_short;' -typedefs['unsigned_long']='typedef unsigned long unsigned_long;' -typedefs['signed_char']='typedef signed char signed_char;' -typedefs['long_long']="""\ -#ifdef _WIN32 -typedef __int64 long_long; -#else -typedef long long long_long; -typedef unsigned long long unsigned_long_long; -#endif -""" -typedefs['insinged_long_long']="""\ -#ifdef _WIN32 -typedef __uint64 long_long; -#else -typedef unsigned long long unsigned_long_long; -#endif -""" -typedefs['long_double']="""\ -#ifndef _LONG_DOUBLE -typedef long double long_double; -#endif -""" -typedefs['complex_long_double']='typedef struct {long double r,i;} complex_long_double;' -typedefs['complex_float']='typedef struct {float r,i;} complex_float;' -typedefs['complex_double']='typedef struct {double r,i;} complex_double;' -typedefs['string']="""typedef char * string;""" - - -############### CPP macros #################### -cppmacros['CFUNCSMESS']="""\ -#ifdef DEBUGCFUNCS -#define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess); -#define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\ -\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ -\tfprintf(stderr,\"\\n\"); -#else -#define CFUNCSMESS(mess) -#define CFUNCSMESSPY(mess,obj) -#endif -""" -cppmacros['F_FUNC']="""\ -#if defined(PREPEND_FORTRAN) -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) _##F -#else -#define F_FUNC(f,F) _##f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) _##F##_ -#else -#define F_FUNC(f,F) _##f##_ -#endif -#endif -#else -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F -#else -#define F_FUNC(f,F) f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F##_ -#else -#define F_FUNC(f,F) f##_ -#endif -#endif -#endif -#if defined(UNDERSCORE_G77) -#define F_FUNC_US(f,F) F_FUNC(f##_,F##_) -#else -#define F_FUNC_US(f,F) F_FUNC(f,F) -#endif -""" -cppmacros['F_WRAPPEDFUNC']="""\ -#if defined(PREPEND_FORTRAN) -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F -#else -#define F_WRAPPEDFUNC(f,F) _f2pywrap##f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_ -#else -#define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_ -#endif -#endif -#else -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F -#else -#define F_WRAPPEDFUNC(f,F) f2pywrap##f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_ -#else -#define F_WRAPPEDFUNC(f,F) f2pywrap##f##_ -#endif -#endif -#endif -#if defined(UNDERSCORE_G77) -#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_) -#else -#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F) -#endif -""" -cppmacros['F_MODFUNC']="""\ -#if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */ -#if defined(NO_APPEND_FORTRAN) -#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f -#else -#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _ -#endif -#endif - -#if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */ -#if defined(NO_APPEND_FORTRAN) -#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f -#else -#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f ## _ -#endif -#endif - -#if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */ -#if defined(NO_APPEND_FORTRAN) -#define F_MODFUNCNAME(m,f) f ## .in. ## m -#else -#define F_MODFUNCNAME(m,f) f ## .in. ## m ## _ -#endif -#endif -/* -#if defined(UPPERCASE_FORTRAN) -#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F) -#else -#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f) -#endif -*/ - -#define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f)) -""" -cppmacros['SWAPUNSAFE']="""\ -#define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\ - (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\ - (size_t)(a) = ((size_t)(a) ^ (size_t)(b)) -""" -cppmacros['SWAP']="""\ -#define SWAP(a,b,t) {\\ -\tt *c;\\ -\tc = a;\\ -\ta = b;\\ -\tb = c;} -""" -#cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) ((m)->flags & CONTIGUOUS)' -cppmacros['PRINTPYOBJERR']="""\ -#define PRINTPYOBJERR(obj)\\ -\tfprintf(stderr,\"#modulename#.error is related to \");\\ -\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ -\tfprintf(stderr,\"\\n\"); -""" -cppmacros['MINMAX']="""\ -#ifndef MAX -#define MAX(a,b) ((a > b) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) ((a < b) ? (a) : (b)) -#endif -""" -cppmacros['len..']="""\ -#define rank(var) var ## _Rank -#define shape(var,dim) var ## _Dims[dim] -#define old_rank(var) (((PyArrayObject *)(capi_ ## var ## _tmp))->nd) -#define old_shape(var,dim) (((PyArrayObject *)(capi_ ## var ## _tmp))->dimensions[dim]) -#define fshape(var,dim) shape(var,rank(var)-dim-1) -#define len(var) shape(var,0) -#define flen(var) fshape(var,0) -#define size(var) PyArray_SIZE((PyArrayObject *)(capi_ ## var ## _tmp)) -/* #define index(i) capi_i ## i */ -#define slen(var) capi_ ## var ## _len -""" - -cppmacros['pyobj_from_char1']='#define pyobj_from_char1(v) (PyInt_FromLong(v))' -cppmacros['pyobj_from_short1']='#define pyobj_from_short1(v) (PyInt_FromLong(v))' -needs['pyobj_from_int1']=['signed_char'] -cppmacros['pyobj_from_int1']='#define pyobj_from_int1(v) (PyInt_FromLong(v))' -cppmacros['pyobj_from_long1']='#define pyobj_from_long1(v) (PyLong_FromLong(v))' -needs['pyobj_from_long_long1']=['long_long'] -cppmacros['pyobj_from_long_long1']="""\ -#ifdef HAVE_LONG_LONG -#define pyobj_from_long_long1(v) (PyLong_FromLongLong(v)) -#else -#warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long. -#define pyobj_from_long_long1(v) (PyLong_FromLong(v)) -#endif -""" -needs['pyobj_from_long_double1']=['long_double'] -cppmacros['pyobj_from_long_double1']='#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))' -cppmacros['pyobj_from_double1']='#define pyobj_from_double1(v) (PyFloat_FromDouble(v))' -cppmacros['pyobj_from_float1']='#define pyobj_from_float1(v) (PyFloat_FromDouble(v))' -needs['pyobj_from_complex_long_double1']=['complex_long_double'] -cppmacros['pyobj_from_complex_long_double1']='#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))' -needs['pyobj_from_complex_double1']=['complex_double'] -cppmacros['pyobj_from_complex_double1']='#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))' -needs['pyobj_from_complex_float1']=['complex_float'] -cppmacros['pyobj_from_complex_float1']='#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))' -needs['pyobj_from_string1']=['string'] -cppmacros['pyobj_from_string1']='#define pyobj_from_string1(v) (PyString_FromString((char *)v))' -needs['TRYPYARRAYTEMPLATE']=['PRINTPYOBJERR'] -cppmacros['TRYPYARRAYTEMPLATE']="""\ -/* New SciPy */ -#define TRYPYARRAYTEMPLATECHAR case PyArray_STRING: *(char *)(arr->data)=*v; break; -#define TRYPYARRAYTEMPLATELONG case PyArray_LONG: *(long *)(arr->data)=*v; break; -#define TRYPYARRAYTEMPLATEOBJECT case PyArray_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data); break; - -#define TRYPYARRAYTEMPLATE(ctype,typecode) \\ - PyArrayObject *arr = NULL;\\ - if (!obj) return -2;\\ - if (!PyArray_Check(obj)) return -1;\\ - if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ - if (arr->descr->type==typecode) {*(ctype *)(arr->data)=*v; return 1;}\\ - switch (arr->descr->type_num) {\\ - case PyArray_DOUBLE: *(double *)(arr->data)=*v; break;\\ - case PyArray_INT: *(int *)(arr->data)=*v; break;\\ - case PyArray_LONG: *(long *)(arr->data)=*v; break;\\ - case PyArray_FLOAT: *(float *)(arr->data)=*v; break;\\ - case PyArray_CDOUBLE: *(double *)(arr->data)=*v; break;\\ - case PyArray_CFLOAT: *(float *)(arr->data)=*v; break;\\ - case PyArray_BOOL: *(Bool *)(arr->data)=(*v!=0); break;\\ - case PyArray_UBYTE: *(unsigned char *)(arr->data)=*v; break;\\ - case PyArray_BYTE: *(signed char *)(arr->data)=*v; break;\\ - case PyArray_SHORT: *(short *)(arr->data)=*v; break;\\ - case PyArray_USHORT: *(ushort *)(arr->data)=*v; break;\\ - case PyArray_UINT: *(uint *)(arr->data)=*v; break;\\ - case PyArray_ULONG: *(ulong *)(arr->data)=*v; break;\\ - case PyArray_LONGLONG: *(longlong *)(arr->data)=*v; break;\\ - case PyArray_ULONGLONG: *(ulonglong *)(arr->data)=*v; break;\\ - case PyArray_LONGDOUBLE: *(longdouble *)(arr->data)=*v; break;\\ - case PyArray_CLONGDOUBLE: *(longdouble *)(arr->data)=*v; break;\\ - case PyArray_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data, arr); break;\\ - default: return -2;\\ - };\\ - return 1 -""" - -needs['TRYCOMPLEXPYARRAYTEMPLATE']=['PRINTPYOBJERR'] -cppmacros['TRYCOMPLEXPYARRAYTEMPLATE']="""\ -#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case PyArray_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break; -#define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\ - PyArrayObject *arr = NULL;\\ - if (!obj) return -2;\\ - if (!PyArray_Check(obj)) return -1;\\ - if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ - if (arr->descr->type==typecode) {\\ - *(ctype *)(arr->data)=(*v).r;\\ - *(ctype *)(arr->data+sizeof(ctype))=(*v).i;\\ - return 1;\\ - }\\ - switch (arr->descr->type_num) {\\ - case PyArray_CDOUBLE: *(double *)(arr->data)=(*v).r;*(double *)(arr->data+sizeof(double))=(*v).i;break;\\ - case PyArray_CFLOAT: *(float *)(arr->data)=(*v).r;*(float *)(arr->data+sizeof(float))=(*v).i;break;\\ - case PyArray_DOUBLE: *(double *)(arr->data)=(*v).r; break;\\ - case PyArray_LONG: *(long *)(arr->data)=(*v).r; break;\\ - case PyArray_FLOAT: *(float *)(arr->data)=(*v).r; break;\\ - case PyArray_INT: *(int *)(arr->data)=(*v).r; break;\\ - case PyArray_SHORT: *(short *)(arr->data)=(*v).r; break;\\ - case PyArray_UBYTE: *(unsigned char *)(arr->data)=(*v).r; break;\\ - case PyArray_BYTE: *(signed char *)(arr->data)=(*v).r; break;\\ - case PyArray_BOOL: *(Bool *)(arr->data)=((*v).r!=0 && (*v).i!=0)); break;\\ - case PyArray_UBYTE: *(unsigned char *)(arr->data)=(*v).r; break;\\ - case PyArray_BYTE: *(signed char *)(arr->data)=(*v).r; break;\\ - case PyArray_SHORT: *(short *)(arr->data)=(*v).r; break;\\ - case PyArray_USHORT: *(ushort *)(arr->data)=(*v).r; break;\\ - case PyArray_UINT: *(uint *)(arr->data)=(*v).r; break;\\ - case PyArray_ULONG: *(ulong *)(arr->data)=(*v).r; break;\\ - case PyArray_LONGLONG: *(longlong *)(arr->data)=(*v).r; break;\\ - case PyArray_ULONGLONG: *(ulonglong *)(arr->data)=(*v).r; break;\\ - case PyArray_LONGDOUBLE: *(longdouble *)(arr->data)=(*v).r; break;\\ - case PyArray_CLONGDOUBLE: *(longdouble *)(arr->data)=(*v).r;*(longdouble *)(arr->data+sizeof(longdouble))=(*v).i;break;\\ - case PyArray_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break;\\ - default: return -2;\\ - };\\ - return -1; -""" -## cppmacros['NUMFROMARROBJ']="""\ -## #define NUMFROMARROBJ(typenum,ctype) \\ -## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ -## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ -## \tif (arr) {\\ -## \t\tif (arr->descr->type_num==PyArray_OBJECT) {\\ -## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ -## \t\t\tgoto capi_fail;\\ -## \t\t} else {\\ -## \t\t\t(arr->descr->cast[typenum])(arr->data,1,(char*)v,1,1);\\ -## \t\t}\\ -## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ -## \t\treturn 1;\\ -## \t} -## """ -## #XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ -## cppmacros['CNUMFROMARROBJ']="""\ -## #define CNUMFROMARROBJ(typenum,ctype) \\ -## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ -## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ -## \tif (arr) {\\ -## \t\tif (arr->descr->type_num==PyArray_OBJECT) {\\ -## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ -## \t\t\tgoto capi_fail;\\ -## \t\t} else {\\ -## \t\t\t(arr->descr->cast[typenum])((void *)(arr->data),1,(void *)(v),1,1);\\ -## \t\t}\\ -## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ -## \t\treturn 1;\\ -## \t} -## """ - - -needs['GETSTRFROMPYTUPLE']=['STRINGCOPYN','PRINTPYOBJERR'] -cppmacros['GETSTRFROMPYTUPLE']="""\ -#define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\ -\t\tPyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\ -\t\tif (rv_cb_str == NULL)\\ -\t\t\tgoto capi_fail;\\ -\t\tif (PyString_Check(rv_cb_str)) {\\ -\t\t\tstr[len-1]='\\0';\\ -\t\t\tSTRINGCOPYN((str),PyString_AS_STRING((PyStringObject*)rv_cb_str),(len));\\ -\t\t} else {\\ -\t\t\tPRINTPYOBJERR(rv_cb_str);\\ -\t\t\tPyErr_SetString(#modulename#_error,\"string object expected\");\\ -\t\t\tgoto capi_fail;\\ -\t\t}\\ -\t} -""" -cppmacros['GETSCALARFROMPYTUPLE']="""\ -#define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\ -\t\tif ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\ -\t\tif (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\ -\t\t\tgoto capi_fail;\\ -\t} -""" - -cppmacros['FAILNULL']="""\\ -#define FAILNULL(p) do { \\ - if ((p) == NULL) { \\ - PyErr_SetString(PyExc_MemoryError, "NULL pointer found"); \\ - goto capi_fail; \\ - } \\ -} while (0) -""" -needs['MEMCOPY']=['string.h', 'FAILNULL'] -cppmacros['MEMCOPY']="""\ -#define MEMCOPY(to,from,n)\\ - do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0) -""" -cppmacros['STRINGMALLOC']="""\ -#define STRINGMALLOC(str,len)\\ -\tif ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\ -\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");\\ -\t\tgoto capi_fail;\\ -\t} else {\\ -\t\t(str)[len] = '\\0';\\ -\t} -""" -cppmacros['STRINGFREE']="""\ -#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0) -""" -needs['STRINGCOPYN']=['string.h', 'FAILNULL'] -cppmacros['STRINGCOPYN']="""\ -#define STRINGCOPYN(to,from,buf_size) \\ - do { \\ - int _m = (buf_size); \\ - char *_to = (to); \\ - char *_from = (from); \\ - FAILNULL(_to); FAILNULL(_from); \\ - (void)strncpy(_to, _from, sizeof(char)*_m); \\ - _to[_m-1] = '\\0'; \\ - /* Padding with spaces instead of nulls */ \\ - for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) { \\ - _to[_m] = ' '; \\ - } \\ - } while (0) -""" -needs['STRINGCOPY']=['string.h', 'FAILNULL'] -cppmacros['STRINGCOPY']="""\ -#define STRINGCOPY(to,from)\\ - do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0) -""" -cppmacros['CHECKGENERIC']="""\ -#define CHECKGENERIC(check,tcheck,name) \\ -\tif (!(check)) {\\ -\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ -\t\t/*goto capi_fail;*/\\ -\t} else """ -cppmacros['CHECKARRAY']="""\ -#define CHECKARRAY(check,tcheck,name) \\ -\tif (!(check)) {\\ -\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ -\t\t/*goto capi_fail;*/\\ -\t} else """ -cppmacros['CHECKSTRING']="""\ -#define CHECKSTRING(check,tcheck,name,show,var)\\ -\tif (!(check)) {\\ -\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ -\t\tfprintf(stderr,show\"\\n\",slen(var),var);\\ -\t\t/*goto capi_fail;*/\\ -\t} else """ -cppmacros['CHECKSCALAR']="""\ -#define CHECKSCALAR(check,tcheck,name,show,var)\\ -\tif (!(check)) {\\ -\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ -\t\tfprintf(stderr,show\"\\n\",var);\\ -\t\t/*goto capi_fail;*/\\ -\t} else """ -## cppmacros['CHECKDIMS']="""\ -## #define CHECKDIMS(dims,rank) \\ -## \tfor (int i=0;i<(rank);i++)\\ -## \t\tif (dims[i]<0) {\\ -## \t\t\tfprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\ -## \t\t\tgoto capi_fail;\\ -## \t\t} -## """ -cppmacros['ARRSIZE']='#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))' -cppmacros['OLDPYNUM']="""\ -#ifdef OLDPYNUM -#error You need to intall Numeric Python version 13 or higher. Get it from http:/sourceforge.net/project/?group_id=1369 -#endif -""" -################# C functions ############### - -cfuncs['calcarrindex']="""\ -static int calcarrindex(int *i,PyArrayObject *arr) { -\tint k,ii = i[0]; -\tfor (k=1; k < arr->nd; k++) -\t\tii += (ii*(arr->dimensions[k] - 1)+i[k]); /* assuming contiguous arr */ -\treturn ii; -}""" -cfuncs['calcarrindextr']="""\ -static int calcarrindextr(int *i,PyArrayObject *arr) { -\tint k,ii = i[arr->nd-1]; -\tfor (k=1; k < arr->nd; k++) -\t\tii += (ii*(arr->dimensions[arr->nd-k-1] - 1)+i[arr->nd-k-1]); /* assuming contiguous arr */ -\treturn ii; -}""" -cfuncs['forcomb']="""\ -static struct { int nd;intp *d;int *i,*i_tr,tr; } forcombcache; -static int initforcomb(intp *dims,int nd,int tr) { - int k; - if (dims==NULL) return 0; - if (nd<0) return 0; - forcombcache.nd = nd; - forcombcache.d = dims; - forcombcache.tr = tr; - if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0; - if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0; - for (k=1;k<nd;k++) { - forcombcache.i[k] = forcombcache.i_tr[nd-k-1] = 0; - } - forcombcache.i[0] = forcombcache.i_tr[nd-1] = -1; - return 1; -} -static int *nextforcomb(void) { - int j,*i,*i_tr,k; - int nd=forcombcache.nd; - if ((i=forcombcache.i) == NULL) return NULL; - if ((i_tr=forcombcache.i_tr) == NULL) return NULL; - if (forcombcache.d == NULL) return NULL; - i[0]++; - if (i[0]==forcombcache.d[0]) { - j=1; - while ((j<nd) && (i[j]==forcombcache.d[j]-1)) j++; - if (j==nd) { - free(i); - free(i_tr); - return NULL; - } - for (k=0;k<j;k++) i[k] = i_tr[nd-k-1] = 0; - i[j]++; - i_tr[nd-j-1]++; - } else - i_tr[nd-1]++; - if (forcombcache.tr) return i_tr; - return i; -}""" -needs['try_pyarr_from_string']=['STRINGCOPYN','PRINTPYOBJERR','string'] -cfuncs['try_pyarr_from_string']="""\ -static int try_pyarr_from_string(PyObject *obj,const string str) { -\tPyArrayObject *arr = NULL; -\tif (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL))) -\t\t{ STRINGCOPYN(arr->data,str,PyArray_NBYTES(arr)); } -\treturn 1; -capi_fail: -\tPRINTPYOBJERR(obj); -\tPyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\"); -\treturn 0; -} -""" -needs['string_from_pyobj']=['string','STRINGMALLOC','STRINGCOPYN'] -cfuncs['string_from_pyobj']="""\ -static int string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess) { -\tPyArrayObject *arr = NULL; -\tPyObject *tmp = NULL; -#ifdef DEBUGCFUNCS -fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj); -#endif -\tif (obj == Py_None) { -\t\tif (*len == -1) -\t\t\t*len = strlen(inistr); /* Will this cause problems? */ -\t\tSTRINGMALLOC(*str,*len); -\t\tSTRINGCOPYN(*str,inistr,*len+1); -\t\treturn 1; -\t} -\tif (PyArray_Check(obj)) { -\t\tif ((arr = (PyArrayObject *)obj) == NULL) -\t\t\tgoto capi_fail; -\t\tif (!ISCONTIGUOUS(arr)) { -\t\t\tPyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\"); -\t\t\tgoto capi_fail; -\t\t} -\t\tif (*len == -1) -\t\t\t*len = (arr->descr->elsize)*PyArray_SIZE(arr); -\t\tSTRINGMALLOC(*str,*len); -\t\tSTRINGCOPYN(*str,arr->data,*len+1); -\t\treturn 1; -\t} -\tif (PyString_Check(obj)) { -\t\ttmp = obj; -\t\tPy_INCREF(tmp); -\t} -\telse -\t\ttmp = PyObject_Str(obj); -\tif (tmp == NULL) goto capi_fail; -\tif (*len == -1) -\t\t*len = PyString_GET_SIZE(tmp); -\tSTRINGMALLOC(*str,*len); -\tSTRINGCOPYN(*str,PyString_AS_STRING(tmp),*len+1); -\tPy_DECREF(tmp); -\treturn 1; -capi_fail: -\tPy_XDECREF(tmp); -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) err = #modulename#_error; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -needs['char_from_pyobj']=['int_from_pyobj'] -cfuncs['char_from_pyobj']="""\ -static int char_from_pyobj(char* v,PyObject *obj,const char *errmess) { -\tint i=0; -\tif (int_from_pyobj(&i,obj,errmess)) { -\t\t*v = (char)i; -\t\treturn 1; -\t} -\treturn 0; -} -""" -needs['signed_char_from_pyobj']=['int_from_pyobj','signed_char'] -cfuncs['signed_char_from_pyobj']="""\ -static int signed_char_from_pyobj(signed_char* v,PyObject *obj,const char *errmess) { -\tint i=0; -\tif (int_from_pyobj(&i,obj,errmess)) { -\t\t*v = (signed_char)i; -\t\treturn 1; -\t} -\treturn 0; -} -""" -needs['short_from_pyobj']=['int_from_pyobj'] -cfuncs['short_from_pyobj']="""\ -static int short_from_pyobj(short* v,PyObject *obj,const char *errmess) { -\tint i=0; -\tif (int_from_pyobj(&i,obj,errmess)) { -\t\t*v = (short)i; -\t\treturn 1; -\t} -\treturn 0; -} -""" -cfuncs['int_from_pyobj']="""\ -static int int_from_pyobj(int* v,PyObject *obj,const char *errmess) { -\tPyObject* tmp = NULL; -\tif (PyInt_Check(obj)) { -\t\t*v = (int)PyInt_AS_LONG(obj); -\t\treturn 1; -\t} -\ttmp = PyNumber_Int(obj); -\tif (tmp) { -\t\t*v = PyInt_AS_LONG(tmp); -\t\tPy_DECREF(tmp); -\t\treturn 1; -\t} -\tif (PyComplex_Check(obj)) -\t\ttmp = PyObject_GetAttrString(obj,\"real\"); -\telse if (PyString_Check(obj)) -\t\t/*pass*/; -\telse if (PySequence_Check(obj)) -\t\ttmp = PySequence_GetItem(obj,0); -\tif (tmp) { -\t\tPyErr_Clear(); -\t\tif (int_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} -\t\tPy_DECREF(tmp); -\t} -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) err = #modulename#_error; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -cfuncs['long_from_pyobj']="""\ -static int long_from_pyobj(long* v,PyObject *obj,const char *errmess) { -\tPyObject* tmp = NULL; -\tif (PyInt_Check(obj)) { -\t\t*v = PyInt_AS_LONG(obj); -\t\treturn 1; -\t} -\ttmp = PyNumber_Int(obj); -\tif (tmp) { -\t\t*v = PyInt_AS_LONG(tmp); -\t\tPy_DECREF(tmp); -\t\treturn 1; -\t} -\tif (PyComplex_Check(obj)) -\t\ttmp = PyObject_GetAttrString(obj,\"real\"); -\telse if (PyString_Check(obj)) -\t\t/*pass*/; -\telse if (PySequence_Check(obj)) -\t\ttmp = PySequence_GetItem(obj,0); -\tif (tmp) { -\t\tPyErr_Clear(); -\t\tif (long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} -\t\tPy_DECREF(tmp); -\t} -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) err = #modulename#_error; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -needs['long_long_from_pyobj']=['long_long'] -cfuncs['long_long_from_pyobj']="""\ -static int long_long_from_pyobj(long_long* v,PyObject *obj,const char *errmess) { -\tPyObject* tmp = NULL; -\tif (PyLong_Check(obj)) { -\t\t*v = PyLong_AsLongLong(obj); -\t\treturn (!PyErr_Occurred()); -\t} -\tif (PyInt_Check(obj)) { -\t\t*v = (long_long)PyInt_AS_LONG(obj); -\t\treturn 1; -\t} -\ttmp = PyNumber_Long(obj); -\tif (tmp) { -\t\t*v = PyLong_AsLongLong(tmp); -\t\tPy_DECREF(tmp); -\t\treturn (!PyErr_Occurred()); -\t} -\tif (PyComplex_Check(obj)) -\t\ttmp = PyObject_GetAttrString(obj,\"real\"); -\telse if (PyString_Check(obj)) -\t\t/*pass*/; -\telse if (PySequence_Check(obj)) -\t\ttmp = PySequence_GetItem(obj,0); -\tif (tmp) { -\t\tPyErr_Clear(); -\t\tif (long_long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} -\t\tPy_DECREF(tmp); -\t} -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) err = #modulename#_error; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -needs['long_double_from_pyobj']=['double_from_pyobj','long_double'] -cfuncs['long_double_from_pyobj']="""\ -static int long_double_from_pyobj(long_double* v,PyObject *obj,const char *errmess) { -\tdouble d=0; -\tif (PyArray_CheckScalar(obj)){ -\t\tif PyArray_IsScalar(obj, LongDouble) { -\t\t\tPyArray_ScalarAsCtype(obj, v); -\t\t\treturn 1; -\t\t} -\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==PyArray_LONGDOUBLE) { -\t\t\t(*v) = *((longdouble *)PyArray_DATA(obj)) -\t\t\treturn 1; -\t\t} -\t} -\tif (double_from_pyobj(&d,obj,errmess)) { -\t\t*v = (long_double)d; -\t\treturn 1; -\t} -\treturn 0; -} -""" -cfuncs['double_from_pyobj']="""\ -static int double_from_pyobj(double* v,PyObject *obj,const char *errmess) { -\tPyObject* tmp = NULL; -\tif (PyFloat_Check(obj)) { -#ifdef __sgi -\t\t*v = PyFloat_AsDouble(obj); -#else -\t\t*v = PyFloat_AS_DOUBLE(obj); -#endif -\t\treturn 1; -\t} -\ttmp = PyNumber_Float(obj); -\tif (tmp) { -#ifdef __sgi -\t\t*v = PyFloat_AsDouble(tmp); -#else -\t\t*v = PyFloat_AS_DOUBLE(tmp); -#endif -\t\tPy_DECREF(tmp); -\t\treturn 1; -\t} -\tif (PyComplex_Check(obj)) -\t\ttmp = PyObject_GetAttrString(obj,\"real\"); -\telse if (PyString_Check(obj)) -\t\t/*pass*/; -\telse if (PySequence_Check(obj)) -\t\ttmp = PySequence_GetItem(obj,0); -\tif (tmp) { -\t\tPyErr_Clear(); -\t\tif (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} -\t\tPy_DECREF(tmp); -\t} -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) err = #modulename#_error; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -needs['float_from_pyobj']=['double_from_pyobj'] -cfuncs['float_from_pyobj']="""\ -static int float_from_pyobj(float* v,PyObject *obj,const char *errmess) { -\tdouble d=0.0; -\tif (double_from_pyobj(&d,obj,errmess)) { -\t\t*v = (float)d; -\t\treturn 1; -\t} -\treturn 0; -} -""" -needs['complex_long_double_from_pyobj']=['complex_long_double','long_double', - 'complex_double_from_pyobj'] -cfuncs['complex_long_double_from_pyobj']="""\ -static int complex_long_double_from_pyobj(complex_long_double* v,PyObject *obj,const char *errmess) { -\tcomplex_double cd={0.0,0.0}; -\tif (PyArray_CheckScalar(obj)){ -\t\tif PyArray_IsScalar(obj, CLongDouble) { -\t\t\tPyArray_ScalarAsCtype(obj, v); -\t\t\treturn 1; -\t\t} -\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==PyArray_CLONGDOUBLE) { -\t\t\t(*v).r = ((clongdouble *)PyArray_DATA(obj))->real; -\t\t\t(*v).i = ((clongdouble *)PyArray_DATA(obj))->imag; -\t\t\treturn 1; -\t\t} -\t} -\tif (complex_double_from_pyobj(&cd,obj,errmess)) { -\t\t(*v).r = (long_double)cd.r; -\t\t(*v).i = (long_double)cd.i; -\t\treturn 1; -\t} -\treturn 0; -} -""" -needs['complex_double_from_pyobj']=['complex_double'] -cfuncs['complex_double_from_pyobj']="""\ -static int complex_double_from_pyobj(complex_double* v,PyObject *obj,const char *errmess) { -\tPy_complex c; -\tif (PyComplex_Check(obj)) { -\t\tc=PyComplex_AsCComplex(obj); -\t\t(*v).r=c.real, (*v).i=c.imag; -\t\treturn 1; -\t} -\tif (PyArray_IsScalar(obj, ComplexFloating)) { -\t\tif (PyArray_IsScalar(obj, CFloat)) { -\t\t\tcfloat new; -\t\t\tPyArray_ScalarAsCtype(obj, &new); -\t\t\t(*v).r = (double)new.real; -\t\t\t(*v).i = (double)new.imag; -\t\t} -\t\telse if (PyArray_IsScalar(obj, CLongDouble)) { -\t\t\tclongdouble new; -\t\t\tPyArray_ScalarAsCtype(obj, &new); -\t\t\t(*v).r = (double)new.real; -\t\t\t(*v).i = (double)new.imag; -\t\t} -\t\telse { /* if (PyArray_IsScalar(obj, CDouble)) */ -\t\t\tPyArray_ScalarAsCtype(obj, v); -\t\t} -\t\treturn 1; -\t} -\tif (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */ -\t\tPyObject *arr; -\t\tif (PyArray_Check(obj)) { -\t\t\tarr = PyArray_Cast((PyArrayObject *)obj, PyArray_CDOUBLE); -\t\t} -\t\telse { -\t\t\tarr = PyArray_FromScalar(obj, PyArray_DescrFromType(PyArray_CDOUBLE)); -\t\t} -\t\tif (arr==NULL) return 0; -\t\t(*v).r = ((cdouble *)PyArray_DATA(arr))->real; -\t\t(*v).i = ((cdouble *)PyArray_DATA(arr))->imag; -\t\treturn 1; -\t} -\t/* Python does not provide PyNumber_Complex function :-( */ -\t(*v).i=0.0; -\tif (PyFloat_Check(obj)) { -#ifdef __sgi -\t\t(*v).r = PyFloat_AsDouble(obj); -#else -\t\t(*v).r = PyFloat_AS_DOUBLE(obj); -#endif -\t\treturn 1; -\t} -\tif (PyInt_Check(obj)) { -\t\t(*v).r = (double)PyInt_AS_LONG(obj); -\t\treturn 1; -\t} -\tif (PyLong_Check(obj)) { -\t\t(*v).r = PyLong_AsDouble(obj); -\t\treturn (!PyErr_Occurred()); -\t} -\tif (PySequence_Check(obj) && (!PyString_Check(obj))) { -\t\tPyObject *tmp = PySequence_GetItem(obj,0); -\t\tif (tmp) { -\t\t\tif (complex_double_from_pyobj(v,tmp,errmess)) { -\t\t\t\tPy_DECREF(tmp); -\t\t\t\treturn 1; -\t\t\t} -\t\t\tPy_DECREF(tmp); -\t\t} -\t} -\t{ -\t\tPyObject* err = PyErr_Occurred(); -\t\tif (err==NULL) -\t\t\terr = PyExc_TypeError; -\t\tPyErr_SetString(err,errmess); -\t} -\treturn 0; -} -""" -needs['complex_float_from_pyobj']=['complex_float','complex_double_from_pyobj'] -cfuncs['complex_float_from_pyobj']="""\ -static int complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess) { -\tcomplex_double cd={0.0,0.0}; -\tif (complex_double_from_pyobj(&cd,obj,errmess)) { -\t\t(*v).r = (float)cd.r; -\t\t(*v).i = (float)cd.i; -\t\treturn 1; -\t} -\treturn 0; -} -""" -needs['try_pyarr_from_char']=['pyobj_from_char1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_char']='static int try_pyarr_from_char(PyObject* obj,char* v) {\n\tTRYPYARRAYTEMPLATE(char,\'c\');\n}\n' -needs['try_pyarr_from_signed_char']=['TRYPYARRAYTEMPLATE','unsigned_char'] -cfuncs['try_pyarr_from_unsigned_char']='static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n\tTRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n' -needs['try_pyarr_from_signed_char']=['TRYPYARRAYTEMPLATE','signed_char'] -cfuncs['try_pyarr_from_signed_char']='static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n\tTRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n' -needs['try_pyarr_from_short']=['pyobj_from_short1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_short']='static int try_pyarr_from_short(PyObject* obj,short* v) {\n\tTRYPYARRAYTEMPLATE(short,\'s\');\n}\n' -needs['try_pyarr_from_int']=['pyobj_from_int1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_int']='static int try_pyarr_from_int(PyObject* obj,int* v) {\n\tTRYPYARRAYTEMPLATE(int,\'i\');\n}\n' -needs['try_pyarr_from_long']=['pyobj_from_long1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_long']='static int try_pyarr_from_long(PyObject* obj,long* v) {\n\tTRYPYARRAYTEMPLATE(long,\'l\');\n}\n' -needs['try_pyarr_from_long_long']=['pyobj_from_long_long1','TRYPYARRAYTEMPLATE','long_long'] -cfuncs['try_pyarr_from_long_long']='static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n\tTRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n' -needs['try_pyarr_from_float']=['pyobj_from_float1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_float']='static int try_pyarr_from_float(PyObject* obj,float* v) {\n\tTRYPYARRAYTEMPLATE(float,\'f\');\n}\n' -needs['try_pyarr_from_double']=['pyobj_from_double1','TRYPYARRAYTEMPLATE'] -cfuncs['try_pyarr_from_double']='static int try_pyarr_from_double(PyObject* obj,double* v) {\n\tTRYPYARRAYTEMPLATE(double,\'d\');\n}\n' -needs['try_pyarr_from_complex_float']=['pyobj_from_complex_float1','TRYCOMPLEXPYARRAYTEMPLATE','complex_float'] -cfuncs['try_pyarr_from_complex_float']='static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n' -needs['try_pyarr_from_complex_double']=['pyobj_from_complex_double1','TRYCOMPLEXPYARRAYTEMPLATE','complex_double'] -cfuncs['try_pyarr_from_complex_double']='static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n' - -needs['create_cb_arglist']=['CFUNCSMESS','PRINTPYOBJERR','MINMAX'] -cfuncs['create_cb_arglist']="""\ -static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofargs,const int nofoptargs,int *nofargs,PyTupleObject **args,const char *errmess) { -\tPyObject *tmp = NULL; -\tPyObject *tmp_fun = NULL; -\tint tot,opt,ext,siz,i,di=0; -\tCFUNCSMESS(\"create_cb_arglist\\n\"); -\ttot=opt=ext=siz=0; -\t/* Get the total number of arguments */ -\tif (PyFunction_Check(fun)) -\t\ttmp_fun = fun; -\telse { -\t\tdi = 1; -\t\tif (PyObject_HasAttrString(fun,\"im_func\")) { -\t\t\ttmp_fun = PyObject_GetAttrString(fun,\"im_func\"); -\t\t} -\t\telse if (PyObject_HasAttrString(fun,\"__call__\")) { -\t\t\ttmp = PyObject_GetAttrString(fun,\"__call__\"); -\t\t\tif (PyObject_HasAttrString(tmp,\"im_func\")) -\t\t\t\ttmp_fun = PyObject_GetAttrString(tmp,\"im_func\"); -\t\t\telse { -\t\t\t\ttmp_fun = fun; /* built-in function */ -\t\t\t\ttot = maxnofargs; -\t\t\t\tif (xa != NULL) -\t\t\t\t\ttot += PyTuple_Size((PyObject *)xa); -\t\t\t} -\t\t\tPy_XDECREF(tmp); -\t\t} -\t\telse if (PyFortran_Check(fun) || PyFortran_Check1(fun)) { -\t\t\ttot = maxnofargs; -\t\t\tif (xa != NULL) -\t\t\t\ttot += PyTuple_Size((PyObject *)xa); -\t\t\ttmp_fun = fun; -\t\t} -\t\telse if (PyCObject_Check(fun)) { -\t\t\ttot = maxnofargs; -\t\t\tif (xa != NULL) -\t\t\t\text = PyTuple_Size((PyObject *)xa); -\t\t\tif(ext>0) { -\t\t\t\tfprintf(stderr,\"extra arguments tuple cannot be used with CObject call-back\\n\"); -\t\t\t\tgoto capi_fail; -\t\t\t} -\t\t\ttmp_fun = fun; -\t\t} -\t} -if (tmp_fun==NULL) { -fprintf(stderr,\"Call-back argument must be function|instance|instance.__call__|f2py-function but got %s.\\n\",(fun==NULL?\"NULL\":fun->ob_type->tp_name)); -goto capi_fail; -} -\tif (PyObject_HasAttrString(tmp_fun,\"func_code\")) { -\t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\")) -\t\t\ttot = PyInt_AsLong(PyObject_GetAttrString(tmp,\"co_argcount\")) - di; -\t\tPy_XDECREF(tmp); -\t} -\t/* Get the number of optional arguments */ -\tif (PyObject_HasAttrString(tmp_fun,\"func_defaults\")) -\t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"func_defaults\"))) -\t\t\topt = PyTuple_Size(tmp); -\t\tPy_XDECREF(tmp); -\t/* Get the number of extra arguments */ -\tif (xa != NULL) -\t\text = PyTuple_Size((PyObject *)xa); -\t/* Calculate the size of call-backs argument list */ -\tsiz = MIN(maxnofargs+ext,tot); -\t*nofargs = MAX(0,siz-ext); -#ifdef DEBUGCFUNCS -\tfprintf(stderr,\"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),tot,opt,ext,siz,nofargs=%d(-%d),%d,%d,%d,%d,%d\\n\",maxnofargs,nofoptargs,tot,opt,ext,siz,*nofargs); -#endif -\tif (siz<tot-opt) { -\t\tfprintf(stderr,\"create_cb_arglist: Failed to build argument list (siz) with enough arguments (tot-opt) required by user-supplied function (siz,tot,opt=%d,%d,%d).\\n\",siz,tot,opt); -\t\tgoto capi_fail; -\t} -\t/* Initialize argument list */ -\t*args = (PyTupleObject *)PyTuple_New(siz); -\tfor (i=0;i<*nofargs;i++) { -\t\tPy_INCREF(Py_None); -\t\tPyTuple_SET_ITEM((PyObject *)(*args),i,Py_None); -\t} -\tif (xa != NULL) -\t\tfor (i=(*nofargs);i<siz;i++) { -\t\t\ttmp = PyTuple_GetItem((PyObject *)xa,i-(*nofargs)); -\t\t\tPy_INCREF(tmp); -\t\t\tPyTuple_SET_ITEM(*args,i,tmp); -\t\t} -\tCFUNCSMESS(\"create_cb_arglist-end\\n\"); -\treturn 1; -capi_fail: -\tif ((PyErr_Occurred())==NULL) -\t\tPyErr_SetString(#modulename#_error,errmess); -\treturn 0; -} -""" - -def buildcfuncs(): - from capi_maps import c2capi_map - for k in c2capi_map.keys(): - m='pyarr_from_p_%s1'%k - cppmacros[m]='#define %s(v) (PyArray_SimpleNewFromData(0,NULL,%s,(char *)v))'%(m,c2capi_map[k]) - k='string' - m='pyarr_from_p_%s1'%k - cppmacros[m]='#define %s(v,dims) (PyArray_SimpleNewFromData(1,dims,PyArray_CHAR,(char *)v))'%(m) - - -############ Auxiliary functions for sorting needs ################### - -def append_needs(need,flag=1): - global outneeds,needs - if type(need)==types.ListType: - for n in need: - append_needs(n,flag) - elif type(need)==types.StringType: - if not need: return - if includes0.has_key(need): n = 'includes0' - elif includes.has_key(need): n = 'includes' - elif typedefs.has_key(need): n = 'typedefs' - elif typedefs_generated.has_key(need): n = 'typedefs_generated' - elif cppmacros.has_key(need): n = 'cppmacros' - elif cfuncs.has_key(need): n = 'cfuncs' - elif callbacks.has_key(need): n = 'callbacks' - elif f90modhooks.has_key(need): n = 'f90modhooks' - elif commonhooks.has_key(need): n = 'commonhooks' - else: - errmess('append_needs: unknown need %s\n'%(`need`)) - return - if need in outneeds[n]: return - if flag: - tmp={} - if needs.has_key(need): - for nn in needs[need]: - t=append_needs(nn,0) - if type(t)==types.DictType: - for nnn in t.keys(): - if tmp.has_key(nnn): tmp[nnn]=tmp[nnn]+t[nnn] - else: tmp[nnn]=t[nnn] - for nn in tmp.keys(): - for nnn in tmp[nn]: - if nnn not in outneeds[nn]: - outneeds[nn]=[nnn]+outneeds[nn] - outneeds[n].append(need) - else: - tmp={} - if needs.has_key(need): - for nn in needs[need]: - t=append_needs(nn,flag) - if type(t)==types.DictType: - for nnn in t.keys(): - if tmp.has_key(nnn): tmp[nnn]=t[nnn]+tmp[nnn] - else: tmp[nnn]=t[nnn] - if not tmp.has_key(n): tmp[n]=[] - tmp[n].append(need) - return tmp - else: - errmess('append_needs: expected list or string but got :%s\n'%(`need`)) - -def get_needs(): - global outneeds,needs - res={} - for n in outneeds.keys(): - out=[] - saveout=copy.copy(outneeds[n]) - while len(outneeds[n])>0: - if not needs.has_key(outneeds[n][0]): - out.append(outneeds[n][0]) - del outneeds[n][0] - else: - flag=0 - for k in outneeds[n][1:]: - if k in needs[outneeds[n][0]]: - flag=1 - break - if flag: - outneeds[n]=outneeds[n][1:]+[outneeds[n][0]] - else: - out.append(outneeds[n][0]) - del outneeds[n][0] - if saveout and (0 not in map(lambda x,y:x==y,saveout,outneeds[n])): - print n,saveout - errmess('get_needs: no progress in sorting needs, probably circular dependence, skipping.\n') - out=out+saveout - break - saveout=copy.copy(outneeds[n]) - if out==[]: out=[n] - res[n]=out - return res diff --git a/numpy/f2py/common_rules.py b/numpy/f2py/common_rules.py deleted file mode 100644 index d97a89cf8..000000000 --- a/numpy/f2py/common_rules.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -""" - -Build common block mechanism for f2py2e. - -Copyright 2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/05/06 10:57:33 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.19 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import pprint -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -import capi_maps -import cfuncs -import func2subr -from crackfortran import rmbadname -############## - -def findcommonblocks(block,top=1): - ret = [] - if hascommon(block): - for n in block['common'].keys(): - vars={} - for v in block['common'][n]: - vars[v]=block['vars'][v] - ret.append((n,block['common'][n],vars)) - elif hasbody(block): - for b in block['body']: - ret=ret+findcommonblocks(b,0) - if top: - tret=[] - names=[] - for t in ret: - if t[0] not in names: - names.append(t[0]) - tret.append(t) - return tret - return ret - -def buildhooks(m): - ret = {'commonhooks':[],'initcommonhooks':[],'docs':['"COMMON blocks:\\n"']} - fwrap = [''] - def fadd(line,s=fwrap): s[0] = '%s\n %s'%(s[0],line) - chooks = [''] - def cadd(line,s=chooks): s[0] = '%s\n%s'%(s[0],line) - ihooks = [''] - def iadd(line,s=ihooks): s[0] = '%s\n%s'%(s[0],line) - doc = [''] - def dadd(line,s=doc): s[0] = '%s\n%s'%(s[0],line) - for (name,vnames,vars) in findcommonblocks(m): - lower_name = string.lower(name) - hnames,inames = [],[] - for n in vnames: - if isintent_hide(vars[n]): hnames.append(n) - else: inames.append(n) - if hnames: - outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n\t\t Hidden: %s\n'%(name,string.join(inames,','),string.join(hnames,','))) - else: - outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n'%(name,string.join(inames,','))) - fadd('subroutine f2pyinit%s(setupfunc)'%name) - fadd('external setupfunc') - for n in vnames: - fadd(func2subr.var2fixfortran(vars,n)) - if name=='_BLNK_': - fadd('common %s'%(string.join(vnames,','))) - else: - fadd('common /%s/ %s'%(name,string.join(vnames,','))) - fadd('call setupfunc(%s)'%(string.join(inames,','))) - fadd('end\n') - cadd('static FortranDataDef f2py_%s_def[] = {'%(name)) - idims=[] - for n in inames: - ct = capi_maps.getctype(vars[n]) - at = capi_maps.c2capi_map[ct] - dm = capi_maps.getarrdims(n,vars[n]) - if dm['dims']: idims.append('(%s)'%(dm['dims'])) - else: idims.append('') - dms=string.strip(dm['dims']) - if not dms: dms='-1' - cadd('\t{\"%s\",%s,{{%s}},%s},'%(n,dm['rank'],dms,at)) - cadd('\t{NULL}\n};') - inames1 = rmbadname(inames) - inames1_tps = string.join(map(lambda s:'char *'+s,inames1),',') - cadd('static void f2py_setup_%s(%s) {'%(name,inames1_tps)) - cadd('\tint i_f2py=0;') - for n in inames1: - cadd('\tf2py_%s_def[i_f2py++].data = %s;'%(name,n)) - cadd('}') - if '_' in lower_name: - F_FUNC='F_FUNC_US' - else: - F_FUNC='F_FUNC' - cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'\ - %(F_FUNC,lower_name,string.upper(name), - string.join(['char*']*len(inames1),','))) - cadd('static void f2py_init_%s(void) {'%name) - cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'\ - %(F_FUNC,lower_name,string.upper(name),name)) - cadd('}\n') - iadd('\tF2PyDict_SetItemString(d, \"%s\", PyFortranObject_New(f2py_%s_def,f2py_init_%s));'%(name,name,name)) - tname = string.replace(name,'_','\\_') - dadd('\\subsection{Common block \\texttt{%s}}\n'%(tname)) - dadd('\\begin{description}') - for n in inames: - dadd('\\item[]{{}\\verb@%s@{}}'%(capi_maps.getarrdocsign(n,vars[n]))) - if hasnote(vars[n]): - note = vars[n]['note'] - if type(note) is type([]): note=string.join(note,'\n') - dadd('--- %s'%(note)) - dadd('\\end{description}') - ret['docs'].append('"\t/%s/ %s\\n"'%(name,string.join(map(lambda v,d:v+d,inames,idims),','))) - ret['commonhooks']=chooks - ret['initcommonhooks']=ihooks - ret['latexdoc']=doc[0] - if len(ret['docs'])<=1: ret['docs']='' - return ret,fwrap[0] diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py deleted file mode 100755 index 74007c0c7..000000000 --- a/numpy/f2py/crackfortran.py +++ /dev/null @@ -1,2670 +0,0 @@ -#!/usr/bin/env python -""" -crackfortran --- read fortran (77,90) code and extract declaration information. - Usage is explained in the comment block below. - -Copyright 1999-2004 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/09/27 07:13:49 $ -Pearu Peterson -""" -__version__ = "$Revision: 1.177 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -""" - Usage of crackfortran: - ====================== - Command line keys: -quiet,-verbose,-fix,-f77,-f90,-show,-h <pyffilename> - -m <module name for f77 routines>,--ignore-contains - Functions: crackfortran, crack2fortran - The following Fortran statements/constructions are supported - (or will be if needed): - block data,byte,call,character,common,complex,contains,data, - dimension,double complex,double precision,end,external,function, - implicit,integer,intent,interface,intrinsic, - logical,module,optional,parameter,private,public, - program,real,(sequence?),subroutine,type,use,virtual, - include,pythonmodule - Note: 'virtual' is mapped to 'dimension'. - Note: 'implicit integer (z) static (z)' is 'implicit static (z)' (this is minor bug). - Note: code after 'contains' will be ignored until its scope ends. - Note: 'common' statement is extended: dimensions are moved to variable definitions - Note: f2py directive: <commentchar>f2py<line> is read as <line> - Note: pythonmodule is introduced to represent Python module - - Usage: - `postlist=crackfortran(files,funcs)` - `postlist` contains declaration information read from the list of files `files`. - `crack2fortran(postlist)` returns a fortran code to be saved to pyf-file - - `postlist` has the following structure: - *** it is a list of dictionaries containing `blocks': - B = {'block','body','vars','parent_block'[,'name','prefix','args','result', - 'implicit','externals','interfaced','common','sortvars', - 'commonvars','note']} - B['block'] = 'interface' | 'function' | 'subroutine' | 'module' | - 'program' | 'block data' | 'type' | 'pythonmodule' - B['body'] --- list containing `subblocks' with the same structure as `blocks' - B['parent_block'] --- dictionary of a parent block: - C['body'][<index>]['parent_block'] is C - B['vars'] --- dictionary of variable definitions - B['sortvars'] --- dictionary of variable definitions sorted by dependence (independent first) - B['name'] --- name of the block (not if B['block']=='interface') - B['prefix'] --- prefix string (only if B['block']=='function') - B['args'] --- list of argument names if B['block']== 'function' | 'subroutine' - B['result'] --- name of the return value (only if B['block']=='function') - B['implicit'] --- dictionary {'a':<variable definition>,'b':...} | None - B['externals'] --- list of variables being external - B['interfaced'] --- list of variables being external and defined - B['common'] --- dictionary of common blocks (list of objects) - B['commonvars'] --- list of variables used in common blocks (dimensions are moved to variable definitions) - B['from'] --- string showing the 'parents' of the current block - B['use'] --- dictionary of modules used in current block: - {<modulename>:{['only':<0|1>],['map':{<local_name1>:<use_name1>,...}]}} - B['note'] --- list of LaTeX comments on the block - B['f2pyenhancements'] --- optional dictionary - {'threadsafe':'','fortranname':<name>, - 'callstatement':<C-expr>|<multi-line block>, - 'callprotoargument':<C-expr-list>, - 'usercode':<multi-line block>|<list of multi-line blocks>, - 'pymethoddef:<multi-line block>' - } - B['entry'] --- dictionary {entryname:argslist,..} - B['varnames'] --- list of variable names given in the order of reading the - Fortran code, useful for derived types. - *** Variable definition is a dictionary - D = B['vars'][<variable name>] = - {'typespec'[,'attrspec','kindselector','charselector','=','typename']} - D['typespec'] = 'byte' | 'character' | 'complex' | 'double complex' | - 'double precision' | 'integer' | 'logical' | 'real' | 'type' - D['attrspec'] --- list of attributes (e.g. 'dimension(<arrayspec>)', - 'external','intent(in|out|inout|hide|c|callback|cache)', - 'optional','required', etc) - K = D['kindselector'] = {['*','kind']} (only if D['typespec'] = - 'complex' | 'integer' | 'logical' | 'real' ) - C = D['charselector'] = {['*','len','kind']} - (only if D['typespec']=='character') - D['='] --- initialization expression string - D['typename'] --- name of the type if D['typespec']=='type' - D['dimension'] --- list of dimension bounds - D['intent'] --- list of intent specifications - D['depend'] --- list of variable names on which current variable depends on - D['check'] --- list of C-expressions; if C-expr returns zero, exception is raised - D['note'] --- list of LaTeX comments on the variable - *** Meaning of kind/char selectors (few examples): - D['typespec>']*K['*'] - D['typespec'](kind=K['kind']) - character*C['*'] - character(len=C['len'],kind=C['kind']) - (see also fortran type declaration statement formats below) - - Fortran 90 type declaration statement format (F77 is subset of F90) -==================================================================== - (Main source: IBM XL Fortran 5.1 Language Reference Manual) - type declaration = <typespec> [[<attrspec>]::] <entitydecl> - <typespec> = byte | - character[<charselector>] | - complex[<kindselector>] | - double complex | - double precision | - integer[<kindselector>] | - logical[<kindselector>] | - real[<kindselector>] | - type(<typename>) - <charselector> = * <charlen> | - ([len=]<len>[,[kind=]<kind>]) | - (kind=<kind>[,len=<len>]) - <kindselector> = * <intlen> | - ([kind=]<kind>) - <attrspec> = comma separated list of attributes. - Only the following attributes are used in - building up the interface: - external - (parameter --- affects '=' key) - optional - intent - Other attributes are ignored. - <intentspec> = in | out | inout - <arrayspec> = comma separated list of dimension bounds. - <entitydecl> = <name> [[*<charlen>][(<arrayspec>)] | [(<arrayspec>)]*<charlen>] - [/<init_expr>/ | =<init_expr>] [,<entitydecl>] - - In addition, the following attributes are used: check,depend,note - - TODO: - * Apply 'parameter' attribute (e.g. 'integer parameter :: i=2' 'real x(i)' - -> 'real x(2)') - The above may be solved by creating appropriate preprocessor program, for example. -""" -# -import sys,string,fileinput,re,pprint,os,copy -from auxfuncs import * - -# Global flags: -strictf77=1 # Ignore `!' comments unless line[0]=='!' -sourcecodeform='fix' # 'fix','free' -quiet=0 # Be verbose if 0 (Obsolete: not used any more) -verbose=1 # Be quiet if 0, extra verbose if > 1. -tabchar=4*' ' -pyffilename='' -f77modulename='' -skipemptyends=0 # for old F77 programs without 'program' statement -ignorecontains=1 -dolowercase=1 -debug=[] -## do_analyze = 1 - -###### global variables - -## use reload(crackfortran) to reset these variables - -groupcounter=0 -grouplist={groupcounter:[]} -neededmodule=-1 -expectbegin=1 -skipblocksuntil=-1 -usermodules=[] -f90modulevars={} -gotnextfile=1 -filepositiontext='' -currentfilename='' -skipfunctions=[] -skipfuncs=[] -onlyfuncs=[] -include_paths=[] -previous_context = None - -###### Some helper functions -def show(o,f=0):pprint.pprint(o) -errmess=sys.stderr.write -def outmess(line,flag=1): - global filepositiontext - if not verbose: return - if not quiet: - if flag:sys.stdout.write(filepositiontext) - sys.stdout.write(line) -re._MAXCACHE=50 -defaultimplicitrules={} -for c in "abcdefghopqrstuvwxyz$_": defaultimplicitrules[c]={'typespec':'real'} -for c in "ijklmn": defaultimplicitrules[c]={'typespec':'integer'} -del c -badnames={} -invbadnames={} -for n in ['int','double','float','char','short','long','void','case','while', - 'return','signed','unsigned','if','for','typedef','sizeof','union', - 'struct','static','register','new','break','do','goto','switch', - 'continue','else','inline','extern','delete','const','auto', - 'len','rank','shape','index','slen','size','_i', - 'flen','fshape', - 'string','complex_double','float_double','stdin','stderr','stdout', - 'type','default']: - badnames[n]=n+'_bn' - invbadnames[n+'_bn']=n -def rmbadname1(name): - if badnames.has_key(name): - errmess('rmbadname1: Replacing "%s" with "%s".\n'%(name,badnames[name])) - return badnames[name] - return name -def rmbadname(names): return map(rmbadname1,names) - -def undo_rmbadname1(name): - if invbadnames.has_key(name): - errmess('undo_rmbadname1: Replacing "%s" with "%s".\n'\ - %(name,invbadnames[name])) - return invbadnames[name] - return name -def undo_rmbadname(names): return map(undo_rmbadname1,names) - -def getextension(name): - i=string.rfind(name,'.') - if i==-1: return '' - if '\\' in name[i:]: return '' - if '/' in name[i:]: return '' - return name[i+1:] - -is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z',re.I).match -_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-',re.I).search -_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-',re.I).search -_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-',re.I).search -_free_f90_start = re.compile(r'[^c*]\s*[^\s\d\t]',re.I).match -def is_free_format(file): - """Check if file is in free format Fortran.""" - # f90 allows both fixed and free format, assuming fixed unless - # signs of free format are detected. - result = 0 - f = open(file,'r') - line = f.readline() - n = 15 # the number of non-comment lines to scan for hints - if _has_f_header(line): - n = 0 - elif _has_f90_header(line): - n = 0 - result = 1 - while n>0 and line: - if line[0]!='!': - n -= 1 - if (line[0]!='\t' and _free_f90_start(line[:5])) or line[-2:-1]=='&': - result = 1 - break - line = f.readline() - f.close() - return result - - -####### Read fortran (77,90) code -def readfortrancode(ffile,dowithline=show,istop=1): - """ - Read fortran codes from files and - 1) Get rid of comments, line continuations, and empty lines; lower cases. - 2) Call dowithline(line) on every line. - 3) Recursively call itself when statement \"include '<filename>'\" is met. - """ - global gotnextfile,filepositiontext,currentfilename,sourcecodeform,strictf77,\ - beginpattern,quiet,verbose,dolowercase,include_paths - if not istop: - saveglobals=gotnextfile,filepositiontext,currentfilename,sourcecodeform,strictf77,\ - beginpattern,quiet,verbose,dolowercase - if ffile==[]: return - localdolowercase = dolowercase - cont=0 - finalline='' - ll='' - commentline=re.compile(r'(?P<line>([^"]*"[^"]*"[^"!]*|[^\']*\'[^\']*\'[^\'!]*|[^!]*))!{1}(?P<rest>.*)') - includeline=re.compile(r'\s*include\s*(\'|")(?P<name>[^\'"]*)(\'|")',re.I) - cont1=re.compile(r'(?P<line>.*)&\s*\Z') - cont2=re.compile(r'(\s*&|)(?P<line>.*)') - mline_mark = re.compile(r".*?'''") - if istop: dowithline('',-1) - ll,l1='','' - spacedigits=[' ']+map(str,range(10)) - filepositiontext='' - fin=fileinput.FileInput(ffile) - while 1: - l=fin.readline() - if not l: break - if fin.isfirstline(): - filepositiontext='' - currentfilename=fin.filename() - gotnextfile=1 - l1=l - strictf77=0 - sourcecodeform='fix' - ext = os.path.splitext(currentfilename)[1] - if is_f_file(currentfilename) and \ - not (_has_f90_header(l) or _has_fix_header(l)): - strictf77=1 - elif is_free_format(currentfilename) and not _has_fix_header(l): - sourcecodeform='free' - if strictf77: beginpattern=beginpattern77 - else: beginpattern=beginpattern90 - outmess('\tReading file %s (format:%s%s)\n'\ - %(`currentfilename`,sourcecodeform, - strictf77 and ',strict' or '')) - - l=string.expandtabs(l).replace('\xa0',' ') - while not l=='': # Get rid of newline characters - if l[-1] not in "\n\r\f": break - l=l[:-1] - if not strictf77: - r=commentline.match(l) - if r: - l=r.group('line')+' ' # Strip comments starting with `!' - rl=r.group('rest') - if string.lower(rl[:4])=='f2py': # f2py directive - l = l + 4*' ' - r=commentline.match(rl[4:]) - if r: l=l+r('line') - else: l = l + rl[4:] - if string.strip(l)=='': # Skip empty line - cont=0 - continue - if sourcecodeform=='fix': - if l[0] in ['*','c','!','C','#']: - if string.lower(l[1:5])=='f2py': # f2py directive - l=' '+l[5:] - else: # Skip comment line - cont=0 - continue - elif strictf77: - if len(l)>72: l=l[:72] - if not (l[0] in spacedigits): - raise 'readfortrancode: Found non-(space,digit) char in the first column.\n\tAre you sure that this code is in fix form?\n\tline=%s'%`l` - - if (not cont or strictf77) and (len(l)>5 and not l[5]==' '): - # Continuation of a previous line - ll=ll+l[6:] - finalline='' - origfinalline='' - else: - if not strictf77: - # F90 continuation - r=cont1.match(l) - if r: l=r.group('line') # Continuation follows .. - if cont: - ll=ll+cont2.match(l).group('line') - finalline='' - origfinalline='' - else: - l=' '+l[5:] # clean up line beginning from possible digits. - if localdolowercase: finalline=string.lower(ll) - else: finalline=ll - origfinalline=ll - ll=l - cont=(r is not None) - else: - l=' '+l[5:] # clean up line beginning from possible digits. - if localdolowercase: finalline=string.lower(ll) - else: finalline=ll - origfinalline =ll - ll=l - - elif sourcecodeform=='free': - if not cont and ext=='.pyf' and mline_mark.match(l): - l = l + '\n' - while 1: - lc = fin.readline() - if not lc: - errmess('Unexpected end of file when reading multiline\n') - break - l = l + lc - if mline_mark.match(lc): - break - l = l.rstrip() - r=cont1.match(l) - if r: l=r.group('line') # Continuation follows .. - if cont: - ll=ll+cont2.match(l).group('line') - finalline='' - origfinalline='' - else: - if localdolowercase: finalline=string.lower(ll) - else: finalline=ll - origfinalline =ll - ll=l - cont=(r is not None) - else: - raise ValueError,"Flag sourcecodeform must be either 'fix' or 'free': %s"%`sourcecodeform` - filepositiontext='Line #%d in %s:"%s"\n\t' % (fin.filelineno()-1,currentfilename,l1) - m=includeline.match(origfinalline) - if m: - fn=m.group('name') - if os.path.isfile(fn): - readfortrancode(fn,dowithline=dowithline,istop=0) - else: - include_dirs = [os.path.dirname(currentfilename)] + include_paths - foundfile = 0 - for inc_dir in include_dirs: - fn1 = os.path.join(inc_dir,fn) - if os.path.isfile(fn1): - foundfile = 1 - readfortrancode(fn1,dowithline=dowithline,istop=0) - break - if not foundfile: - outmess('readfortrancode: could not find include file %s. Ignoring.\n'%(`fn`)) - else: - dowithline(finalline) - l1=ll - if localdolowercase: - finalline=string.lower(ll) - else: finalline=ll - origfinalline = ll - filepositiontext='Line #%d in %s:"%s"\n\t' % (fin.filelineno()-1,currentfilename,l1) - m=includeline.match(origfinalline) - if m: - fn=m.group('name') - fn1=os.path.join(os.path.dirname(currentfilename),fn) - if os.path.isfile(fn): - readfortrancode(fn,dowithline=dowithline,istop=0) - elif os.path.isfile(fn1): - readfortrancode(fn1,dowithline=dowithline,istop=0) - else: - outmess('readfortrancode: could not find include file %s. Ignoring.\n'%(`fn`)) - else: - dowithline(finalline) - filepositiontext='' - fin.close() - if istop: dowithline('',1) - else: - gotnextfile,filepositiontext,currentfilename,sourcecodeform,strictf77,\ - beginpattern,quiet,verbose,dolowercase=saveglobals - -########### Crack line -beforethisafter=r'\s*(?P<before>%s(?=\s*(\b(%s)\b)))'+ \ - r'\s*(?P<this>(\b(%s)\b))'+ \ - r'\s*(?P<after>%s)\s*\Z' -## -fortrantypes='character|logical|integer|real|complex|double\s*(precision\s*(complex|)|complex)|type(?=\s*\([\w\s,=(*)]*\))|byte' -typespattern=re.compile(beforethisafter%('',fortrantypes,fortrantypes,'.*'),re.I),'type' -typespattern4implicit=re.compile(beforethisafter%('',fortrantypes+'|static|automatic|undefined',fortrantypes+'|static|automatic|undefined','.*'),re.I) -# -functionpattern=re.compile(beforethisafter%('([a-z]+[\w\s(=*+-/)]*?|)','function','function','.*'),re.I),'begin' -subroutinepattern=re.compile(beforethisafter%('[a-z\s]*?','subroutine','subroutine','.*'),re.I),'begin' -#modulepattern=re.compile(beforethisafter%('[a-z\s]*?','module','module','.*'),re.I),'begin' -# -groupbegins77=r'program|block\s*data' -beginpattern77=re.compile(beforethisafter%('',groupbegins77,groupbegins77,'.*'),re.I),'begin' -groupbegins90=groupbegins77+r'|module|python\s*module|interface|type(?!\s*\()' -beginpattern90=re.compile(beforethisafter%('',groupbegins90,groupbegins90,'.*'),re.I),'begin' -groupends=r'end|endprogram|endblockdata|endmodule|endpythonmodule|endinterface' -endpattern=re.compile(beforethisafter%('',groupends,groupends,'[\w\s]*'),re.I),'end' -#endifs='end\s*(if|do|where|select|while|forall)' -endifs='(end\s*(if|do|where|select|while|forall))|(module\s*procedure)' -endifpattern=re.compile(beforethisafter%('[\w]*?',endifs,endifs,'[\w\s]*'),re.I),'endif' -# -implicitpattern=re.compile(beforethisafter%('','implicit','implicit','.*'),re.I),'implicit' -dimensionpattern=re.compile(beforethisafter%('','dimension|virtual','dimension|virtual','.*'),re.I),'dimension' -externalpattern=re.compile(beforethisafter%('','external','external','.*'),re.I),'external' -optionalpattern=re.compile(beforethisafter%('','optional','optional','.*'),re.I),'optional' -requiredpattern=re.compile(beforethisafter%('','required','required','.*'),re.I),'required' -publicpattern=re.compile(beforethisafter%('','public','public','.*'),re.I),'public' -privatepattern=re.compile(beforethisafter%('','private','private','.*'),re.I),'private' -intrisicpattern=re.compile(beforethisafter%('','intrisic','intrisic','.*'),re.I),'intrisic' -intentpattern=re.compile(beforethisafter%('','intent|depend|note|check','intent|depend|note|check','\s*\(.*?\).*'),re.I),'intent' -parameterpattern=re.compile(beforethisafter%('','parameter','parameter','\s*\(.*'),re.I),'parameter' -datapattern=re.compile(beforethisafter%('','data','data','.*'),re.I),'data' -callpattern=re.compile(beforethisafter%('','call','call','.*'),re.I),'call' -entrypattern=re.compile(beforethisafter%('','entry','entry','.*'),re.I),'entry' -callfunpattern=re.compile(beforethisafter%('','callfun','callfun','.*'),re.I),'callfun' -commonpattern=re.compile(beforethisafter%('','common','common','.*'),re.I),'common' -usepattern=re.compile(beforethisafter%('','use','use','.*'),re.I),'use' -containspattern=re.compile(beforethisafter%('','contains','contains',''),re.I),'contains' -formatpattern=re.compile(beforethisafter%('','format','format','.*'),re.I),'format' -## Non-fortran and f2py-specific statements -f2pyenhancementspattern=re.compile(beforethisafter%('','threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef','threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef','.*'),re.I|re.S),'f2pyenhancements' -multilinepattern = re.compile(r"\s*(?P<before>''')(?P<this>.*?)(?P<after>''')\s*\Z",re.S),'multiline' -## - -def _simplifyargs(argsline): - a = [] - for n in string.split(markoutercomma(argsline),'@,@'): - for r in '(),': - n = string.replace(n,r,'_') - a.append(n) - return string.join(a,',') - -crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+[\w]*\b)\s*[=].*',re.I) -def crackline(line,reset=0): - """ - reset=-1 --- initialize - reset=0 --- crack the line - reset=1 --- final check if mismatch of blocks occured - - Cracked data is saved in grouplist[0]. - """ - global beginpattern,groupcounter,groupname,groupcache,grouplist,gotnextfile,\ - filepositiontext,currentfilename,neededmodule,expectbegin,skipblocksuntil,\ - skipemptyends,previous_context - if ';' in line and not (f2pyenhancementspattern[0].match(line) or - multilinepattern[0].match(line)): - for l in line.split(';'): - assert reset==0,`reset` # XXX: non-zero reset values need testing - crackline(l,reset) - return - if reset<0: - groupcounter=0 - groupname={groupcounter:''} - groupcache={groupcounter:{}} - grouplist={groupcounter:[]} - groupcache[groupcounter]['body']=[] - groupcache[groupcounter]['vars']={} - groupcache[groupcounter]['block']='' - groupcache[groupcounter]['name']='' - neededmodule=-1 - skipblocksuntil=-1 - return - if reset>0: - fl=0 - if f77modulename and neededmodule==groupcounter: fl=2 - while groupcounter>fl: - outmess('crackline: groupcounter=%s groupname=%s\n'%(`groupcounter`,`groupname`)) - outmess('crackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement.\n') - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 - if f77modulename and neededmodule==groupcounter: - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 # end interface - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 # end module - neededmodule=-1 - return - if line=='': return - flag=0 - for pat in [dimensionpattern,externalpattern,intentpattern,optionalpattern, - requiredpattern, - parameterpattern,datapattern,publicpattern,privatepattern, - intrisicpattern, - endifpattern,endpattern, - formatpattern, - beginpattern,functionpattern,subroutinepattern, - implicitpattern,typespattern,commonpattern, - callpattern,usepattern,containspattern, - entrypattern, - f2pyenhancementspattern, - multilinepattern - ]: - m = pat[0].match(line) - if m: - break - flag=flag+1 - if not m: - re_1 = crackline_re_1 - if 0<=skipblocksuntil<=groupcounter:return - if groupcache[groupcounter].has_key('externals'): - for name in groupcache[groupcounter]['externals']: - if invbadnames.has_key(name): - name=invbadnames[name] - if groupcache[groupcounter].has_key('interfaced') and name in groupcache[groupcounter]['interfaced']: continue - m1=re.match(r'(?P<before>[^"]*)\b%s\b\s*@\(@(?P<args>[^@]*)@\)@.*\Z'%name,markouterparen(line),re.I) - if m1: - m2 = re_1.match(m1.group('before')) - a = _simplifyargs(m1.group('args')) - if m2: - line='callfun %s(%s) result (%s)'%(name,a,m2.group('result')) - else: line='callfun %s(%s)'%(name,a) - m = callfunpattern[0].match(line) - if not m: - outmess('crackline: could not resolve function call for line=%s.\n'%`line`) - return - analyzeline(m,'callfun',line) - return - if verbose>1: - previous_context = None - outmess('crackline:%d: No pattern for line\n'%(groupcounter)) - return - elif pat[1]=='end': - if 0<=skipblocksuntil<groupcounter: - groupcounter=groupcounter-1 - if skipblocksuntil<=groupcounter: return - if groupcounter<=0: - raise 'crackline: groupcounter(=%s) is nonpositive. Check the blocks.'\ - % (groupcounter) - m1 = beginpattern[0].match((line)) - if (m1) and (not m1.group('this')==groupname[groupcounter]): - raise 'crackline: End group %s does not match with previous Begin group %s\n\t%s'%(`m1.group('this')`,`groupname[groupcounter]`,filepositiontext) - if skipblocksuntil==groupcounter: - skipblocksuntil=-1 - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 - if not skipemptyends: - expectbegin=1 - elif pat[1] == 'begin': - if 0<=skipblocksuntil<=groupcounter: - groupcounter=groupcounter+1 - return - gotnextfile=0 - analyzeline(m,pat[1],line) - expectbegin=0 - elif pat[1]=='endif': - pass - elif pat[1]=='contains': - if ignorecontains: return - if 0<=skipblocksuntil<=groupcounter: return - skipblocksuntil=groupcounter - else: - if 0<=skipblocksuntil<=groupcounter:return - analyzeline(m,pat[1],line) - -def markouterparen(line): - l='';f=0 - for c in line: - if c=='(': - f=f+1 - if f==1: l=l+'@(@'; continue - elif c==')': - f=f-1 - if f==0: l=l+'@)@'; continue - l=l+c - return l -def markoutercomma(line,comma=','): - l='';f=0 - cc='' - for c in line: - if (not cc or cc==')') and c=='(': - f=f+1 - cc = ')' - elif not cc and c=='\'' and (not l or l[-1]!='\\'): - f=f+1 - cc = '\'' - elif c==cc: - f=f-1 - if f==0: - cc='' - elif c==comma and f==0: - l=l+'@'+comma+'@' - continue - l=l+c - assert not f,`f,line,l,cc` - return l -def unmarkouterparen(line): - r = string.replace(string.replace(line,'@(@','('),'@)@',')') - return r -def appenddecl(decl,decl2,force=1): - if not decl: decl={} - if not decl2: return decl - if decl is decl2: return decl - for k in decl2.keys(): - if k=='typespec': - if force or not decl.has_key(k): decl[k]=decl2[k] - elif k=='attrspec': - for l in decl2[k]: - decl=setattrspec(decl,l,force) - elif k=='kindselector': - decl=setkindselector(decl,decl2[k],force) - elif k=='charselector': - decl=setcharselector(decl,decl2[k],force) - elif k in ['=','typename']: - if force or not decl.has_key(k): decl[k]=decl2[k] - elif k=='note': - pass - elif k in ['intent','check','dimension','optional','required']: - errmess('appenddecl: "%s" not implemented.\n'%k) - else: - raise 'appenddecl: Unknown variable definition key:', k - return decl - -selectpattern=re.compile(r'\s*(?P<this>(@\(@.*?@\)@|[*][\d*]+|[*]\s*@\(@.*?@\)@|))(?P<after>.*)\Z',re.I) -nameargspattern=re.compile(r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*(result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))*\s*\Z',re.I) -callnameargspattern=re.compile(r'\s*(?P<name>\b[\w$]+\b)\s*@\(@\s*(?P<args>.*)\s*@\)@\s*\Z',re.I) -real16pattern = re.compile(r'([-+]?(?:\d+(?:\.\d*)?|\d*\.\d+))[dD]((?:[-+]?\d+)?)') -real8pattern = re.compile(r'([-+]?((?:\d+(?:\.\d*)?|\d*\.\d+))[eE]((?:[-+]?\d+)?)|(\d+\.\d*))') - -_intentcallbackpattern = re.compile(r'intent\s*\(.*?\bcallback\b',re.I) -def _is_intent_callback(vdecl): - for a in vdecl.get('attrspec',[]): - if _intentcallbackpattern.match(a): - return 1 - return 0 - -def _resolvenameargspattern(line): - line = markouterparen(line) - m1=nameargspattern.match(line) - if m1: return m1.group('name'),m1.group('args'),m1.group('result') - m1=callnameargspattern.match(line) - if m1: return m1.group('name'),m1.group('args'),None - return None,[],None - -def analyzeline(m,case,line): - global groupcounter,groupname,groupcache,grouplist,filepositiontext,\ - currentfilename,f77modulename,neededinterface,neededmodule,expectbegin,\ - gotnextfile,previous_context - block=m.group('this') - if case != 'multiline': - previous_context = None - if expectbegin and case not in ['begin','call','callfun','type'] \ - and not skipemptyends and groupcounter<1: - newname=string.split(os.path.basename(currentfilename),'.')[0] - outmess('analyzeline: no group yet. Creating program group with name "%s".\n'%newname) - gotnextfile=0 - groupcounter=groupcounter+1 - groupname[groupcounter]='program' - groupcache[groupcounter]={} - grouplist[groupcounter]=[] - groupcache[groupcounter]['body']=[] - groupcache[groupcounter]['vars']={} - groupcache[groupcounter]['block']='program' - groupcache[groupcounter]['name']=newname - groupcache[groupcounter]['from']='fromsky' - expectbegin=0 - if case in ['begin','call','callfun']: - # Crack line => block,name,args,result - block = block.lower() - if re.match(r'block\s*data',block,re.I): block='block data' - if re.match(r'python\s*module',block,re.I): block='python module' - name,args,result = _resolvenameargspattern(m.group('after')) - if name is None: - if block=='block data': - name = '_BLOCK_DATA_' - else: - name = '' - if block not in ['interface','block data']: - outmess('analyzeline: No name/args pattern found for line.\n') - - previous_context = (block,name,groupcounter) - if args: args=rmbadname(map(string.strip,string.split(markoutercomma(args),'@,@'))) - else: args=[] - if '' in args: - while '' in args: - args.remove('') - outmess('analyzeline: argument list is malformed (missing argument).\n') - - # end of crack line => block,name,args,result - needmodule=0 - needinterface=0 - - if case in ['call','callfun']: - needinterface=1 - if not groupcache[groupcounter].has_key('args'): return - if name not in groupcache[groupcounter]['args']: - return - for it in grouplist[groupcounter]: - if it['name']==name: return - if name in groupcache[groupcounter]['interfaced']: return - block={'call':'subroutine','callfun':'function'}[case] - if f77modulename and neededmodule==-1 and groupcounter<=1: - neededmodule=groupcounter+2 - needmodule=1 - needinterface=1 - # Create new block(s) - groupcounter=groupcounter+1 - groupcache[groupcounter]={} - grouplist[groupcounter]=[] - if needmodule: - if verbose>1: - outmess('analyzeline: Creating module block %s\n'%`f77modulename`,0) - groupname[groupcounter]='module' - groupcache[groupcounter]['block']='python module' - groupcache[groupcounter]['name']=f77modulename - groupcache[groupcounter]['from']='' - groupcache[groupcounter]['body']=[] - groupcache[groupcounter]['externals']=[] - groupcache[groupcounter]['interfaced']=[] - groupcache[groupcounter]['vars']={} - groupcounter=groupcounter+1 - groupcache[groupcounter]={} - grouplist[groupcounter]=[] - if needinterface: - if verbose>1: - outmess('analyzeline: Creating additional interface block.\n',0) - groupname[groupcounter]='interface' - groupcache[groupcounter]['block']='interface' - groupcache[groupcounter]['name']='unknown_interface' - groupcache[groupcounter]['from']='%s:%s'%(groupcache[groupcounter-1]['from'],groupcache[groupcounter-1]['name']) - groupcache[groupcounter]['body']=[] - groupcache[groupcounter]['externals']=[] - groupcache[groupcounter]['interfaced']=[] - groupcache[groupcounter]['vars']={} - groupcounter=groupcounter+1 - groupcache[groupcounter]={} - grouplist[groupcounter]=[] - groupname[groupcounter]=block - groupcache[groupcounter]['block']=block - if not name: name='unknown_'+block - groupcache[groupcounter]['prefix']=m.group('before') - groupcache[groupcounter]['name']=rmbadname1(name) - groupcache[groupcounter]['result']=result - if groupcounter==1: - groupcache[groupcounter]['from']=currentfilename - else: - if f77modulename and groupcounter==3: - groupcache[groupcounter]['from']='%s:%s'%(groupcache[groupcounter-1]['from'],currentfilename) - else: - groupcache[groupcounter]['from']='%s:%s'%(groupcache[groupcounter-1]['from'],groupcache[groupcounter-1]['name']) - for k in groupcache[groupcounter].keys(): - if not groupcache[groupcounter][k]: del groupcache[groupcounter][k] - groupcache[groupcounter]['args']=args - groupcache[groupcounter]['body']=[] - groupcache[groupcounter]['externals']=[] - groupcache[groupcounter]['interfaced']=[] - groupcache[groupcounter]['vars']={} - groupcache[groupcounter]['entry']={} - # end of creation - if block=='type': - groupcache[groupcounter]['varnames'] = [] - - if case in ['call','callfun']: # set parents variables - if name not in groupcache[groupcounter-2]['externals']: - groupcache[groupcounter-2]['externals'].append(name) - groupcache[groupcounter]['vars']=copy.deepcopy(groupcache[groupcounter-2]['vars']) - #try: del groupcache[groupcounter]['vars'][groupcache[groupcounter-2]['name']] - #except: pass - try: del groupcache[groupcounter]['vars'][name][groupcache[groupcounter]['vars'][name]['attrspec'].index('external')] - except: pass - if block in ['function','subroutine']: # set global attributes - try: groupcache[groupcounter]['vars'][name]=appenddecl(groupcache[groupcounter]['vars'][name],groupcache[groupcounter-2]['vars']['']) - except: pass - if case=='callfun': # return type - if result and groupcache[groupcounter]['vars'].has_key(result): - if not name==result: - groupcache[groupcounter]['vars'][name]=appenddecl(groupcache[groupcounter]['vars'][name],groupcache[groupcounter]['vars'][result]) - #if groupcounter>1: # name is interfaced - try: groupcache[groupcounter-2]['interfaced'].append(name) - except: pass - if block=='function': - t=typespattern[0].match(m.group('before')+' '+name) - if t: - typespec,selector,attr,edecl=cracktypespec0(t.group('this'),t.group('after')) - updatevars(typespec,selector,attr,edecl) - if case in ['call','callfun']: - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 # end routine - grouplist[groupcounter-1].append(groupcache[groupcounter]) - grouplist[groupcounter-1][-1]['body']=grouplist[groupcounter] - del grouplist[groupcounter] - groupcounter=groupcounter-1 # end interface - elif case=='entry': - name,args,result=_resolvenameargspattern(m.group('after')) - if name is not None: - if args: - args=rmbadname(map(string.strip,string.split(markoutercomma(args),'@,@'))) - else: args=[] - assert result is None,`result` - groupcache[groupcounter]['entry'][name] = args - previous_context = ('entry',name,groupcounter) - elif case=='type': - typespec,selector,attr,edecl=cracktypespec0(block,m.group('after')) - last_name = updatevars(typespec,selector,attr,edecl) - if last_name is not None: - previous_context = ('variable',last_name,groupcounter) - elif case in ['dimension','intent','optional','required','external','public','private','intrisic']: - edecl=groupcache[groupcounter]['vars'] - ll=m.group('after').strip() - i=string.find(ll,'::') - if i<0 and case=='intent': - i=string.find(markouterparen(ll),'@)@')-2 - ll=ll[:i+1]+'::'+ll[i+1:] - i=string.find(ll,'::') - if ll[i:]=='::' and groupcache[groupcounter].has_key('args'): - outmess('All arguments will have attribute %s%s\n'%(m.group('this'),ll[:i])) - ll = ll + string.join(groupcache[groupcounter]['args'],',') - if i<0:i=0;pl='' - else: pl=string.strip(ll[:i]);ll=ll[i+2:] - ch = string.split(markoutercomma(pl),'@,@') - if len(ch)>1: - pl = ch[0] - outmess('analyzeline: cannot handle multiple attributes without type specification. Ignoring %r.\n' % (','.join(ch[1:]))) - last_name = None - for e in map(string.strip,string.split(markoutercomma(ll),'@,@')): - m1=namepattern.match(e) - if not m1: - if case in ['public','private']: k='' - else: - print m.groupdict() - outmess('analyzeline: no name pattern found in %s statement for %s. Skipping.\n'%(case,`e`)) - continue - else: - k=rmbadname1(m1.group('name')) - if not edecl.has_key(k): edecl[k]={} - if case=='dimension': ap=case+m1.group('after') - if case=='intent': - ap=m.group('this')+pl - if _intentcallbackpattern.match(ap): - if k not in groupcache[groupcounter]['args']: - if groupcounter>1 and \ - string.find(groupcache[groupcounter-2]['name'], - '__user__')==-1: - outmess('analyzeline: appending intent(callback) %s'\ - ' to %s arguments\n' % (k,groupcache[groupcounter]['name'])) - groupcache[groupcounter]['args'].append(k) - else: - errmess('analyzeline: intent(callback) %s is already'\ - ' in argument list' % (k)) - if case in ['optional','required','public','external','private','intrisic']: ap=case - if edecl[k].has_key('attrspec'): edecl[k]['attrspec'].append(ap) - else: edecl[k]['attrspec']=[ap] - if case=='external': - if groupcache[groupcounter]['block']=='program': - outmess('analyzeline: ignoring program arguments\n') - continue - if k not in groupcache[groupcounter]['args']: - #outmess('analyzeline: ignoring external %s (not in arguments list)\n'%(`k`)) - continue - if not groupcache[groupcounter].has_key('externals'): - groupcache[groupcounter]['externals']=[] - groupcache[groupcounter]['externals'].append(k) - last_name = k - groupcache[groupcounter]['vars']=edecl - if last_name is not None: - previous_context = ('variable',last_name,groupcounter) - elif case=='parameter': - edecl=groupcache[groupcounter]['vars'] - ll=string.strip(m.group('after'))[1:-1] - last_name = None - for e in string.split(markoutercomma(ll),'@,@'): - try: - k,initexpr=map(string.strip,string.split(e,'=')) - except: - outmess('analyzeline: could not extract name,expr in parameter statement "%s" of "%s"\n'%(e,ll));continue - params = get_parameters(edecl) - k=rmbadname1(k) - if not edecl.has_key(k): edecl[k]={} - if edecl[k].has_key('=') and (not edecl[k]['=']==initexpr): - outmess('analyzeline: Overwriting the value of parameter "%s" ("%s") with "%s".\n'%(k,edecl[k]['='],initexpr)) - t = determineexprtype(initexpr,params) - if t: - if t.get('typespec')=='real': - tt = list(initexpr) - for m in real16pattern.finditer(initexpr): - tt[m.start():m.end()] = list(\ - initexpr[m.start():m.end()].lower().replace('d', 'e')) - initexpr = "".join(tt) - elif t.get('typespec')=='complex': - initexpr = initexpr[1:].lower().replace('d','e').\ - replace(',','+1j*(') - try: - v = eval(initexpr,{},params) - except (SyntaxError,NameError),msg: - errmess('analyzeline: Failed to evaluate %r. Ignoring: %s\n'\ - % (initexpr, msg)) - continue - edecl[k]['='] = repr(v) - if edecl[k].has_key('attrspec'): - edecl[k]['attrspec'].append('parameter') - else: edecl[k]['attrspec']=['parameter'] - last_name = k - groupcache[groupcounter]['vars']=edecl - if last_name is not None: - previous_context = ('variable',last_name,groupcounter) - elif case=='implicit': - if string.lower(string.strip(m.group('after')))=='none': - groupcache[groupcounter]['implicit']=None - elif m.group('after'): - if groupcache[groupcounter].has_key('implicit'): - impl=groupcache[groupcounter]['implicit'] - else: impl={} - if impl is None: - outmess('analyzeline: Overwriting earlier "implicit none" statement.\n') - impl={} - for e in string.split(markoutercomma(m.group('after')),'@,@'): - decl={} - m1=re.match(r'\s*(?P<this>.*?)\s*(\(\s*(?P<after>[a-z-, ]+)\s*\)\s*|)\Z',e,re.I) - if not m1: - outmess('analyzeline: could not extract info of implicit statement part "%s"\n'%(e));continue - m2=typespattern4implicit.match(m1.group('this')) - if not m2: - outmess('analyzeline: could not extract types pattern of implicit statement part "%s"\n'%(e));continue - typespec,selector,attr,edecl=cracktypespec0(m2.group('this'),m2.group('after')) - kindselect,charselect,typename=cracktypespec(typespec,selector) - decl['typespec']=typespec - decl['kindselector']=kindselect - decl['charselector']=charselect - decl['typename']=typename - for k in decl.keys(): - if not decl[k]: del decl[k] - for r in string.split(markoutercomma(m1.group('after')),'@,@'): - if '-' in r: - try: begc,endc=map(string.strip,string.split(r,'-')) - except: - outmess('analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement\n'%r);continue - else: begc=endc=string.strip(r) - if not len(begc)==len(endc)==1: - outmess('analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement (2)\n'%r);continue - for o in range(ord(begc),ord(endc)+1): - impl[chr(o)]=decl - groupcache[groupcounter]['implicit']=impl - elif case=='data': - ll=[] - dl='';il='';f=0;fc=1 - for c in m.group('after'): - if c=="'": fc=not fc - if c=='/' and fc: f=f+1;continue - if f==0: dl=dl+c - elif f==1: il=il+c - elif f==2: - dl = dl.strip() - if dl.startswith(','): - dl = dl[1:].strip() - ll.append([dl,il]) - dl=c;il='';f=0 - if f==2: - dl = dl.strip() - if dl.startswith(','): - dl = dl[1:].strip() - ll.append([dl,il]) - vars={} - if groupcache[groupcounter].has_key('vars'): - vars=groupcache[groupcounter]['vars'] - last_name = None - for l in ll: - l=map(string.strip,l) - if l[0][0]==',':l[0]=l[0][1:] - if l[0][0]=='(': - outmess('analyzeline: implied-DO list "%s" is not supported. Skipping.\n'%l[0]) - continue - #if '(' in l[0]: - # #outmess('analyzeline: ignoring this data statement.\n') - # continue - i=0;j=0;llen=len(l[1]) - for v in rmbadname(map(string.strip,string.split(markoutercomma(l[0]),'@,@'))): - if v[0]=='(': - outmess('analyzeline: implied-DO list "%s" is not supported. Skipping.\n'%v) - # XXX: subsequent init expressions may get wrong values. - # Ignoring since data statements are irrelevant for wrapping. - continue - fc=0 - while (i<llen) and (fc or not l[1][i]==','): - if l[1][i]=="'": fc=not fc - i=i+1 - i=i+1 - #v,l[1][j:i-1]=name,initvalue - if not vars.has_key(v): - vars[v]={} - if vars[v].has_key('=') and not vars[v]['=']==l[1][j:i-1]: - outmess('analyzeline: changing init expression of "%s" ("%s") to "%s"\n'%(v,vars[v]['='],l[1][j:i-1])) - vars[v]['=']=l[1][j:i-1] - j=i - last_name = v - groupcache[groupcounter]['vars']=vars - if last_name is not None: - previous_context = ('variable',last_name,groupcounter) - elif case=='common': - line=string.strip(m.group('after')) - if not line[0]=='/':line='//'+line - cl=[] - f=0;bn='';ol='' - for c in line: - if c=='/':f=f+1;continue - if f>=3: - bn = string.strip(bn) - if not bn: bn='_BLNK_' - cl.append([bn,ol]) - f=f-2;bn='';ol='' - if f%2: bn=bn+c - else: ol=ol+c - bn = string.strip(bn) - if not bn: bn='_BLNK_' - cl.append([bn,ol]) - commonkey={} - if groupcache[groupcounter].has_key('common'): - commonkey=groupcache[groupcounter]['common'] - for c in cl: - if commonkey.has_key(c[0]): - outmess('analyzeline: previously defined common block encountered. Skipping.\n') - continue - commonkey[c[0]]=[] - for i in map(string.strip,string.split(markoutercomma(c[1]),'@,@')): - if i: commonkey[c[0]].append(i) - groupcache[groupcounter]['common']=commonkey - previous_context = ('common',bn,groupcounter) - elif case=='use': - m1=re.match(r'\A\s*(?P<name>\b[\w]+\b)\s*((,(\s*\bonly\b\s*:|(?P<notonly>))\s*(?P<list>.*))|)\s*\Z',m.group('after'),re.I) - if m1: - mm=m1.groupdict() - if not groupcache[groupcounter].has_key('use'): groupcache[groupcounter]['use']={} - name=m1.group('name') - groupcache[groupcounter]['use'][name]={} - isonly=0 - if mm.has_key('list') and mm['list'] is not None: - if mm.has_key('notonly') and mm['notonly'] is None:isonly=1 - groupcache[groupcounter]['use'][name]['only']=isonly - ll=map(string.strip,string.split(mm['list'],',')) - rl={} - for l in ll: - if '=' in l: - m2=re.match(r'\A\s*(?P<local>\b[\w]+\b)\s*=\s*>\s*(?P<use>\b[\w]+\b)\s*\Z',l,re.I) - if m2: rl[string.strip(m2.group('local'))]=string.strip(m2.group('use')) - else: - outmess('analyzeline: Not local=>use pattern found in %s\n'%`l`) - else: - rl[l]=l - groupcache[groupcounter]['use'][name]['map']=rl - else: - pass - - else: - print m.groupdict() - outmess('analyzeline: Could not crack the use statement.\n') - elif case in ['f2pyenhancements']: - if not groupcache[groupcounter].has_key ('f2pyenhancements'): - groupcache[groupcounter]['f2pyenhancements'] = {} - d = groupcache[groupcounter]['f2pyenhancements'] - if m.group('this')=='usercode' and d.has_key('usercode'): - if type(d['usercode']) is type(''): - d['usercode'] = [d['usercode']] - d['usercode'].append(m.group('after')) - else: - d[m.group('this')] = m.group('after') - elif case=='multiline': - if previous_context is None: - if verbose: - outmess('analyzeline: No context for multiline block.\n') - return - gc = groupcounter - #gc = previous_context[2] - appendmultiline(groupcache[gc], - previous_context[:2], - m.group('this')) - else: - if verbose>1: - print m.groupdict() - outmess('analyzeline: No code implemented for line.\n') - -def appendmultiline(group, context_name,ml): - if not group.has_key('f2pymultilines'): - group['f2pymultilines'] = {} - d = group['f2pymultilines'] - if not d.has_key(context_name): - d[context_name] = [] - d[context_name].append(ml) - return - -def cracktypespec0(typespec,ll): - selector=None - attr=None - if re.match(r'double\s*complex',typespec,re.I): typespec='double complex' - elif re.match(r'double\s*precision',typespec,re.I): typespec='double precision' - else: typespec=string.lower(string.strip(typespec)) - m1=selectpattern.match(markouterparen(ll)) - if not m1: - outmess('cracktypespec0: no kind/char_selector pattern found for line.\n') - return - d=m1.groupdict() - for k in d.keys(): d[k]=unmarkouterparen(d[k]) - if typespec in ['complex','integer','logical','real','character','type']: - selector=d['this'] - ll=d['after'] - i=string.find(ll,'::') - if i>=0: - attr=string.strip(ll[:i]) - ll=ll[i+2:] - return typespec,selector,attr,ll -##### -namepattern=re.compile(r'\s*(?P<name>\b[\w]+\b)\s*(?P<after>.*)\s*\Z',re.I) -kindselector=re.compile(r'\s*(\(\s*(kind\s*=)?\s*(?P<kind>.*)\s*\)|[*]\s*(?P<kind2>.*?))\s*\Z',re.I) -charselector=re.compile(r'\s*(\((?P<lenkind>.*)\)|[*]\s*(?P<charlen>.*))\s*\Z',re.I) -lenkindpattern=re.compile(r'\s*(kind\s*=\s*(?P<kind>.*?)\s*(@,@\s*len\s*=\s*(?P<len>.*)|)|(len\s*=\s*|)(?P<len2>.*?)\s*(@,@\s*(kind\s*=\s*|)(?P<kind2>.*)|))\s*\Z',re.I) -lenarraypattern=re.compile(r'\s*(@\(@\s*(?!/)\s*(?P<array>.*?)\s*@\)@\s*[*]\s*(?P<len>.*?)|([*]\s*(?P<len2>.*?)|)\s*(@\(@\s*(?!/)\s*(?P<array2>.*?)\s*@\)@|))\s*(=\s*(?P<init>.*?)|(@\(@|)/\s*(?P<init2>.*?)\s*/(@\)@|)|)\s*\Z',re.I) -def removespaces(expr): - expr=string.strip(expr) - if len(expr)<=1: return expr - expr2=expr[0] - for i in range(1,len(expr)-1): - if expr[i]==' ' and \ - ((expr[i+1] in "()[]{}= ") or (expr[i-1] in "()[]{}= ")): continue - expr2=expr2+expr[i] - expr2=expr2+expr[-1] - return expr2 -def markinnerspaces(line): - l='';f=0 - cc='\'' - cc1='"' - cb='' - for c in line: - if cb=='\\' and c in ['\\','\'','"']: - l=l+c; - cb=c - continue - if f==0 and c in ['\'','"']: cc=c; cc1={'\'':'"','"':'\''}[c] - if c==cc:f=f+1 - elif c==cc:f=f-1 - elif c==' ' and f==1: l=l+'@_@'; continue - l=l+c;cb=c - return l -def updatevars(typespec,selector,attrspec,entitydecl): - global groupcache,groupcounter - last_name = None - kindselect,charselect,typename=cracktypespec(typespec,selector) - if attrspec: - attrspec=map(string.strip,string.split(markoutercomma(attrspec),'@,@')) - l = [] - c = re.compile(r'(?P<start>[a-zA-Z]+)') - for a in attrspec: - m = c.match(a) - if m: - s = string.lower(m.group('start')) - a = s + a[len(s):] - l.append(a) - attrspec = l - el=map(string.strip,string.split(markoutercomma(entitydecl),'@,@')) - el1=[] - for e in el: - for e1 in map(string.strip,string.split(markoutercomma(removespaces(markinnerspaces(e)),comma=' '),'@ @')): - if e1: el1.append(string.replace(e1,'@_@',' ')) - for e in el1: - m=namepattern.match(e) - if not m: - outmess('updatevars: no name pattern found for entity=%s. Skipping.\n'%(`e`)) - continue - ename=rmbadname1(m.group('name')) - edecl={} - if groupcache[groupcounter]['vars'].has_key(ename): - edecl=groupcache[groupcounter]['vars'][ename].copy() - has_typespec = edecl.has_key('typespec') - if not has_typespec: - edecl['typespec']=typespec - elif typespec and (not typespec==edecl['typespec']): - outmess('updatevars: attempt to change the type of "%s" ("%s") to "%s". Ignoring.\n' % (ename,edecl['typespec'],typespec)) - if not edecl.has_key('kindselector'): - edecl['kindselector']=copy.copy(kindselect) - elif kindselect: - for k in kindselect.keys(): - if edecl['kindselector'].has_key(k) and (not kindselect[k]==edecl['kindselector'][k]): - outmess('updatevars: attempt to change the kindselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (k,ename,edecl['kindselector'][k],kindselect[k])) - else: edecl['kindselector'][k]=copy.copy(kindselect[k]) - if not edecl.has_key('charselector') and charselect: - if not has_typespec: - edecl['charselector']=charselect - else: - errmess('updatevars:%s: attempt to change empty charselector to %r. Ignoring.\n' \ - %(ename,charselect)) - elif charselect: - for k in charselect.keys(): - if edecl['charselector'].has_key(k) and (not charselect[k]==edecl['charselector'][k]): - outmess('updatevars: attempt to change the charselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (k,ename,edecl['charselector'][k],charselect[k])) - else: edecl['charselector'][k]=copy.copy(charselect[k]) - if not edecl.has_key('typename'): - edecl['typename']=typename - elif typename and (not edecl['typename']==typename): - outmess('updatevars: attempt to change the typename of "%s" ("%s") to "%s". Ignoring.\n' % (ename,edecl['typename'],typename)) - if not edecl.has_key('attrspec'): - edecl['attrspec']=copy.copy(attrspec) - elif attrspec: - for a in attrspec: - if a not in edecl['attrspec']: - edecl['attrspec'].append(a) - else: - edecl['typespec']=copy.copy(typespec) - edecl['kindselector']=copy.copy(kindselect) - edecl['charselector']=copy.copy(charselect) - edecl['typename']=typename - edecl['attrspec']=copy.copy(attrspec) - if m.group('after'): - m1=lenarraypattern.match(markouterparen(m.group('after'))) - if m1: - d1=m1.groupdict() - for lk in ['len','array','init']: - if d1[lk+'2'] is not None: d1[lk]=d1[lk+'2']; del d1[lk+'2'] - for k in d1.keys(): - if d1[k] is not None: d1[k]=unmarkouterparen(d1[k]) - else: del d1[k] - if d1.has_key('len') and d1.has_key('array'): - if d1['len']=='': - d1['len']=d1['array'] - del d1['array'] - else: - d1['array']=d1['array']+','+d1['len'] - del d1['len'] - errmess('updatevars: "%s %s" is mapped to "%s %s(%s)"\n'%(typespec,e,typespec,ename,d1['array'])) - if d1.has_key('array'): - dm = 'dimension(%s)'%d1['array'] - if not edecl.has_key('attrspec') or (not edecl['attrspec']): - edecl['attrspec']=[dm] - else: - edecl['attrspec'].append(dm) - for dm1 in edecl['attrspec']: - if dm1[:9]=='dimension' and dm1!=dm: - del edecl['attrspec'][-1] - errmess('updatevars:%s: attempt to change %r to %r. Ignoring.\n' \ - % (ename,dm1,dm)) - break - - if d1.has_key('len'): - if typespec in ['complex','integer','logical','real']: - if (not edecl.has_key('kindselector')) or (not edecl['kindselector']): - edecl['kindselector']={} - edecl['kindselector']['*']=d1['len'] - elif typespec == 'character': - if (not edecl.has_key('charselector')) or (not edecl['charselector']): edecl['charselector']={} - if edecl['charselector'].has_key('len'): del edecl['charselector']['len'] - edecl['charselector']['*']=d1['len'] - if d1.has_key('init'): - if edecl.has_key('=') and (not edecl['=']==d1['init']): - outmess('updatevars: attempt to change the init expression of "%s" ("%s") to "%s". Ignoring.\n' % (ename,edecl['='],d1['init'])) - else: - edecl['=']=d1['init'] - else: - outmess('updatevars: could not crack entity declaration "%s". Ignoring.\n'%(ename+m.group('after'))) - for k in edecl.keys(): - if not edecl[k]: del edecl[k] - groupcache[groupcounter]['vars'][ename]=edecl - if groupcache[groupcounter].has_key('varnames'): - groupcache[groupcounter]['varnames'].append(ename) - last_name = ename - return last_name - -def cracktypespec(typespec,selector): - kindselect=None - charselect=None - typename=None - if selector: - if typespec in ['complex','integer','logical','real']: - kindselect=kindselector.match(selector) - if not kindselect: - outmess('cracktypespec: no kindselector pattern found for %s\n'%(`selector`)) - return - kindselect=kindselect.groupdict() - kindselect['*']=kindselect['kind2'] - del kindselect['kind2'] - for k in kindselect.keys(): - if not kindselect[k]: del kindselect[k] - for k,i in kindselect.items(): - kindselect[k] = rmbadname1(i) - elif typespec=='character': - charselect=charselector.match(selector) - if not charselect: - outmess('cracktypespec: no charselector pattern found for %s\n'%(`selector`)) - return - charselect=charselect.groupdict() - charselect['*']=charselect['charlen'] - del charselect['charlen'] - if charselect['lenkind']: - lenkind=lenkindpattern.match(markoutercomma(charselect['lenkind'])) - lenkind=lenkind.groupdict() - for lk in ['len','kind']: - if lenkind[lk+'2']: - lenkind[lk]=lenkind[lk+'2'] - charselect[lk]=lenkind[lk] - del lenkind[lk+'2'] - del charselect['lenkind'] - for k in charselect.keys(): - if not charselect[k]: del charselect[k] - for k,i in charselect.items(): - charselect[k] = rmbadname1(i) - elif typespec=='type': - typename=re.match(r'\s*\(\s*(?P<name>\w+)\s*\)',selector,re.I) - if typename: typename=typename.group('name') - else: outmess('cracktypespec: no typename found in %s\n'%(`typespec+selector`)) - else: - outmess('cracktypespec: no selector used for %s\n'%(`selector`)) - return kindselect,charselect,typename -###### -def setattrspec(decl,attr,force=0): - if not decl: decl={} - if not attr: return decl - if not decl.has_key('attrspec'): - decl['attrspec']=[attr] - return decl - if force: decl['attrspec'].append(attr) - if attr in decl['attrspec']: return decl - if attr=='static' and 'automatic' not in decl['attrspec']: - decl['attrspec'].append(attr) - elif attr=='automatic' and 'static' not in decl['attrspec']: - decl['attrspec'].append(attr) - elif attr=='public' and 'private' not in decl['attrspec']: - decl['attrspec'].append(attr) - elif attr=='private' and 'public' not in decl['attrspec']: - decl['attrspec'].append(attr) - else: - decl['attrspec'].append(attr) - return decl -def setkindselector(decl,sel,force=0): - if not decl: decl={} - if not sel: return decl - if not decl.has_key('kindselector'): - decl['kindselector']=sel - return decl - for k in sel.keys(): - if force or not decl['kindselector'].has_key(k): - decl['kindselector'][k]=sel[k] - return decl -def setcharselector(decl,sel,force=0): - if not decl: decl={} - if not sel: return decl - if not decl.has_key('charselector'): - decl['charselector']=sel - return decl - for k in sel.keys(): - if force or not decl['charselector'].has_key(k): - decl['charselector'][k]=sel[k] - return decl -def getblockname(block,unknown='unknown'): - if block.has_key('name'): return block['name'] - return unknown -###### post processing -def setmesstext(block): - global filepositiontext - try: filepositiontext='In: %s:%s\n'%(block['from'],block['name']) - except: pass - -def get_usedict(block): - usedict = {} - if block.has_key('parent_block'): - usedict = get_usedict(block['parent_block']) - if block.has_key('use'): - usedict.update(block['use']) - return usedict - -def get_useparameters(block, param_map=None): - global f90modulevars - if param_map is None: - param_map = {} - usedict = get_usedict(block) - if not usedict: - return param_map - for usename,mapping in usedict.items(): - usename = string.lower(usename) - if not f90modulevars.has_key(usename): - continue - mvars = f90modulevars[usename] - params = get_parameters(mvars) - if not params: - continue - # XXX: apply mapping - if mapping: - errmess('get_useparameters: mapping for %s not impl.' % (mapping)) - for k,v in params.items(): - if param_map.has_key(k): - outmess('get_useparameters: overriding parameter %s with'\ - ' value from module %s' % (`k`,`usename`)) - param_map[k] = v - return param_map - -def postcrack2(block,tab='',param_map=None): - global f90modulevars - if not f90modulevars: - return block - if type(block)==types.ListType: - ret = [] - for g in block: - g = postcrack2(g,tab=tab+'\t',param_map=param_map) - ret.append(g) - return ret - setmesstext(block) - outmess('%sBlock: %s\n'%(tab,block['name']),0) - - if param_map is None: - param_map = get_useparameters(block) - - if param_map is not None and block.has_key('vars'): - vars = block['vars'] - for n in vars.keys(): - var = vars[n] - if var.has_key('kindselector'): - kind = var['kindselector'] - if kind.has_key('kind'): - val = kind['kind'] - if param_map.has_key(val): - kind['kind'] = param_map[val] - new_body = [] - for b in block['body']: - b = postcrack2(b,tab=tab+'\t',param_map=param_map) - new_body.append(b) - block['body'] = new_body - - return block - -def postcrack(block,args=None,tab=''): - """ - TODO: - function return values - determine expression types if in argument list - """ - global usermodules,onlyfunctions - if type(block)==types.ListType: - gret=[] - uret=[] - for g in block: - setmesstext(g) - g=postcrack(g,tab=tab+'\t') - if g.has_key('name') and string.find(g['name'],'__user__')>=0: # sort user routines to appear first - uret.append(g) - else: - gret.append(g) - return uret+gret - setmesstext(block) - if (not type(block)==types.DictType) and not block.has_key('block'): - raise 'postcrack: Expected block dictionary instead of ',block - if block.has_key('name') and not block['name']=='unknown_interface': - outmess('%sBlock: %s\n'%(tab,block['name']),0) - blocktype=block['block'] - block=analyzeargs(block) - block=analyzecommon(block) - block['vars']=analyzevars(block) - block['sortvars']=sortvarnames(block['vars']) - if block.has_key('args') and block['args']: - args=block['args'] - block['body']=analyzebody(block,args,tab=tab) - - userisdefined=[] -## fromuser = [] - if block.has_key('use'): - useblock=block['use'] - for k in useblock.keys(): - if string.find(k,'__user__')>=0: - userisdefined.append(k) -## if useblock[k].has_key('map'): -## for n in useblock[k]['map'].values(): -## if n not in fromuser: fromuser.append(n) - else: useblock={} - name='' - if block.has_key('name'):name=block['name'] - if block.has_key('externals') and block['externals']:# and not userisdefined: # Build a __user__ module - interfaced=[] - if block.has_key('interfaced'): interfaced=block['interfaced'] - mvars=copy.copy(block['vars']) - if name: mname=name+'__user__routines' - else: mname='unknown__user__routines' - if mname in userisdefined: - i=1 - while '%s_%i'%(mname,i) in userisdefined: i=i+1 - mname='%s_%i'%(mname,i) - interface={'block':'interface','body':[],'vars':{},'name':name+'_user_interface'} - for e in block['externals']: -## if e in fromuser: -## outmess(' Skipping %s that is defined explicitly in another use statement\n'%(`e`)) -## continue - if e in interfaced: - edef=[] - j=-1 - for b in block['body']: - j=j+1 - if b['block']=='interface': - i=-1 - for bb in b['body']: - i=i+1 - if bb.has_key('name') and bb['name']==e: - edef=copy.copy(bb) - del b['body'][i] - break - if edef: - if not b['body']: del block['body'][j] - del interfaced[interfaced.index(e)] - break - interface['body'].append(edef) - else: - if mvars.has_key(e) and not isexternal(mvars[e]): - interface['vars'][e]=mvars[e] - if interface['vars'] or interface['body']: - block['interfaced']=interfaced - mblock={'block':'python module','body':[interface],'vars':{},'name':mname,'interfaced':block['externals']} - useblock[mname]={} - usermodules.append(mblock) - if useblock: - block['use']=useblock - return block - -def sortvarnames(vars): - indep = [] - dep = [] - for v in vars.keys(): - if vars[v].has_key('depend') and vars[v]['depend']: - dep.append(v) - #print '%s depends on %s'%(v,vars[v]['depend']) - else: indep.append(v) - n = len(dep) - i = 0 - while dep: #XXX: How to catch dependence cycles correctly? - v = dep[0] - fl = 0 - for w in dep[1:]: - if w in vars[v]['depend']: - fl = 1 - break - if fl: - dep = dep[1:]+[v] - i = i + 1 - if i>n: - errmess('sortvarnames: failed to compute dependencies because' - ' of cyclic dependencies between ' - +string.join(dep,', ')+'\n') - indep = indep + dep - break - else: - indep.append(v) - dep = dep[1:] - n = len(dep) - i = 0 - #print indep - return indep - -def analyzecommon(block): - if not hascommon(block): return block - commonvars=[] - for k in block['common'].keys(): - comvars=[] - for e in block['common'][k]: - m=re.match(r'\A\s*\b(?P<name>.*?)\b\s*(\((?P<dims>.*?)\)|)\s*\Z',e,re.I) - if m: - dims=[] - if m.group('dims'): - dims=map(string.strip,string.split(markoutercomma(m.group('dims')),'@,@')) - n=string.strip(m.group('name')) - if block['vars'].has_key(n): - if block['vars'][n].has_key('attrspec'): - block['vars'][n]['attrspec'].append('dimension(%s)'%(string.join(dims,','))) - else: - block['vars'][n]['attrspec']=['dimension(%s)'%(string.join(dims,','))] - else: - if dims: - block['vars'][n]={'attrspec':['dimension(%s)'%(string.join(dims,','))]} - else: block['vars'][n]={} - if n not in commonvars: commonvars.append(n) - else: - n=e - errmess('analyzecommon: failed to extract "<name>[(<dims>)]" from "%s" in common /%s/.\n'%(e,k)) - comvars.append(n) - block['common'][k]=comvars - if not block.has_key('commonvars'): - block['commonvars']=commonvars - else: - block['commonvars']=block['commonvars']+commonvars - return block -def analyzebody(block,args,tab=''): - global usermodules,skipfuncs,onlyfuncs,f90modulevars - setmesstext(block) - body=[] - for b in block['body']: - b['parent_block'] = block - if b['block'] in ['function','subroutine']: - if args is not None and b['name'] not in args: - continue - else: - as=b['args'] - if b['name'] in skipfuncs: - continue - if onlyfuncs and b['name'] not in onlyfuncs: - continue - else: as=args - b=postcrack(b,as,tab=tab+'\t') - if b['block']=='interface' and not b['body']: - if not b.has_key('f2pyenhancements'): - continue - if string.replace(b['block'],' ','')=='pythonmodule': - usermodules.append(b) - else: - if b['block']=='module': - f90modulevars[b['name']] = b['vars'] - body.append(b) - return body -def buildimplicitrules(block): - setmesstext(block) - implicitrules=defaultimplicitrules - attrrules={} - if block.has_key('implicit'): - if block['implicit'] is None: - implicitrules=None - if verbose>1: - outmess('buildimplicitrules: no implicit rules for routine %s.\n'%`block['name']`) - else: - for k in block['implicit'].keys(): - if block['implicit'][k].get('typespec') not in ['static','automatic']: - implicitrules[k]=block['implicit'][k] - else: - attrrules[k]=block['implicit'][k]['typespec'] - return implicitrules,attrrules - -def myeval(e,g=None,l=None): - r = eval(e,g,l) - if type(r) in [type(0),type(0.0)]: - return r - raise ValueError,'r=%r' % (r) - -getlincoef_re_1 = re.compile(r'\A\b\w+\b\Z',re.I) -def getlincoef(e,xset): # e = a*x+b ; x in xset - try: - c = int(myeval(e,{},{})) - return 0,c,None - except: pass - if getlincoef_re_1.match(e): - return 1,0,e - len_e = len(e) - for x in xset: - if len(x)>len_e: continue - re_1 = re.compile(r'(?P<before>.*?)\b'+x+r'\b(?P<after>.*)',re.I) - m = re_1.match(e) - if m: - try: - m1 = re_1.match(e) - while m1: - ee = '%s(%s)%s'%(m1.group('before'),0,m1.group('after')) - m1 = re_1.match(ee) - b = myeval(ee,{},{}) - m1 = re_1.match(e) - while m1: - ee = '%s(%s)%s'%(m1.group('before'),1,m1.group('after')) - m1 = re_1.match(ee) - a = myeval(ee,{},{}) - b - m1 = re_1.match(e) - while m1: - ee = '%s(%s)%s'%(m1.group('before'),0.5,m1.group('after')) - m1 = re_1.match(ee) - c = myeval(ee,{},{}) - if (a*0.5+b==c): - return a,b,x - except: pass - break - return None,None,None - -_varname_match = re.compile(r'\A[a-z]\w*\Z').match -def getarrlen(dl,args,star='*'): - edl = [] - try: edl.append(myeval(dl[0],{},{})) - except: edl.append(dl[0]) - try: edl.append(myeval(dl[1],{},{})) - except: edl.append(dl[1]) - if type(edl[0]) is type(0): - p1 = 1-edl[0] - if p1==0: d = str(dl[1]) - elif p1<0: d = '%s-%s'%(dl[1],-p1) - else: d = '%s+%s'%(dl[1],p1) - elif type(edl[1]) is type(0): - p1 = 1+edl[1] - if p1==0: d='-(%s)' % (dl[0]) - else: d='%s-(%s)' % (p1,dl[0]) - else: d = '%s-(%s)+1'%(dl[1],dl[0]) - try: return `myeval(d,{},{})`,None,None - except: pass - d1,d2=getlincoef(dl[0],args),getlincoef(dl[1],args) - if None not in [d1[0],d2[0]]: - if (d1[0],d2[0])==(0,0): - return `d2[1]-d1[1]+1`,None,None - b = d2[1] - d1[1] + 1 - d1 = (d1[0],0,d1[2]) - d2 = (d2[0],b,d2[2]) - if d1[0]==0 and d2[2] in args: - if b<0: return '%s * %s - %s'%(d2[0],d2[2],-b),d2[2],'+%s)/(%s)'%(-b,d2[0]) - elif b: return '%s * %s + %s'%(d2[0],d2[2],b),d2[2],'-%s)/(%s)'%(b,d2[0]) - else: return '%s * %s'%(d2[0],d2[2]),d2[2],')/(%s)'%(d2[0]) - if d2[0]==0 and d1[2] in args: - - if b<0: return '%s * %s - %s'%(-d1[0],d1[2],-b),d1[2],'+%s)/(%s)'%(-b,-d1[0]) - elif b: return '%s * %s + %s'%(-d1[0],d1[2],b),d1[2],'-%s)/(%s)'%(b,-d1[0]) - else: return '%s * %s'%(-d1[0],d1[2]),d1[2],')/(%s)'%(-d1[0]) - if d1[2]==d2[2] and d1[2] in args: - a = d2[0] - d1[0] - if not a: return `b`,None,None - if b<0: return '%s * %s - %s'%(a,d1[2],-b),d2[2],'+%s)/(%s)'%(-b,a) - elif b: return '%s * %s + %s'%(a,d1[2],b),d2[2],'-%s)/(%s)'%(b,a) - else: return '%s * %s'%(a,d1[2]),d2[2],')/(%s)'%(a) - if d1[0]==d2[0]==1: - c = str(d1[2]) - if c not in args: - if _varname_match(c): - outmess('\tgetarrlen:variable "%s" undefined\n' % (c)) - c = '(%s)'%c - if b==0: d='%s-%s' % (d2[2],c) - elif b<0: d='%s-%s-%s' % (d2[2],c,-b) - else: d='%s-%s+%s' % (d2[2],c,b) - elif d1[0]==0: - c2 = str(d2[2]) - if c2 not in args: - if _varname_match(c2): - outmess('\tgetarrlen:variable "%s" undefined\n' % (c2)) - c2 = '(%s)'%c2 - if d2[0]==1: pass - elif d2[0]==-1: c2='-%s' %c2 - else: c2='%s*%s'%(d2[0],c2) - - if b==0: d=c2 - elif b<0: d='%s-%s' % (c2,-b) - else: d='%s+%s' % (c2,b) - elif d2[0]==0: - c1 = str(d1[2]) - if c1 not in args: - if _varname_match(c1): - outmess('\tgetarrlen:variable "%s" undefined\n' % (c1)) - c1 = '(%s)'%c1 - if d1[0]==1: c1='-%s'%c1 - elif d1[0]==-1: c1='+%s'%c1 - elif d1[0]<0: c1='+%s*%s'%(-d1[0],c1) - else: c1 = '-%s*%s' % (d1[0],c1) - - if b==0: d=c1 - elif b<0: d='%s-%s' % (c1,-b) - else: d='%s+%s' % (c1,b) - else: - c1 = str(d1[2]) - if c1 not in args: - if _varname_match(c1): - outmess('\tgetarrlen:variable "%s" undefined\n' % (c1)) - c1 = '(%s)'%c1 - if d1[0]==1: c1='-%s'%c1 - elif d1[0]==-1: c1='+%s'%c1 - elif d1[0]<0: c1='+%s*%s'%(-d1[0],c1) - else: c1 = '-%s*%s' % (d1[0],c1) - - c2 = str(d2[2]) - if c2 not in args: - if _varname_match(c2): - outmess('\tgetarrlen:variable "%s" undefined\n' % (c2)) - c2 = '(%s)'%c2 - if d2[0]==1: pass - elif d2[0]==-1: c2='-%s' %c2 - else: c2='%s*%s'%(d2[0],c2) - - if b==0: d='%s%s' % (c2,c1) - elif b<0: d='%s%s-%s' % (c2,c1,-b) - else: d='%s%s+%s' % (c2,c1,b) - return d,None,None - -word_pattern = re.compile(r'\b[a-z][\w$]*\b',re.I) - -def _get_depend_dict(name, vars, deps): - if vars.has_key(name): - words = vars[name].get('depend',[]) - - if vars[name].has_key('=') and not isstring(vars[name]): - for word in word_pattern.findall(vars[name]['=']): - if word not in words and vars.has_key(word): - words.append(word) - for word in words[:]: - for w in deps.get(word,[]) \ - or _get_depend_dict(word, vars, deps): - if w not in words: - words.append(w) - else: - outmess('_get_depend_dict: no dependence info for %s\n' % (`name`)) - words = [] - deps[name] = words - return words - -def _calc_depend_dict(vars): - names = vars.keys() - depend_dict = {} - for n in names: - _get_depend_dict(n, vars, depend_dict) - return depend_dict - -def get_sorted_names(vars): - """ - """ - depend_dict = _calc_depend_dict(vars) - names = [] - for name in depend_dict.keys(): - if not depend_dict[name]: - names.append(name) - del depend_dict[name] - while depend_dict: - for name, lst in depend_dict.items(): - new_lst = [n for n in lst if depend_dict.has_key(n)] - if not new_lst: - names.append(name) - del depend_dict[name] - else: - depend_dict[name] = new_lst - return [name for name in names if vars.has_key(name)] - -def _kind_func(string): - #XXX: return something sensible. - if string[0] in "'\"": - string = string[1:-1] - if real16pattern.match(string): - return 16 - elif real8pattern.match(string): - return 8 - return 'kind('+string+')' - -def _selected_int_kind_func(r): - #XXX: This should be processor dependent - m = 10**r - if m<=2**8: return 1 - if m<=2**16: return 2 - if m<=2**32: return 4 - if m<=2**64: return 8 - if m<=2**128: return 16 - return -1 - -def get_parameters(vars, global_params={}): - params = copy.copy(global_params) - g_params = copy.copy(global_params) - for name,func in [('kind',_kind_func), - ('selected_int_kind',_selected_int_kind_func), - ]: - if not g_params.has_key(name): - g_params[name] = func - param_names = [] - for n in get_sorted_names(vars): - if vars[n].has_key('attrspec') and 'parameter' in vars[n]['attrspec']: - param_names.append(n) - kind_re = re.compile(r'\bkind\s*\(\s*(?P<value>.*)\s*\)',re.I) - selected_int_kind_re = re.compile(r'\bselected_int_kind\s*\(\s*(?P<value>.*)\s*\)',re.I) - for n in param_names: - if vars[n].has_key('='): - v = vars[n]['='] - if islogical(vars[n]): - v = v.lower() - for repl in [ - ('.false.','False'), - ('.true.','True'), - #TODO: test .eq., .neq., etc replacements. - ]: - v = v.replace(*repl) - v = kind_re.sub(r'kind("\1")',v) - v = selected_int_kind_re.sub(r'selected_int_kind(\1)',v) - if isinteger(vars[n]) and not selected_int_kind_re.match(v): - v = v.split('_')[0] - if isdouble(vars[n]): - tt = list(v) - for m in real16pattern.finditer(v): - tt[m.start():m.end()] = list(\ - v[m.start():m.end()].lower().replace('d', 'e')) - v = string.join(tt,'') - if iscomplex(vars[n]): - if v[0]=='(' and v[-1]==')': - l = markoutercomma(v[1:-1]).split('@,@') - print n,params - try: - params[n] = eval(v,g_params,params) - except Exception,msg: - params[n] = v - #print params - outmess('get_parameters: got "%s" on %s\n' % (msg,`v`)) - if isstring(vars[n]) and type(params[n]) is type(0): - params[n] = chr(params[n]) - nl = string.lower(n) - if nl!=n: - params[nl] = params[n] - else: - print vars[n] - outmess('get_parameters:parameter %s does not have value?!\n'%(`n`)) - return params - -def _eval_length(length,params): - if length in ['(:)','(*)','*']: - return '(*)' - return _eval_scalar(length,params) - -_is_kind_number = re.compile('\d+_').match - -def _eval_scalar(value,params): - if _is_kind_number(value): - value = value.split('_')[0] - try: - value = str(eval(value,{},params)) - except (NameError, SyntaxError): - return value - except Exception,msg: - errmess('"%s" in evaluating %r '\ - '(available names: %s)\n' \ - % (msg,value,params.keys())) - return value - -def analyzevars(block): - global f90modulevars - setmesstext(block) - implicitrules,attrrules=buildimplicitrules(block) - vars=copy.copy(block['vars']) - if block['block']=='function' and not vars.has_key(block['name']): - vars[block['name']]={} - if block['vars'].has_key(''): - del vars[''] - if block['vars'][''].has_key('attrspec'): - gen=block['vars']['']['attrspec'] - for n in vars.keys(): - for k in ['public','private']: - if k in gen: - vars[n]=setattrspec(vars[n],k) - svars=[] - args = block['args'] - for a in args: - try: - vars[a] - svars.append(a) - except KeyError: - pass - for n in vars.keys(): - if n not in args: svars.append(n) - - params = get_parameters(vars, get_useparameters(block)) - - dep_matches = {} - name_match = re.compile(r'\w[\w\d_$]*').match - for v in vars.keys(): - m = name_match(v) - if m: - n = v[m.start():m.end()] - try: - dep_matches[n] - except KeyError: - dep_matches[n] = re.compile(r'.*\b%s\b'%(v),re.I).match - for n in svars: - if n[0] in attrrules.keys(): - vars[n]=setattrspec(vars[n],attrrules[n[0]]) - if not vars[n].has_key('typespec'): - if not(vars[n].has_key('attrspec') and 'external' in vars[n]['attrspec']): - if implicitrules: - ln0 = string.lower(n[0]) - for k in implicitrules[ln0].keys(): - if k=='typespec' and implicitrules[ln0][k]=='undefined': - continue - if not vars[n].has_key(k): - vars[n][k]=implicitrules[ln0][k] - elif k=='attrspec': - for l in implicitrules[ln0][k]: - vars[n]=setattrspec(vars[n],l) - elif n in block['args']: - outmess('analyzevars: typespec of variable %s is not defined in routine %s.\n'%(`n`,block['name'])) - - if vars[n].has_key('charselector'): - if vars[n]['charselector'].has_key('len'): - l = vars[n]['charselector']['len'] - try: - l = str(eval(l,{},params)) - except: - pass - vars[n]['charselector']['len'] = l - - if vars[n].has_key('kindselector'): - if vars[n]['kindselector'].has_key('kind'): - l = vars[n]['kindselector']['kind'] - try: - l = str(eval(l,{},params)) - except: - pass - vars[n]['kindselector']['kind'] = l - - savelindims = {} - if vars[n].has_key('attrspec'): - attr=vars[n]['attrspec'] - attr.reverse() - vars[n]['attrspec']=[] - dim,intent,depend,check,note=None,None,None,None,None - for a in attr: - if a[:9]=='dimension': dim=(string.strip(a[9:]))[1:-1] - elif a[:6]=='intent': intent=(string.strip(a[6:]))[1:-1] - elif a[:6]=='depend': depend=(string.strip(a[6:]))[1:-1] - elif a[:5]=='check': check=(string.strip(a[5:]))[1:-1] - elif a[:4]=='note': note=(string.strip(a[4:]))[1:-1] - else: vars[n]=setattrspec(vars[n],a) - if intent: - if not vars[n].has_key('intent'): vars[n]['intent']=[] - for c in map(string.strip,string.split(markoutercomma(intent),'@,@')): - if not c in vars[n]['intent']: - vars[n]['intent'].append(c) - intent=None - if note: - note=string.replace(note,'\\n\\n','\n\n') - note=string.replace(note,'\\n ','\n') - if not vars[n].has_key('note'): vars[n]['note']=[note] - else: vars[n]['note'].append(note) - note=None - if depend is not None: - if not vars[n].has_key('depend'): vars[n]['depend']=[] - for c in rmbadname(map(string.strip,string.split(markoutercomma(depend),'@,@'))): - if c not in vars[n]['depend']: - vars[n]['depend'].append(c) - depend=None - if check is not None: - if not vars[n].has_key('check'): vars[n]['check']=[] - for c in map(string.strip,string.split(markoutercomma(check),'@,@')): - if not c in vars[n]['check']: - vars[n]['check'].append(c) - check=None - if dim and not vars[n].has_key('dimension'): - vars[n]['dimension']=[] - for d in rmbadname(map(string.strip,string.split(markoutercomma(dim),'@,@'))): - star = '*' - if d==':': star=':' - if params.has_key(d): - d = str(params[d]) - for p in params.keys(): - m = re.match(r'(?P<before>.*?)\b'+p+r'\b(?P<after>.*)',d,re.I) - if m: - #outmess('analyzevars:replacing parameter %s in %s (dimension of %s) with %s\n'%(`p`,`d`,`n`,`params[p]`)) - d = m.group('before')+str(params[p])+m.group('after') - if d==star: - dl = [star] - else: - dl=string.split(markoutercomma(d,':'),'@:@') - if len(dl)==2 and '*' in dl: # e.g. dimension(5:*) - dl = ['*'] - d = '*' - if len(dl)==1 and not dl[0]==star: dl = ['1',dl[0]] - if len(dl)==2: - d,v,di = getarrlen(dl,block['vars'].keys()) - if d[:4] == '1 * ': d = d[4:] - if di and di[-4:] == '/(1)': di = di[:-4] - if v: savelindims[d] = v,di - vars[n]['dimension'].append(d) - if vars[n].has_key('dimension'): - if isintent_c(vars[n]): - shape_macro = 'shape' - else: - shape_macro = 'shape'#'fshape' - if isstringarray(vars[n]): - if vars[n].has_key('charselector'): - d = vars[n]['charselector'] - if d.has_key('*'): - d = d['*'] - errmess('analyzevars: character array "character*%s %s(%s)" is considered as "character %s(%s)"; "intent(c)" is forced.\n'\ - %(d,n, - ','.join(vars[n]['dimension']), - n,','.join(vars[n]['dimension']+[d]))) - vars[n]['dimension'].append(d) - del vars[n]['charselector'] - if not vars[n].has_key('intent'): - vars[n]['intent'] = [] - if 'c' not in vars[n]['intent']: - vars[n]['intent'].append('c') - else: - errmess("analyzevars: charselector=%r unhandled." % (d)) - if not vars[n].has_key('check') and block.has_key('args') and n in block['args']: - flag=not vars[n].has_key('depend') - if flag: vars[n]['depend']=[] - vars[n]['check']=[] - if vars[n].has_key('dimension'): - #/----< no check - #vars[n]['check'].append('rank(%s)==%s'%(n,len(vars[n]['dimension']))) - i=-1; ni=len(vars[n]['dimension']) - for d in vars[n]['dimension']: - ddeps=[] # dependecies of 'd' - ad='' - pd='' - #origd = d - if not vars.has_key(d): - if savelindims.has_key(d): - pd,ad='(',savelindims[d][1] - d = savelindims[d][0] - else: - for r in block['args']: - #for r in block['vars'].keys(): - if not vars.has_key(r): continue - if re.match(r'.*?\b'+r+r'\b',d,re.I): - ddeps.append(r) - if vars.has_key(d): - if vars[d].has_key('attrspec'): - for aa in vars[d]['attrspec']: - if aa[:6]=='depend': - ddeps=ddeps+string.split((string.strip(aa[6:]))[1:-1],',') - if vars[d].has_key('depend'): - ddeps=ddeps+vars[d]['depend'] - i=i+1 - if vars.has_key(d) and (not vars[d].has_key('depend')) \ - and (not vars[d].has_key('=')) and (d not in vars[n]['depend']) \ - and l_or(isintent_in,isintent_inout,isintent_inplace)(vars[n]): - vars[d]['depend']=[n] - if ni>1: - vars[d]['=']='%s%s(%s,%s)%s'% (pd,shape_macro,n,i,ad) - else: - vars[d]['=']='%slen(%s)%s'% (pd,n,ad) - # /---< no check - if 1 and not vars[d].has_key('check'): - if ni>1: - vars[d]['check']=['%s%s(%s,%i)%s==%s'\ - %(pd,shape_macro,n,i,ad,d)] - else: - vars[d]['check']=['%slen(%s)%s>=%s'%(pd,n,ad,d)] - if not vars[d].has_key('attrspec'): vars[d]['attrspec']=['optional'] - if ('optional' not in vars[d]['attrspec']) and\ - ('required' not in vars[d]['attrspec']): - vars[d]['attrspec'].append('optional') - elif d not in ['*',':']: - #/----< no check - #if ni>1: vars[n]['check'].append('shape(%s,%i)==%s'%(n,i,d)) - #else: vars[n]['check'].append('len(%s)>=%s'%(n,d)) - if flag: - if vars.has_key(d): - if n not in ddeps: - vars[n]['depend'].append(d) - else: - vars[n]['depend'] = vars[n]['depend'] + ddeps - elif isstring(vars[n]): - length='1' - if vars[n].has_key('charselector'): - if vars[n]['charselector'].has_key('*'): - length = _eval_length(vars[n]['charselector']['*'], - params) - vars[n]['charselector']['*']=length - elif vars[n]['charselector'].has_key('len'): - length = _eval_length(vars[n]['charselector']['len'], - params) - del vars[n]['charselector']['len'] - vars[n]['charselector']['*']=length - - if not vars[n]['check']: del vars[n]['check'] - if flag and not vars[n]['depend']: del vars[n]['depend'] - if vars[n].has_key('='): - if not vars[n].has_key('attrspec'): vars[n]['attrspec']=[] - if ('optional' not in vars[n]['attrspec']) and \ - ('required' not in vars[n]['attrspec']): - vars[n]['attrspec'].append('optional') - if not vars[n].has_key('depend'): - vars[n]['depend']=[] - for v,m in dep_matches.items(): - if m(vars[n]['=']): vars[n]['depend'].append(v) - if not vars[n]['depend']: del vars[n]['depend'] - if isscalar(vars[n]): - vars[n]['='] = _eval_scalar(vars[n]['='],params) - - for n in vars.keys(): - if n==block['name']: # n is block name - if vars[n].has_key('note'): - block['note']=vars[n]['note'] - if block['block']=='function': - if block.has_key('result') and vars.has_key(block['result']): - vars[n]=appenddecl(vars[n],vars[block['result']]) - if block.has_key('prefix'): - pr=block['prefix']; ispure=0; isrec=1 - pr1=string.replace(pr,'pure','') - ispure=(not pr==pr1) - pr=string.replace(pr1,'recursive','') - isrec=(not pr==pr1) - m=typespattern[0].match(pr) - if m: - typespec,selector,attr,edecl=cracktypespec0(m.group('this'),m.group('after')) - kindselect,charselect,typename=cracktypespec(typespec,selector) - vars[n]['typespec']=typespec - if kindselect: - if kindselect.has_key('kind'): - try: - kindselect['kind'] = eval(kindselect['kind'],{},params) - except: - pass - vars[n]['kindselector']=kindselect - if charselect: vars[n]['charselector']=charselect - if typename: vars[n]['typename']=typename - if ispure: vars[n]=setattrspec(vars[n],'pure') - if isrec: vars[n]=setattrspec(vars[n],'recursive') - else: - outmess('analyzevars: prefix (%s) were not used\n'%`block['prefix']`) - if not block['block'] in ['module','pythonmodule','python module','block data']: - if block.has_key('commonvars'): - neededvars=copy.copy(block['args']+block['commonvars']) - else: - neededvars=copy.copy(block['args']) - for n in vars.keys(): - if l_or(isintent_callback,isintent_aux)(vars[n]): - neededvars.append(n) - if block.has_key('entry'): - neededvars.extend(block['entry'].keys()) - for k in block['entry'].keys(): - for n in block['entry'][k]: - if n not in neededvars: - neededvars.append(n) - if block['block']=='function': - if block.has_key('result'): - neededvars.append(block['result']) - else: - neededvars.append(block['name']) - if block['block'] in ['subroutine','function']: - name = block['name'] - if vars.has_key(name) and vars[name].has_key('intent'): - block['intent'] = vars[name]['intent'] - if block['block'] == 'type': - neededvars.extend(vars.keys()) - for n in vars.keys(): - if n not in neededvars: - del vars[n] - return vars -analyzeargs_re_1 = re.compile(r'\A[a-z]+[\w$]*\Z',re.I) -def analyzeargs(block): - setmesstext(block) - implicitrules,attrrules=buildimplicitrules(block) - if not block.has_key('args'): block['args']=[] - args=[] - re_1 = analyzeargs_re_1 - for a in block['args']: - if not re_1.match(a): # `a` is an expression - at=determineexprtype(a,block['vars'],implicitrules) - na='e_' - for c in a: - if c not in string.lowercase+string.digits: c='_' - na=na+c - if na[-1]=='_': na=na+'e' - else: na=na+'_e' - a=na - while block['vars'].has_key(a) or a in block['args']: a=a+'r' - block['vars'][a]=at - args.append(a) - if not block['vars'].has_key(a): - block['vars'][a]={} - if block.has_key('externals') and a in block['externals']+block['interfaced']: - block['vars'][a]=setattrspec(block['vars'][a],'external') - block['args']=args - - if block.has_key('entry'): - for k,args1 in block['entry'].items(): - for a in args1: - if not block['vars'].has_key(a): - block['vars'][a]={} - - for b in block['body']: - if b['name'] in args: - if not block.has_key('externals'): block['externals']=[] - if b['name'] not in block['externals']: - block['externals'].append(b['name']) - if block.has_key('result') and not block['vars'].has_key(block['result']): - block['vars'][block['result']]={} - return block -determineexprtype_re_1 = re.compile(r'\A\(.+?[,].+?\)\Z',re.I) -determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(P<name>[\w]+)|)\Z',re.I) -determineexprtype_re_3 = re.compile(r'\A[+-]?[\d.]+[\d+-de.]*(_(P<name>[\w]+)|)\Z',re.I) -determineexprtype_re_4 = re.compile(r'\A\(.*\)\Z',re.I) -determineexprtype_re_5 = re.compile(r'\A(?P<name>\w+)\s*\(.*?\)\s*\Z',re.I) -def _ensure_exprdict(r): - if type(r) is type(0): - return {'typespec':'integer'} - if type(r) is type(0.0): - return {'typespec':'real'} - if type(r) is type(0j): - return {'typespec':'complex'} - assert type(r) is type({}),`r` - return r - -def determineexprtype(expr,vars,rules={}): - if vars.has_key(expr): - return _ensure_exprdict(vars[expr]) - expr=string.strip(expr) - if determineexprtype_re_1.match(expr): - return {'typespec':'complex'} - m=determineexprtype_re_2.match(expr) - if m: - if m.groupdict().has_key('name') and m.group('name'): - outmess('determineexprtype: selected kind types not supported (%s)\n'%`expr`) - return {'typespec':'integer'} - m = determineexprtype_re_3.match(expr) - if m: - if m.groupdict().has_key('name') and m.group('name'): - outmess('determineexprtype: selected kind types not supported (%s)\n'%`expr`) - return {'typespec':'real'} - for op in ['+','-','*','/']: - for e in map(string.strip,string.split(markoutercomma(expr,comma=op),'@'+op+'@')): - if vars.has_key(e): - return _ensure_exprdict(vars[e]) - t={} - if determineexprtype_re_4.match(expr): # in parenthesis - t=determineexprtype(expr[1:-1],vars,rules) - else: - m = determineexprtype_re_5.match(expr) - if m: - rn=m.group('name') - t=determineexprtype(m.group('name'),vars,rules) - if t and t.has_key('attrspec'): del t['attrspec'] - if not t: - if rules.has_key(rn[0]): - return _ensure_exprdict(rules[rn[0]]) - if expr[0] in '\'"': - return {'typespec':'character','charselector':{'*':'*'}} - if not t: - outmess('determineexprtype: could not determine expressions (%s) type.\n'%(`expr`)) - return t -###### -def crack2fortrangen(block,tab='\n'): - global skipfuncs, onlyfuncs - setmesstext(block) - ret='' - if type(block) is type([]): - for g in block: - if g['block'] in ['function','subroutine']: - if g['name'] in skipfuncs: - continue - if onlyfuncs and g['name'] not in onlyfuncs: - continue - ret=ret+crack2fortrangen(g,tab) - return ret - prefix='' - name='' - args='' - blocktype=block['block'] - if blocktype=='program': return '' - al=[] - if block.has_key('name'): name=block['name'] - if block.has_key('args'): - vars = block['vars'] - al = [a for a in block['args'] if not isintent_callback(vars[a])] - if block['block']=='function' or al: - args='(%s)'%string.join(al,',') - f2pyenhancements = '' - if block.has_key('f2pyenhancements'): - for k in block['f2pyenhancements'].keys(): - f2pyenhancements = '%s%s%s %s'%(f2pyenhancements,tab+tabchar,k,block['f2pyenhancements'][k]) - intent_lst = block.get('intent',[])[:] - if blocktype=='function' and 'callback' in intent_lst: - intent_lst.remove('callback') - if intent_lst: - f2pyenhancements = '%s%sintent(%s) %s'%\ - (f2pyenhancements,tab+tabchar, - string.join(intent_lst,','),name) - use='' - if block.has_key('use'): - use=use2fortran(block['use'],tab+tabchar) - common='' - if block.has_key('common'): - common=common2fortran(block['common'],tab+tabchar) - if name=='unknown_interface': name='' - result='' - if block.has_key('result'): - result=' result (%s)'%block['result'] - if block['result'] not in al: - al.append(block['result']) - #if block.has_key('prefix'): prefix=block['prefix']+' ' - body=crack2fortrangen(block['body'],tab+tabchar) - vars=vars2fortran(block,block['vars'],al,tab+tabchar) - mess='' - if block.has_key('from'): - mess='! in %s'%block['from'] - if block.has_key('entry'): - entry_stmts = '' - for k,i in block['entry'].items(): - entry_stmts = '%s%sentry %s(%s)' \ - % (entry_stmts,tab+tabchar,k,string.join(i,',')) - body = body + entry_stmts - if blocktype=='block data' and name=='_BLOCK_DATA_': - name = '' - ret='%s%s%s %s%s%s %s%s%s%s%s%s%send %s %s'%(tab,prefix,blocktype,name,args,result,mess,f2pyenhancements,use,vars,common,body,tab,blocktype,name) - return ret -def common2fortran(common,tab=''): - ret='' - for k in common.keys(): - if k=='_BLNK_': - ret='%s%scommon %s'%(ret,tab,string.join(common[k],',')) - else: - ret='%s%scommon /%s/ %s'%(ret,tab,k,string.join(common[k],',')) - return ret -def use2fortran(use,tab=''): - ret='' - for m in use.keys(): - ret='%s%suse %s,'%(ret,tab,m) - if use[m]=={}: - if ret and ret[-1]==',': ret=ret[:-1] - continue - if use[m].has_key('only') and use[m]['only']: - ret='%s,only:'%(ret) - if use[m].has_key('map') and use[m]['map']: - c=' ' - for k in use[m]['map'].keys(): - if k==use[m]['map'][k]: - ret='%s%s%s'%(ret,c,k); c=',' - else: - ret='%s%s%s=>%s'%(ret,c,k,use[m]['map'][k]); c=',' - if ret and ret[-1]==',': ret=ret[:-1] - return ret -def true_intent_list(var): - lst = var['intent'] - ret = [] - for intent in lst: - try: - exec('c = isintent_%s(var)' % intent) - except NameError: - c = 0 - if c: - ret.append(intent) - return ret -def vars2fortran(block,vars,args,tab=''): - """ - TODO: - public sub - ... - """ - setmesstext(block) - ret='' - nout=[] - for a in args: - if block['vars'].has_key(a): nout.append(a) - if block.has_key('commonvars'): - for a in block['commonvars']: - if vars.has_key(a): - if a not in nout: nout.append(a) - else: errmess('vars2fortran: Confused?!: "%s" is not defined in vars.\n'%a) - if block.has_key('varnames'): - nout.extend(block['varnames']) - for a in vars.keys(): - if a not in nout: nout.append(a) - for a in nout: - if vars[a].has_key('depend'): - for d in vars[a]['depend']: - if vars.has_key(d) and vars[d].has_key('depend') and a in vars[d]['depend']: - errmess('vars2fortran: Warning: cross-dependence between variables "%s" and "%s"\n'%(a,d)) - if block.has_key('externals') and a in block['externals']: - if isintent_callback(vars[a]): - ret='%s%sintent(callback) %s'%(ret,tab,a) - ret='%s%sexternal %s'%(ret,tab,a) - if isoptional(vars[a]): - ret='%s%soptional %s'%(ret,tab,a) - if vars.has_key(a) and not vars[a].has_key('typespec'): - continue - cont=1 - for b in block['body']: - if a==b['name'] and b['block']=='function': cont=0;break - if cont: continue - if not vars.has_key(a): - show(vars) - outmess('vars2fortran: No definition for argument "%s".\n'%a) - continue - if a==block['name'] and not block['block']=='function': - continue - if not vars[a].has_key('typespec'): - if vars[a].has_key('attrspec') and 'external' in vars[a]['attrspec']: - if a in args: - ret='%s%sexternal %s'%(ret,tab,a) - continue - show(vars[a]) - outmess('vars2fortran: No typespec for argument "%s".\n'%a) - continue - vardef=vars[a]['typespec'] - if vardef=='type' and vars[a].has_key('typename'): - vardef='%s(%s)'%(vardef,vars[a]['typename']) - selector={} - if vars[a].has_key('kindselector'): selector=vars[a]['kindselector'] - elif vars[a].has_key('charselector'): selector=vars[a]['charselector'] - if selector.has_key('*'): - if selector['*'] in ['*',':']: - vardef='%s*(%s)'%(vardef,selector['*']) - else: - vardef='%s*%s'%(vardef,selector['*']) - else: - if selector.has_key('len'): - vardef='%s(len=%s'%(vardef,selector['len']) - if selector.has_key('kind'): - vardef='%s,kind=%s)'%(vardef,selector['kind']) - else: - vardef='%s)'%(vardef) - elif selector.has_key('kind'): - vardef='%s(kind=%s)'%(vardef,selector['kind']) - c=' ' - if vars[a].has_key('attrspec'): - attr=[] - for l in vars[a]['attrspec']: - if l not in ['external']: - attr.append(l) - if attr: - vardef='%s %s'%(vardef,string.join(attr,',')) - c=',' - if vars[a].has_key('dimension'): -# if not isintent_c(vars[a]): -# vars[a]['dimension'].reverse() - vardef='%s%sdimension(%s)'%(vardef,c,string.join(vars[a]['dimension'],',')) - c=',' - if vars[a].has_key('intent'): - lst = true_intent_list(vars[a]) - if lst: - vardef='%s%sintent(%s)'%(vardef,c,string.join(lst,',')) - c=',' - if vars[a].has_key('check'): - vardef='%s%scheck(%s)'%(vardef,c,string.join(vars[a]['check'],',')) - c=',' - if vars[a].has_key('depend'): - vardef='%s%sdepend(%s)'%(vardef,c,string.join(vars[a]['depend'],',')) - c=',' - if vars[a].has_key('='): - v = vars[a]['='] - if vars[a]['typespec'] in ['complex','double complex']: - try: - v = eval(v) - v = '(%s,%s)' % (v.real,v.imag) - except: - pass - vardef='%s :: %s=%s'%(vardef,a,v) - else: - vardef='%s :: %s'%(vardef,a) - ret='%s%s%s'%(ret,tab,vardef) - return ret -###### - -def crackfortran(files): - global usermodules - outmess('Reading fortran codes...\n',0) - readfortrancode(files,crackline) - outmess('Post-processing...\n',0) - usermodules=[] - postlist=postcrack(grouplist[0]) - outmess('Post-processing (stage 2)...\n',0) - postlist=postcrack2(postlist) - return usermodules+postlist -def crack2fortran(block): - global f2py_version - pyf=crack2fortrangen(block)+'\n' - header="""! -*- f90 -*- -! Note: the context of this file is case sensitive. -""" - footer=""" -! This file was auto-generated with f2py (version:%s). -! See http://cens.ioc.ee/projects/f2py2e/ -"""%(f2py_version) - return header+pyf+footer - -if __name__ == "__main__": - files=[] - funcs=[] - f=1;f2=0;f3=0 - showblocklist=0 - for l in sys.argv[1:]: - if l=='': pass - elif l[0]==':': - f=0 - elif l=='-quiet': - quiet=1 - verbose=0 - elif l=='-verbose': - verbose=2 - quiet=0 - elif l=='-fix': - if strictf77: - outmess('Use option -f90 before -fix if Fortran 90 code is in fix form.\n',0) - skipemptyends=1 - sourcecodeform='fix' - elif l=='-skipemptyends': - skipemptyends=1 - elif l=='--ignore-contains': - ignorecontains=1 - elif l=='-f77': - strictf77=1 - sourcecodeform='fix' - elif l=='-f90': - strictf77=0 - sourcecodeform='free' - skipemptyends=1 - elif l=='-h': - f2=1 - elif l=='-show': - showblocklist=1 - elif l=='-m': - f3=1 - elif l[0]=='-': - errmess('Unknown option %s\n'%`l`) - elif f2: - f2=0 - pyffilename=l - elif f3: - f3=0 - f77modulename=l - elif f: - try: - open(l).close() - files.append(l) - except IOError,detail: - errmess('IOError: %s\n'%str(detail)) - else: - funcs.append(l) - if not strictf77 and f77modulename and not skipemptyends: - outmess("""\ - Warning: You have specifyied module name for non Fortran 77 code - that should not need one (expect if you are scanning F90 code - for non module blocks but then you should use flag -skipemptyends - and also be sure that the files do not contain programs without program statement). -""",0) - - postlist=crackfortran(files,funcs) - if pyffilename: - outmess('Writing fortran code to file %s\n'%`pyffilename`,0) - pyf=crack2fortran(postlist) - f=open(pyffilename,'w') - f.write(pyf) - f.close() - if showblocklist: - show(postlist) diff --git a/numpy/f2py/diagnose.py b/numpy/f2py/diagnose.py deleted file mode 100644 index c270c597c..000000000 --- a/numpy/f2py/diagnose.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python - -import os,sys,tempfile - -def run_command(cmd): - print 'Running %r:' % (cmd) - s = os.system(cmd) - print '------' -def run(): - _path = os.getcwd() - os.chdir(tempfile.gettempdir()) - print '------' - print 'os.name=%r' % (os.name) - print '------' - print 'sys.platform=%r' % (sys.platform) - print '------' - print 'sys.version:' - print sys.version - print '------' - print 'sys.prefix:' - print sys.prefix - print '------' - print 'sys.path=%r' % (':'.join(sys.path)) - print '------' - try: - import Numeric - has_Numeric = 1 - except ImportError: - print 'Failed to import Numeric:',sys.exc_value - has_Numeric = 0 - try: - import numarray - has_numarray = 1 - except ImportError: - print 'Failed to import numarray:',sys.exc_value - has_numarray = 0 - try: - import numpy - has_newnumpy = 1 - except ImportError: - print 'Failed to import new numpy:', sys.exc_value - has_newnumpy = 0 - try: - import f2py2e - has_f2py2e = 1 - except ImportError: - print 'Failed to import f2py2e:',sys.exc_value - has_f2py2e = 0 - try: - import numpy.distutils - has_numpy_distutils = 2 - except ImportError: - try: - import numpy_distutils - has_numpy_distutils = 1 - except ImportError: - print 'Failed to import numpy_distutils:',sys.exc_value - has_numpy_distutils = 0 - if has_Numeric: - try: - print 'Found Numeric version %r in %s' % \ - (Numeric.__version__,Numeric.__file__) - except Exception,msg: - print 'error:',msg - print '------' - if has_numarray: - try: - print 'Found numarray version %r in %s' % \ - (numarray.__version__,numarray.__file__) - except Exception,msg: - print 'error:',msg - print '------' - if has_newnumpy: - try: - print 'Found new numpy version %r in %s' % \ - (numpy.__version__, numpy.__file__) - except Exception,msg: - print 'error:', msg - print '------' - if has_f2py2e: - try: - print 'Found f2py2e version %r in %s' % \ - (f2py2e.__version__.version,f2py2e.__file__) - except Exception,msg: - print 'error:',msg - print '------' - if has_numpy_distutils: - try: - if has_numpy_distutils==2: - print 'Found numpy.distutils version %r in %r' % (\ - numpy.distutils.__version__, - numpy.distutils.__file__) - else: - print 'Found numpy_distutils version %r in %r' % (\ - numpy_distutils.numpy_distutils_version.numpy_distutils_version, - numpy_distutils.__file__) - print '------' - except Exception,msg: - print 'error:',msg - print '------' - try: - if has_numpy_distutils==1: - print 'Importing numpy_distutils.command.build_flib ...', - import numpy_distutils.command.build_flib as build_flib - print 'ok' - print '------' - try: - print 'Checking availability of supported Fortran compilers:' - for compiler_class in build_flib.all_compilers: - compiler_class(verbose=1).is_available() - print '------' - except Exception,msg: - print 'error:',msg - print '------' - except Exception,msg: - print 'error:',msg,'(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)' - print '------' - try: - if has_numpy_distutils==2: - print 'Importing numpy.distutils.fcompiler ...', - import numpy.distutils.fcompiler as fcompiler - else: - print 'Importing numpy_distutils.fcompiler ...', - import numpy_distutils.fcompiler as fcompiler - print 'ok' - print '------' - try: - print 'Checking availability of supported Fortran compilers:' - fcompiler.show_fcompilers() - print '------' - except Exception,msg: - print 'error:',msg - print '------' - except Exception,msg: - print 'error:',msg - print '------' - try: - if has_numpy_distutils==2: - print 'Importing numpy.distutils.cpuinfo ...', - from numpy.distutils.cpuinfo import cpuinfo - print 'ok' - print '------' - else: - try: - print 'Importing numpy_distutils.command.cpuinfo ...', - from numpy_distutils.command.cpuinfo import cpuinfo - print 'ok' - print '------' - except Exception,msg: - print 'error:',msg,'(ignore it)' - print 'Importing numpy_distutils.cpuinfo ...', - from numpy_distutils.cpuinfo import cpuinfo - print 'ok' - print '------' - cpu = cpuinfo() - print 'CPU information:', - for name in dir(cpuinfo): - if name[0]=='_' and name[1]!='_' and getattr(cpu,name[1:])(): - print name[1:], - print '------' - except Exception,msg: - print 'error:',msg - print '------' - os.chdir(_path) -if __name__ == "__main__": - run() diff --git a/numpy/f2py/doc/Makefile b/numpy/f2py/doc/Makefile deleted file mode 100644 index 2f241da0a..000000000 --- a/numpy/f2py/doc/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -# Makefile for compiling f2py2e documentation (dvi, ps, html) -# Pearu Peterson <pearu@ioc.ee> - -REL=4 -TOP = usersguide -LATEXSRC = bugs.tex commands.tex f2py2e.tex intro.tex notes.tex signaturefile.tex -MAINLATEX = f2py2e - -LATEX = latex -PDFLATEX = pdflatex - -COLLECTINPUT = ./collectinput.py -INSTALLDATA = install -m 644 -c - -TTH = tth -TTHFILTER = sed -e "s/{{}\\\verb@/\\\texttt{/g" | sed -e "s/@{}}/}/g" | $(TTH) -L$(MAINLATEX) -i -TTHFILTER2 = sed -e "s/{{}\\\verb@/\\\texttt{/g" | sed -e "s/@{}}/}/g" | $(TTH) -Lpython9 -i -TTHFILTER3 = sed -e "s/{{}\\\verb@/\\\texttt{/g" | sed -e "s/@{}}/}/g" | $(TTH) -Lfortranobject -i -TTHMISSING = "\ -***************************************************************\n\ -Warning: Could not find tth (a TeX to HTML translator) \n\ - or an error arised was by tth\n\ -You can download tth from http://hutchinson.belmont.ma.us/tth/ \n\ -or\n\ -use your favorite LaTeX to HTML translator on file tmp_main.tex\n\ -***************************************************************\ -" - -all: dvi ps html clean -$(MAINLATEX).dvi: $(LATEXSRC) - $(LATEX) $(MAINLATEX).tex - $(LATEX) $(MAINLATEX).tex - $(LATEX) $(MAINLATEX).tex - $(PDFLATEX) $(MAINLATEX).tex -$(TOP).dvi: $(MAINLATEX).dvi - cp -f $(MAINLATEX).dvi $(TOP).dvi - mv -f $(MAINLATEX).pdf $(TOP).pdf -$(TOP).ps: $(TOP).dvi - dvips $(TOP).dvi -o -$(TOP).html: $(LATEXSRC) - $(COLLECTINPUT) < $(MAINLATEX).tex > tmp_$(MAINLATEX).tex - @test `which $(TTH)` && cat tmp_$(MAINLATEX).tex | $(TTHFILTER) > $(TOP).html\ - || echo -e $(TTHMISSING) -dvi: $(TOP).dvi -ps: $(TOP).ps - gzip -f $(TOP).ps -html: $(TOP).html - -python9: - cp -f python9.tex f2python9-final/src/ - cd f2python9-final && mk_html.sh - cd f2python9-final && mk_ps.sh - cd f2python9-final && mk_pdf.sh -pyfobj: - $(LATEX) fortranobject.tex - $(LATEX) fortranobject.tex - $(LATEX) fortranobject.tex - @test `which $(TTH)` && cat fortranobject.tex | $(TTHFILTER3) > pyfobj.html\ - || echo -e $(TTHMISSING) - dvips fortranobject.dvi -o pyfobj.ps - gzip -f pyfobj.ps - pdflatex fortranobject.tex - mv fortranobject.pdf pyfobj.pdf - -WWWDIR=/net/cens/home/www/unsecure/projects/f2py2e/ -wwwpage: all - $(INSTALLDATA) index.html $(TOP).html $(TOP).ps.gz $(TOP).dvi $(TOP).pdf \ - Release-$(REL).x.txt ../NEWS.txt win32_notes.txt $(WWWDIR) - $(INSTALLDATA) pyfobj.{ps.gz,pdf,html} $(WWWDIR) - $(INSTALLDATA) f2python9-final/f2python9.{ps.gz,pdf,html} f2python9-final/{flow,structure,aerostructure}.jpg $(WWWDIR) -clean: - rm -f tmp_$(MAINLATEX).* $(MAINLATEX).{aux,dvi,log,toc} -distclean: - rm -f tmp_$(MAINLATEX).* $(MAINLATEX).{aux,dvi,log,toc} - rm -f $(TOP).{ps,dvi,html,pdf,ps.gz} - rm -f *~ diff --git a/numpy/f2py/doc/Release-1.x.txt b/numpy/f2py/doc/Release-1.x.txt deleted file mode 100644 index 46d6fbf09..000000000 --- a/numpy/f2py/doc/Release-1.x.txt +++ /dev/null @@ -1,27 +0,0 @@ - -I am pleased to announce the first public release of f2py 1.116: - -Writing Python C/API wrappers for Fortran routines can be a very -tedious task, especially if a Fortran routine takes more than 20 -arguments but only few of them are relevant for the problems that they -solve. - -The Fortran to Python Interface Generator, or FPIG for short, is a -command line tool (f2py) for generating Python C/API modules for -wrapping Fortran 77 routines, accessing common blocks from Python, and -calling Python functions from Fortran (call-backs). - -The tool can be downloaded from - - http://cens.ioc.ee/projects/f2py2e/ - -where you can find also information about f2py features and its User's -Guide. - -f2py is released under the LGPL license. - -With regards, - Pearu Peterson <pearu@ioc.ee> - -<P><A HREF="http://cens.ioc.ee/projects/f2py2e/">f2py 1.116</A> - The -Fortran to Python Interface Generator (25-Jan-00) diff --git a/numpy/f2py/doc/Release-2.x.txt b/numpy/f2py/doc/Release-2.x.txt deleted file mode 100644 index 807eb0ca8..000000000 --- a/numpy/f2py/doc/Release-2.x.txt +++ /dev/null @@ -1,77 +0,0 @@ - -FPIG - Fortran to Python Interface Generator - -I am pleased to announce the second public release of f2py -(version 2.264): - - http://cens.ioc.ee/projects/f2py2e/ - -f2py is a command line tool for binding Python and Fortran codes. It -scans Fortran 77/90/95 codes and generates a Python C/API module that -makes it possible to call Fortran routines from Python. No Fortran or -C expertise is required for using this tool. - -Features include: - - *** All basic Fortran types are supported: - integer[ | *1 | *2 | *4 | *8 ], logical[ | *1 | *2 | *4 | *8 ], - character[ | *(*) | *1 | *2 | *3 | ... ] - real[ | *4 | *8 | *16 ], double precision, - complex[ | *8 | *16 | *32 ] - - *** Multi-dimensional arrays of (almost) all basic types. - Dimension specifications: - <dim> | <start>:<end> | * | : - - *** Supported attributes: - intent([ in | inout | out | hide | in,out | inout,out ]) - dimension(<dimspec>) - depend([<names>]) - check([<C-booleanexpr>]) - note(<LaTeX text>) - optional, required, external - - *** Calling Fortran 77/90/95 subroutines and functions. Also - Fortran 90/95 module routines. Internal initialization of - optional arguments. - - *** Accessing COMMON blocks from Python. Accessing Fortran 90/95 - module data coming soon. - - *** Call-back functions: calling Python functions from Fortran with - very flexible hooks. - - *** In Python, arguments of the interfaced functions may be of - different type - necessary type conversations are done - internally in C level. - - *** Automatically generates documentation (__doc__,LaTeX) for - interface functions. - - *** Automatically generates signature files --- user has full - control over the interface constructions. Automatically - detects the signatures of call-back functions, solves argument - dependencies, etc. - - *** Automatically generates Makefile for compiling Fortran and C - codes and linking them to a shared module. Many compilers are - supported: gcc, Compaq Fortran, VAST/f90 Fortran, Absoft - F77/F90, MIPSpro 7 Compilers, etc. Platforms: Intel/Alpha - Linux, HP-UX, IRIX64. - - *** Complete User's Guide in various formats (html,ps,pdf,dvi). - - *** f2py users list is available for support, feedback, etc. - -More information about f2py, see - - http://cens.ioc.ee/projects/f2py2e/ - -f2py is released under the LGPL license. - -Sincerely, - Pearu Peterson <pearu@ioc.ee> - September 12, 2000 - -<P><A HREF="http://cens.ioc.ee/projects/f2py2e/">f2py 2.264</A> - The -Fortran to Python Interface Generator (12-Sep-00) diff --git a/numpy/f2py/doc/Release-3.x.txt b/numpy/f2py/doc/Release-3.x.txt deleted file mode 100644 index 940771015..000000000 --- a/numpy/f2py/doc/Release-3.x.txt +++ /dev/null @@ -1,87 +0,0 @@ - -F2PY - Fortran to Python Interface Generator - -I am pleased to announce the third public release of f2py -(version 2.3.321): - - http://cens.ioc.ee/projects/f2py2e/ - -f2py is a command line tool for binding Python and Fortran codes. It -scans Fortran 77/90/95 codes and generates a Python C/API module that -makes it possible to call Fortran subroutines from Python. No Fortran or -C expertise is required for using this tool. - -Features include: - - *** All basic Fortran types are supported: - integer[ | *1 | *2 | *4 | *8 ], logical[ | *1 | *2 | *4 | *8 ], - character[ | *(*) | *1 | *2 | *3 | ... ] - real[ | *4 | *8 | *16 ], double precision, - complex[ | *8 | *16 | *32 ] - - *** Multi-dimensional arrays of (almost) all basic types. - Dimension specifications: - <dim> | <start>:<end> | * | : - - *** Supported attributes and statements: - intent([ in | inout | out | hide | in,out | inout,out ]) - dimension(<dimspec>) - depend([<names>]) - check([<C-booleanexpr>]) - note(<LaTeX text>) - optional, required, external -NEW: intent(c), threadsafe, fortranname - - *** Calling Fortran 77/90/95 subroutines and functions. Also - Fortran 90/95 module subroutines are supported. Internal - initialization of optional arguments. - - *** Accessing COMMON blocks from Python. -NEW: Accessing Fortran 90/95 module data. - - *** Call-back functions: calling Python functions from Fortran with - very flexible hooks. - - *** In Python, arguments of the interfaced functions may be of - different type - necessary type conversations are done - internally in C level. - - *** Automatically generates documentation (__doc__,LaTeX) for - interfaced functions. - - *** Automatically generates signature files --- user has full - control over the interface constructions. Automatically - detects the signatures of call-back functions, solves argument - dependencies, etc. - -NEW: * Automatically generates setup_<modulename>.py for building - extension modules using tools from distutils and - fortran_support module (SciPy). - - *** Automatically generates Makefile for compiling Fortran and C - codes and linking them to a shared module. Many compilers are - supported: gcc, Compaq Fortran, VAST/f90 Fortran, Absoft - F77/F90, MIPSpro 7 Compilers, etc. Platforms: Intel/Alpha - Linux, HP-UX, IRIX64. - - *** Complete User's Guide in various formats (html,ps,pdf,dvi). - - *** f2py users list is available for support, feedback, etc. - -NEW: * Installation with distutils. - - *** And finally, many bugs are fixed. - -More information about f2py, see - - http://cens.ioc.ee/projects/f2py2e/ - -LICENSE: - f2py is released under the LGPL. - -Sincerely, - Pearu Peterson <pearu@cens.ioc.ee> - December 4, 2001 - -<P><A HREF="http://cens.ioc.ee/projects/f2py2e/">f2py 2.3.321</A> - The -Fortran to Python Interface Generator (04-Dec-01) diff --git a/numpy/f2py/doc/Release-4.x.txt b/numpy/f2py/doc/Release-4.x.txt deleted file mode 100644 index ed071a0cb..000000000 --- a/numpy/f2py/doc/Release-4.x.txt +++ /dev/null @@ -1,91 +0,0 @@ - -F2PY - Fortran to Python Interface Generator - -I am pleased to announce the fourth public release of f2py -(version 2.4.366): - - http://cens.ioc.ee/projects/f2py2e/ - -f2py is a command line tool for binding Python and Fortran codes. It -scans Fortran 77/90/95 codes and generates a Python C/API module that -makes it possible to call Fortran subroutines from Python. No Fortran or -C expertise is required for using this tool. - -New features: - *** Win32 support. - *** Better Python C/API generated code (-Wall is much less verbose). - -Features include: - - *** All basic Fortran types are supported: - integer[ | *1 | *2 | *4 | *8 ], logical[ | *1 | *2 | *4 | *8 ], - character[ | *(*) | *1 | *2 | *3 | ... ] - real[ | *4 | *8 | *16 ], double precision, - complex[ | *8 | *16 | *32 ] - - *** Multi-dimensional arrays of (almost) all basic types. - Dimension specifications: - <dim> | <start>:<end> | * | : - - *** Supported attributes and statements: - intent([ in | inout | out | hide | in,out | inout,out ]) - dimension(<dimspec>) - depend([<names>]) - check([<C-booleanexpr>]) - note(<LaTeX text>) - optional, required, external - intent(c), threadsafe, fortranname - - *** Calling Fortran 77/90/95 subroutines and functions. Also - Fortran 90/95 module subroutines are supported. Internal - initialization of optional arguments. - - *** Accessing COMMON blocks from Python. - Accessing Fortran 90/95 module data. - - *** Call-back functions: calling Python functions from Fortran with - very flexible hooks. - - *** In Python, arguments of the interfaced functions may be of - different type - necessary type conversations are done - internally in C level. - - *** Automatically generates documentation (__doc__,LaTeX) for - interfaced functions. - - *** Automatically generates signature files --- user has full - control over the interface constructions. Automatically - detects the signatures of call-back functions, solves argument - dependencies, etc. - - *** Automatically generates setup_<modulename>.py for building - extension modules using tools from distutils and - fortran_support module (SciPy). - - *** Automatically generates Makefile for compiling Fortran and C - codes and linking them to a shared module. Many compilers are - supported: gcc, Compaq Fortran, VAST/f90 Fortran, Absoft - F77/F90, MIPSpro 7 Compilers, etc. Platforms: Intel/Alpha - Linux, HP-UX, IRIX64. - - *** Complete User's Guide in various formats (html,ps,pdf,dvi). - - *** f2py users list is available for support, feedback, etc. - - *** Installation with distutils. - - *** And finally, many bugs are fixed. - -More information about f2py, see - - http://cens.ioc.ee/projects/f2py2e/ - -LICENSE: - f2py is released under the LGPL. - -Sincerely, - Pearu Peterson <pearu@cens.ioc.ee> - December 17, 2001 - -<P><A HREF="http://cens.ioc.ee/projects/f2py2e/">f2py 2.4.366</A> - The -Fortran to Python Interface Generator (17-Dec-01) diff --git a/numpy/f2py/doc/apps.tex b/numpy/f2py/doc/apps.tex deleted file mode 100644 index 513c048bd..000000000 --- a/numpy/f2py/doc/apps.tex +++ /dev/null @@ -1,71 +0,0 @@ - -\section{Applications} -\label{sec:apps} - - -\subsection{Example: wrapping C library \texttt{fftw}} -\label{sec:wrapfftw} - -Here follows a simple example how to use \fpy to generate a wrapper -for C functions. Let us create a FFT code using the functions in FFTW -library. I'll assume that the library \texttt{fftw} is configured with -\texttt{-{}-enable-shared} option. - -Here is the wrapper for the typical usage of FFTW: -\begin{verbatim} -/* File: wrap_dfftw.c */ -#include <dfftw.h> - -extern void dfftw_one(fftw_complex *in,fftw_complex *out,int *n) { - fftw_plan p; - p = fftw_create_plan(*n,FFTW_FORWARD,FFTW_ESTIMATE); - fftw_one(p,in,out); - fftw_destroy_plan(p); -} -\end{verbatim} -and here follows the corresponding siganture file (created manually): -\begin{verbatim} -!%f90 -! File: fftw.f90 -module fftw - interface - subroutine dfftw_one(in,out,n) - integer n - complex*16 in(n),out(n) - intent(out) out - intent(hide) n - end subroutine dfftw_one - end interface -end module fftw -\end{verbatim} - -Now let us generate the Python C/API module with \fpy: -\begin{verbatim} -f2py fftw.f90 -\end{verbatim} -and compile it -\begin{verbatim} -gcc -shared -I/numeric/include -I`f2py -I` -L/numeric/lib -ldfftw \ - -o fftwmodule.so -DNO_APPEND_FORTRAN fftwmodule.c wrap_dfftw.c -\end{verbatim} - -In Python: -\begin{verbatim} ->>> from Numeric import * ->>> from fftw import * ->>> print dfftw_one.__doc__ -Function signature: - out = dfftw_one(in) -Required arguments: - in : input rank-1 array('D') with bounds (n) -Return objects: - out : rank-1 array('D') with bounds (n) ->>> print dfftw_one([1,2,3,4]) -[ 10.+0.j -2.+2.j -2.+0.j -2.-2.j] ->>> -\end{verbatim} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: diff --git a/numpy/f2py/doc/bugs.tex b/numpy/f2py/doc/bugs.tex deleted file mode 100644 index 699ecf530..000000000 --- a/numpy/f2py/doc/bugs.tex +++ /dev/null @@ -1,109 +0,0 @@ - -\section{Bugs, Plans, and Feedback} -\label{sec:bugs} - -Currently no bugs have found that I was not able to fix. I will be -happy to receive bug reports from you (so that I could fix them and -keep the first sentence of this paragraph as true as possible ;-). -Note that \fpy is developed to work properly with gcc/g77 -compilers. -\begin{description} -\item[NOTE:] Wrapping callback functions returning \texttt{COMPLEX} - may fail on some systems. Workaround: avoid it by using callback - subroutines. -\end{description} - -Here follows a list of things that I plan to implement in (near) future: -\begin{enumerate} -\item recognize file types by their extension (signatures: - \texttt{*.pyf}, Fortran 77, Fortran 90 fixed: \texttt{*.f, *.for, *.F, *.FOR}, - Fortran 90 free: \texttt{*.F90, *.f90, *.m, *.f95, *.F95}); [DONE] -\item installation using \texttt{distutils} (when it will be stable); -\item put out to the web examples of \fpy usages in real situations: - wrapping \texttt{vode}, for example; -\item implement support for \texttt{PARAMETER} statement; [DONE] -\item rewrite test-site; -\item ... -\end{enumerate} -and here are things that I plan to do in future: -\begin{enumerate} -\item implement \texttt{intent(cache)} attribute for an optional work - arrays with a feature of allocating additional memory if needed; -\item use \fpy for wrapping Fortran 90/95 codes. \fpy should scan - Fortran 90/95 codes with no problems, what needs to be done is find - out how to call a Fortran 90/95 function (from a module) from - C. Anybody there willing to test \fpy with Fortran 90/95 modules? [DONE] -\item implement support for Fortran 90/95 module data; [DONE] -\item implement support for \texttt{BLOCK DATA} blocks (if needed); -\item test/document \fpy for \texttt{CHARACTER} arrays; -\item decide whether internal transposition of multi-dimensional - arrays is reasonable (need efficient code then), even if this is - controlled by the user trough some additional keyword; need - consistent and safe policy here; -\item use \fpy for generating wrapper functions also for C programs (a - kind of SWIG, only between Python and C). For that \fpy needs a - command line switch to inform itself that C scalars are passed in by - their value, not by their reference, for instance; -\item introduce a counter that counts the number of inefficient usages - of wrapper functions (copying caused by type-casting, non-contiguous - arrays); -\item if needed, make \texttt{DATA} statement to work properly for - arrays; -\item rewrite \texttt{COMMON} wrapper; [DONE] -\item ... -\end{enumerate} -I'll appreciate any feedback that will improve \fpy (bug reports, -suggestions, etc). If you find a correct Fortran code that fails with -\fpy, try to send me a minimal version of it so that I could track -down the cause of the failure. Note also that there is no sense to -send me files that are auto-generated with \fpy (I can generate them -myself); the version of \fpy that you are using (run \texttt{\fpy\ - -v}), and the relevant fortran codes or modified signature files -should be enough information to fix the bugs. Also add some -information on compilers and linkers that you use to the bug report. - - -\section{History of \fpy} -\label{sec:history} - -\begin{enumerate} -\item I was driven to start developing a tool such as \fpy after I had - wrote several Python C/API modules for interfacing various Fortran - routines from the Netlib. This work was tedious (some of functions - had more than 20 arguments, only few of them made sense for the - problems that they solved). I realized that most of the writing - could be done automatically. -\item On 9th of July, 1999, the first lines of the tool was written. A - prototype of the tool was ready to use in only three weeks. During - this time Travis Oliphant joined to the project and shared his - valuable knowledge and experience; the call-back mechanism is his - major contribution. Then I gave the tool to public under the name - FPIG --- \emph{Fortran to Python Interface Generator}. The tool contained - only one file \texttt{f2py.py}. -\item By autumn, it was clear that a better implementation was needed - as the debugging process became very tedious. So, I reserved some - time and rewrote the tool from scratch. The most important result of - this rewriting was the code that reads real Fortran codes and - determines the signatures of the Fortran routines. The main - attention was payed in particular to this part so that the tool - could read arbitrary Fortran~77/90/95 codes. As a result, the other - side of the tools task, that is, generating Python C/API functions, - was not so great. In public, this version of the tool was called - \texttt{f2py2e} --- \emph{Fortran to Python C/API generator, the - Second Edition}. -\item So, a month before The New Year 2000, I started the third - iteration of the \fpy development. Now the main attention was to - have a good C/API module constructing code. By 21st of January, - 2000, the tool of generating wrapper functions for Fortran routines - was ready. It had many new features and was more robust than ever. -\item In 25th of January, 2000, the first public release of \fpy was - announced (version 1.116). -\item In 12th of September, 2000, the second public release of \fpy was - announced (version 2.264). It now has among other changes a support - for Fortran 90/95 module routines. -\end{enumerate} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: diff --git a/numpy/f2py/doc/collectinput.py b/numpy/f2py/doc/collectinput.py deleted file mode 100755 index 2e3a09d9d..000000000 --- a/numpy/f2py/doc/collectinput.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -""" -collectinput - Collects all files that are included to a main Latex document - with \input or \include commands. These commands must be - in separate lines. - -Copyright 1999 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -Pearu Peterson - -Usage: - collectinput <infile> <outfile> - collectinput <infile> # <outfile>=inputless_<infile> - collectinput # in and out are stdin and stdout -""" - -__version__ = "0.0" - -stdoutflag=0 -import sys,os,string,fileinput,re,commands - -try: fn=sys.argv[2] -except: - try: fn='inputless_'+sys.argv[1] - except: stdoutflag=1 -try: fi=sys.argv[1] -except: fi=() -if not stdoutflag: - sys.stdout=open(fn,'w') - -nonverb=r'[\w\s\\&=\^\*\.\{\(\)\[\?\+\$/]*(?!\\verb.)' -input=re.compile(nonverb+r'\\(input|include)\*?\s*\{?.*}?') -comment=re.compile(r'[^%]*%') - -for l in fileinput.input(fi): - l=l[:-1] - l1='' - if comment.match(l): - m=comment.match(l) - l1=l[m.end()-1:] - l=l[:m.end()-1] - m=input.match(l) - if m: - l=string.strip(l) - if l[-1]=='}': l=l[:-1] - i=m.end()-2 - sys.stderr.write('>>>>>>') - while i>-1 and (l[i] not in [' ','{']): i=i-1 - if i>-1: - fn=l[i+1:] - try: f=open(fn,'r'); flag=1; f.close() - except: - try: f=open(fn+'.tex','r'); flag=1;fn=fn+'.tex'; f.close() - except: flag=0 - if flag==0: - sys.stderr.write('Could not open a file: '+fn+'\n') - print l+l1 - continue - elif flag==1: - sys.stderr.write(fn+'\n') - print '%%%%% Begin of '+fn - print commands.getoutput(sys.argv[0]+' < '+fn) - print '%%%%% End of '+fn - else: - sys.stderr.write('Could not extract a file name from: '+l) - print l+l1 - else: - print l+l1 -sys.stdout.close() diff --git a/numpy/f2py/doc/commands.tex b/numpy/f2py/doc/commands.tex deleted file mode 100644 index 5101a9ff5..000000000 --- a/numpy/f2py/doc/commands.tex +++ /dev/null @@ -1,20 +0,0 @@ -\usepackage{xspace} -\usepackage{verbatim} - -%%tth:\newcommand{\xspace}{ } - -\newcommand{\fpy}{\texttt{f2py}\xspace} - -\newcommand{\bs}{\symbol{`\\}} -% need bs here: -%%tth:\newcommand{\bs}{\texttt{<backslash>}} - -\newcommand{\shell}[1]{\hspace*{1em}\texttt{sh> \begin{minipage}[t]{0.8\textwidth}#1\end{minipage}}} - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: - - diff --git a/numpy/f2py/doc/ex1/arr.f b/numpy/f2py/doc/ex1/arr.f deleted file mode 100644 index c4e49988f..000000000 --- a/numpy/f2py/doc/ex1/arr.f +++ /dev/null @@ -1,4 +0,0 @@ - subroutine arr(l,m,n,a) - integer l,m,n - real*8 a(l,m,n) - end diff --git a/numpy/f2py/doc/ex1/bar.f b/numpy/f2py/doc/ex1/bar.f deleted file mode 100644 index c723b5af1..000000000 --- a/numpy/f2py/doc/ex1/bar.f +++ /dev/null @@ -1,4 +0,0 @@ - function bar(a,b) - integer a,b,bar - bar = a + b - end diff --git a/numpy/f2py/doc/ex1/foo.f b/numpy/f2py/doc/ex1/foo.f deleted file mode 100644 index cdcac4103..000000000 --- a/numpy/f2py/doc/ex1/foo.f +++ /dev/null @@ -1,5 +0,0 @@ - subroutine foo(a) - integer a -cf2py intent(in,out) :: a - a = a + 5 - end diff --git a/numpy/f2py/doc/ex1/foobar-smart.f90 b/numpy/f2py/doc/ex1/foobar-smart.f90 deleted file mode 100644 index 61385a685..000000000 --- a/numpy/f2py/doc/ex1/foobar-smart.f90 +++ /dev/null @@ -1,24 +0,0 @@ -!%f90 -module foobar ! in - note(This module contains two examples that are used in & - \texttt{f2py} documentation.) foobar - interface ! in :foobar - subroutine foo(a) ! in :foobar:foo.f - note(Example of a wrapper function of a Fortran subroutine.) foo - integer intent(inout),& - note(5 is added to the variable {{}\verb@a@{}} ``in place''.) :: a - end subroutine foo - function bar(a,b) result (ab) ! in :foobar:bar.f - integer :: a - integer :: b - integer :: ab - note(The first value.) a - note(The second value.) b - note(Add two values.) bar - note(The result.) ab - end function bar - end interface -end module foobar - -! This file was auto-generated with f2py (version:0.95). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/ex1/foobar.f90 b/numpy/f2py/doc/ex1/foobar.f90 deleted file mode 100644 index 53ac5b506..000000000 --- a/numpy/f2py/doc/ex1/foobar.f90 +++ /dev/null @@ -1,16 +0,0 @@ -!%f90 -module foobar ! in - interface ! in :foobar - subroutine foo(a) ! in :foobar:foo.f - integer intent(inout) :: a - end subroutine foo - function bar(a,b) ! in :foobar:bar.f - integer :: a - integer :: b - integer :: bar - end function bar - end interface -end module foobar - -! This file was auto-generated with f2py (version:0.95). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/ex1/foobarmodule.tex b/numpy/f2py/doc/ex1/foobarmodule.tex deleted file mode 100644 index 32411ec03..000000000 --- a/numpy/f2py/doc/ex1/foobarmodule.tex +++ /dev/null @@ -1,36 +0,0 @@ -% This file is auto-generated with f2py (version:2.266) -\section{Module \texttt{foobar}} - -This module contains two examples that are used in \texttt{f2py} documentation. - -\subsection{Wrapper function \texttt{foo}} - - -\noindent{{}\verb@foo@{}}\texttt{(a)} ---- Example of a wrapper function of a Fortran subroutine. - -\noindent Required arguments: -\begin{description} -\item[]{{}\verb@a : in/output rank-0 array(int,'i')@{}} ---- 5 is added to the variable {{}\verb@a@{}} ``in place''. -\end{description} - -\subsection{Wrapper function \texttt{bar}} - - -\noindent{{}\verb@bar = bar@{}}\texttt{(a, b)} ---- Add two values. - -\noindent Required arguments: -\begin{description} -\item[]{{}\verb@a : input int@{}} ---- The first value. -\item[]{{}\verb@b : input int@{}} ---- The second value. -\end{description} -\noindent Return objects: -\begin{description} -\item[]{{}\verb@bar : int@{}} ---- See elsewhere. -\end{description} - diff --git a/numpy/f2py/doc/ex1/runme b/numpy/f2py/doc/ex1/runme deleted file mode 100755 index 2aac6158e..000000000 --- a/numpy/f2py/doc/ex1/runme +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -f2py2e='python ../../f2py2e.py' -PYINC=`$f2py2e -pyinc` -$f2py2e foobar-smart.pyf --short-latex --overwrite-makefile -makefile foo.f bar.f -gmake -f Makefile-foobar -#gcc -O3 -I$PYINC -I$PYINC/Numeric -shared -o foobarmodule.so foobarmodule.c foo.f bar.f -python -c ' -import foobar -print foobar.__doc__ -print foobar.bar(2,3) -from Numeric import * -a=array(3) -print a,foobar.foo(a),a -print foobar.foo.__doc__ -print foobar.bar.__doc__ -print "ok" -' diff --git a/numpy/f2py/doc/f2py2e.tex b/numpy/f2py/doc/f2py2e.tex deleted file mode 100644 index 6e3e9d68c..000000000 --- a/numpy/f2py/doc/f2py2e.tex +++ /dev/null @@ -1,50 +0,0 @@ -\documentclass{article} -\usepackage{a4wide} - -\input commands - -\title{\fpy\\Fortran to Python Interface Generator\\{\large Second Edition}} -\author{Pearu Peterson \texttt{<pearu@ioc.ee>}} -\date{$Revision: 1.16 $\\\today} -\begin{document} -\special{html: <font size=-1>If equations does not show Greek letters or large - brackets correctly, then your browser configuration needs some - adjustment. Read the notes for <A - href=http://hutchinson.belmont.ma.us/tth/Xfonts.html>Enabling Symbol - Fonts in Netscape under X </A>. In addition, the browser must be set - to use document fonts. </font> -} - -\maketitle -\begin{abstract} - \fpy is a Python program that generates Python C/API modules for - wrapping Fortran~77/90/95 codes to Python. The user can influence the - process by modifying the signature files that \fpy generates when - scanning the Fortran codes. This document describes the syntax of - the signature files and the ways how the user can dictate the tool - to produce wrapper functions with desired Python signatures. Also - how to call the wrapper functions from Python is discussed. - - See \texttt{http://cens.ioc.ee/projects/f2py2e/} for updates of this - document and the tool. -\end{abstract} - -\tableofcontents - -\input intro -\input signaturefile -\input notes -\input options -\input bugs - -\appendix -\input ex1/foobarmodule -\input apps -\end{document} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: - - diff --git a/numpy/f2py/doc/f2python9-final/README.txt b/numpy/f2py/doc/f2python9-final/README.txt deleted file mode 100644 index b907216b6..000000000 --- a/numpy/f2py/doc/f2python9-final/README.txt +++ /dev/null @@ -1,38 +0,0 @@ - -This directory contains the source of the paper - - "Fortran to Python Interface Generator with an Application - to Aerospace Engineering" - -by - Pearu Peterson <pearu@cens.ioc.ee> (the corresponding author) - Joaquim R. R. A. Martins <joaquim.martins@stanford.edu> - Juan J. Alonso <jjalonso@stanford.edu> - -for The 9th International Python Conference, March 5-8, 2001, Long Beach, California. - -The paper is provided here is in the HTML format: - - f2python9.html (size=48151 bytes) - -Note that this file includes the following JPG images - - flow.jpg (size=13266) - structure.jpg (size=17860) - aerostructure.jpg (size=72247) - -PS: -The HTML file f2python9.html is generated using TTH (http://hutchinson.belmont.ma.us/tth/) -from the LaTeX source file `python9.tex'. The source can be found in the - src/ -directory. This directory contains also the following EPS files - flow.eps - structure.eps - aerostructure.eps -and the text files - examples/{exp1.f,exp1mess.txt,exp1session.txt,foo.pyf,foom.pyf} -that are used by the LaTeX source python9.tex. - -Regards, - Pearu -January 15, 2001 diff --git a/numpy/f2py/doc/f2python9-final/aerostructure.jpg b/numpy/f2py/doc/f2python9-final/aerostructure.jpg Binary files differdeleted file mode 100644 index 896ad6e12..000000000 --- a/numpy/f2py/doc/f2python9-final/aerostructure.jpg +++ /dev/null diff --git a/numpy/f2py/doc/f2python9-final/flow.jpg b/numpy/f2py/doc/f2python9-final/flow.jpg Binary files differdeleted file mode 100644 index cfe0f85f3..000000000 --- a/numpy/f2py/doc/f2python9-final/flow.jpg +++ /dev/null diff --git a/numpy/f2py/doc/f2python9-final/mk_html.sh b/numpy/f2py/doc/f2python9-final/mk_html.sh deleted file mode 100755 index 944110e93..000000000 --- a/numpy/f2py/doc/f2python9-final/mk_html.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -cd src - -test -f aerostructure.eps || convert ../aerostructure.jpg aerostructure.eps -test -f flow.eps || convert ../flow.jpg flow.eps -test -f structure.eps || convert ../structure.jpg structure.eps - -latex python9.tex -latex python9.tex -latex python9.tex - -test `which tth` && cat python9.tex | sed -e "s/{{}\\\verb@/\\\texttt{/g" | sed -e "s/@{}}/}/g" | tth -Lpython9 -i > ../f2python9.html -cd .. diff --git a/numpy/f2py/doc/f2python9-final/mk_pdf.sh b/numpy/f2py/doc/f2python9-final/mk_pdf.sh deleted file mode 100755 index b773028b7..000000000 --- a/numpy/f2py/doc/f2python9-final/mk_pdf.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -cd src - -test -f aerostructure.pdf || convert ../aerostructure.jpg aerostructure.pdf -test -f flow.pdf || convert ../flow.jpg flow.pdf -test -f structure.pdf || convert ../structure.jpg structure.pdf - -cat python9.tex | sed -e "s/eps,/pdf,/g" > python9pdf.tex -pdflatex python9pdf.tex -pdflatex python9pdf.tex -pdflatex python9pdf.tex - -mv python9pdf.pdf ../f2python9.pdf
\ No newline at end of file diff --git a/numpy/f2py/doc/f2python9-final/mk_ps.sh b/numpy/f2py/doc/f2python9-final/mk_ps.sh deleted file mode 100755 index 4b0863fcd..000000000 --- a/numpy/f2py/doc/f2python9-final/mk_ps.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -cd src - -test -f aerostructure.eps || convert ../aerostructure.jpg aerostructure.eps -test -f flow.eps || convert ../flow.jpg flow.eps -test -f structure.eps || convert ../structure.jpg structure.eps - -latex python9.tex -latex python9.tex -latex python9.tex - -dvips python9.dvi -o ../f2python9.ps -cd .. -gzip -f f2python9.ps diff --git a/numpy/f2py/doc/f2python9-final/src/examples/exp1.f b/numpy/f2py/doc/f2python9-final/src/examples/exp1.f deleted file mode 100644 index 36bee50b0..000000000 --- a/numpy/f2py/doc/f2python9-final/src/examples/exp1.f +++ /dev/null @@ -1,26 +0,0 @@ - subroutine exp1(l,u,n) -C Input: n is number of iterations -C Output: l,u are such that -C l(1)/l(2) < exp(1) < u(1)/u(2) -C -Cf2py integer*4 :: n = 1 -Cf2py intent(out) l,u - integer*4 n,i - real*8 l(2),u(2),t,t1,t2,t3,t4 - l(2) = 1 - l(1) = 0 - u(2) = 0 - u(1) = 1 - do 10 i=0,n - t1 = 4 + 32*(1+i)*i - t2 = 11 + (40+32*i)*i - t3 = 3 + (24+32*i)*i - t4 = 8 + 32*(1+i)*i - t = u(1) - u(1) = l(1)*t1 + t*t2 - l(1) = l(1)*t3 + t*t4 - t = u(2) - u(2) = l(2)*t1 + t*t2 - l(2) = l(2)*t3 + t*t4 - 10 continue - end diff --git a/numpy/f2py/doc/f2python9-final/src/examples/exp1mess.txt b/numpy/f2py/doc/f2python9-final/src/examples/exp1mess.txt deleted file mode 100644 index ae1545718..000000000 --- a/numpy/f2py/doc/f2python9-final/src/examples/exp1mess.txt +++ /dev/null @@ -1,17 +0,0 @@ -Reading fortran codes... - Reading file 'exp1.f' -Post-processing... - Block: foo - Block: exp1 -Creating 'Makefile-foo'... - Linker: ld ('GNU ld' 2.9.5) - Fortran compiler: f77 ('g77 2.x.x' 2.95.2) - C compiler: cc ('gcc 2.x.x' 2.95.2) -Building modules... - Building module "foo"... - Constructing wrapper function "exp1"... - l,u = exp1([n]) - Wrote C/API module "foo" to file "foomodule.c" - Documentation is saved to file "foomodule.tex" -Run GNU make to build shared modules: - gmake -f Makefile-<modulename> [test] diff --git a/numpy/f2py/doc/f2python9-final/src/examples/exp1session.txt b/numpy/f2py/doc/f2python9-final/src/examples/exp1session.txt deleted file mode 100644 index 9bec9198e..000000000 --- a/numpy/f2py/doc/f2python9-final/src/examples/exp1session.txt +++ /dev/null @@ -1,20 +0,0 @@ ->>> import foo,Numeric ->>> print foo.exp1.__doc__ -exp1 - Function signature: - l,u = exp1([n]) -Optional arguments: - n := 1 input int -Return objects: - l : rank-1 array('d') with bounds (2) - u : rank-1 array('d') with bounds (2) - ->>> l,u = foo.exp1() ->>> print l,u -[ 1264. 465.] [ 1457. 536.] ->>> print l[0]/l[1], u[0]/u[1]-l[0]/l[1] -2.71827956989 2.25856657199e-06 ->>> l,u = foo.exp1(2) ->>> print l,u -[ 517656. 190435.] [ 566827. 208524.] ->>> print l[0]/l[1], u[0]/u[1]-l[0]/l[1] -2.71828182845 1.36437527942e-11
\ No newline at end of file diff --git a/numpy/f2py/doc/f2python9-final/src/examples/foo.pyf b/numpy/f2py/doc/f2python9-final/src/examples/foo.pyf deleted file mode 100644 index 516bb292f..000000000 --- a/numpy/f2py/doc/f2python9-final/src/examples/foo.pyf +++ /dev/null @@ -1,13 +0,0 @@ -!%f90 -*- f90 -*- -python module foo - interface - subroutine exp1(l,u,n) - real*8 dimension(2) :: l - real*8 dimension(2) :: u - integer*4 :: n - end subroutine exp1 - end interface -end python module foo -! This file was auto-generated with f2py -! (version:2.298). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/f2python9-final/src/examples/foom.pyf b/numpy/f2py/doc/f2python9-final/src/examples/foom.pyf deleted file mode 100644 index 6392ebc95..000000000 --- a/numpy/f2py/doc/f2python9-final/src/examples/foom.pyf +++ /dev/null @@ -1,14 +0,0 @@ -!%f90 -*- f90 -*- -python module foo - interface - subroutine exp1(l,u,n) - real*8 dimension(2) :: l - real*8 dimension(2) :: u - intent(out) l,u - integer*4 optional :: n = 1 - end subroutine exp1 - end interface -end python module foo -! This file was auto-generated with f2py -! (version:2.298) and modified by pearu. -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/f2python9-final/structure.jpg b/numpy/f2py/doc/f2python9-final/structure.jpg Binary files differdeleted file mode 100644 index 9aa691339..000000000 --- a/numpy/f2py/doc/f2python9-final/structure.jpg +++ /dev/null diff --git a/numpy/f2py/doc/fortranobject.tex b/numpy/f2py/doc/fortranobject.tex deleted file mode 100644 index dbb244cdd..000000000 --- a/numpy/f2py/doc/fortranobject.tex +++ /dev/null @@ -1,574 +0,0 @@ -\documentclass{article} - -\headsep=0pt -\topmargin=0pt -\headheight=0pt -\oddsidemargin=0pt -\textwidth=6.5in -\textheight=9in - -\usepackage{xspace} -\usepackage{verbatim} -\newcommand{\fpy}{\texttt{f2py}\xspace} -\newcommand{\bs}{\symbol{`\\}} -\newcommand{\email}[1]{\special{html:<A href="mailto:#1">}\texttt{<#1>}\special{html:</A>}} -\title{\texttt{PyFortranObject} --- example usages} -\author{ -\large Pearu Peterson\\ -\small \email{pearu@cens.ioc.ee} -} - -\begin{document} - -\maketitle - -\special{html: Other formats of this document: -<A href=pyfobj.ps.gz>Gzipped PS</A>, -<A href=pyfobj.pdf>PDF</A> -} - -\tableofcontents - -\section{Introduction} -\label{sec:intro} - -Fortran language defines the following concepts that we would like to -access from Python: functions, subroutines, data in \texttt{COMMON} blocks, -F90 module functions and subroutines, F90 module data (both static and -allocatable arrays). - -In the following we shall assume that we know the signatures (full -specifications of routine arguments and variables) of these concepts -from their Fortran source codes. Now, in order to call or use them -from C, one needs to have pointers to the corresponding objects. The -pointers to Fortran 77 objects (routines, data in \texttt{COMMON} -blocks) are readily available to C codes (there are various sources -available about mixing Fortran 77 and C codes). On the other hand, F90 -module specifications are highly compiler dependent and sometimes it -is not even possible to access F90 module objects from C (at least, -not directly, see remark about MIPSPro 7 Compilers). But using some -tricks (described below), the pointers to F90 module objects can be -determined in runtime providing a compiler independent solution. - -To use Fortran objects from Python in unified manner, \fpy introduces -\texttt{PyFortranObject} to hold pointers of the Fortran objects and -the corresponing wrapper functions. In fact, \texttt{PyFortranObject} -does much more: it generates documentation strings in run-time (for -items in \texttt{COMMON} blocks and data in F90 modules), provides -methods for accessing Fortran data and for calling Fortran routines, -etc. - -\section{\texttt{PyFortranObject}} -\label{sec:pyfortobj} - -\texttt{PyFortranObject} is defined as follows -\begin{verbatim} -typedef struct { - PyObject_HEAD - int len; /* Number of attributes */ - FortranDataDef *defs; /* An array of FortranDataDef's */ - PyObject *dict; /* Fortran object attribute dictionary */ -} PyFortranObject; -\end{verbatim} -where \texttt{FortranDataDef} is -\begin{verbatim} -typedef struct { - char *name; /* attribute (array||routine) name */ - int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS, - || rank=-1 for Fortran routine */ - struct {int d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */ - int type; /* PyArray_<type> || not used */ - char *data; /* pointer to array || Fortran routine */ - void (*func)(); /* initialization function for - allocatable arrays: - func(&rank,dims,set_ptr_func,name,len(name)) - || C/API wrapper for Fortran routine */ - char *doc; /* documentation string; only recommended - for routines. */ -} FortranDataDef; -\end{verbatim} -In the following we demonstrate typical usages of -\texttt{PyFortranObject}. Just relevant code fragments will be given. - - -\section{Fortran 77 subroutine} -\label{sec:f77subrout} - -Consider Fortran 77 subroutine -\begin{verbatim} -subroutine bar() -end -\end{verbatim} -The corresponding \texttt{PyFortranObject} is defined in C as follows: -\begin{verbatim} -static char doc_bar[] = "bar()"; -static PyObject *c_bar(PyObject *self, PyObject *args, - PyObject *keywds, void (*f2py_func)()) { - static char *capi_kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(args,keywds,"|:bar",capi_kwlist)) - return NULL; - (*f2py_func)(); - return Py_BuildValue(""); -} -extern void F_FUNC(bar,BAR)(); -static FortranDataDef f2py_routines_def[] = { - {"bar",-1, {-1}, 0, (char *)F_FUNC(bar,BAR),(void*)c_bar,doc_bar}, - {NULL} -}; -void initfoo() { - <snip> - d = PyModule_GetDict(m); - PyDict_SetItemString(d, f2py_routines_def[0].name, - PyFortranObject_NewAsAttr(&f2py_routines_def[0])); -} -\end{verbatim} -where CPP macro \texttt{F\_FUNC} defines how Fortran 77 routines are -seen in C. -In Python, Fortran subroutine \texttt{bar} is called as follows -\begin{verbatim} ->>> import foo ->>> foo.bar() -\end{verbatim} - -\section{Fortran 77 function} -\label{sec:f77func} -Consider Fortran 77 function -\begin{verbatim} -function bar() -complex bar -end -\end{verbatim} -The corresponding \texttt{PyFortranObject} is defined in C as in -previous example but with the following changes: -\begin{verbatim} -static char doc_bar[] = "bar = bar()"; -static PyObject *c_bar(PyObject *self, PyObject *args, - PyObject *keywds, void (*f2py_func)()) { - complex_float bar; - static char *capi_kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(args,keywds,"|:bar",capi_kwlist)) - return NULL; - (*f2py_func)(&bar); - return Py_BuildValue("O",pyobj_from_complex_float1(bar)); -} -extern void F_WRAPPEDFUNC(bar,BAR)(); -static FortranDataDef f2py_routines_def[] = { - {"bar",-1,{-1},0,(char *)F_WRAPPEDFUNC(bar,BAR),(void *)c_bar,doc_bar}, - {NULL} -}; -\end{verbatim} -where CPP macro \texttt{F\_WRAPPEDFUNC} gives the pointer to the following -Fortran 77 subroutine: -\begin{verbatim} -subroutine f2pywrapbar (barf2pywrap) -external bar -complex bar, barf2pywrap -barf2pywrap = bar() -end -\end{verbatim} -With these hooks, calling Fortran functions returning composed types -becomes platform/compiler independent. - - -\section{\texttt{COMMON} block data} -\label{sec:commondata} - -Consider Fortran 77 \texttt{COMMON} block -\begin{verbatim} -integer i -COMMON /bar/ i -\end{verbatim} -In order to access the variable \texttt{i} from Python, -\texttt{PyFortranObject} is defined as follows: -\begin{verbatim} -static FortranDataDef f2py_bar_def[] = { - {"i",0,{-1},PyArray_INT}, - {NULL} -}; -static void f2py_setup_bar(char *i) { - f2py_bar_def[0].data = i; -} -extern void F_FUNC(f2pyinitbar,F2PYINITBAR)(); -static void f2py_init_bar() { - F_FUNC(f2pyinitbar,F2PYINITBAR)(f2py_setup_bar); -} -void initfoo() { - <snip> - PyDict_SetItemString(d, "bar", PyFortranObject_New(f2py_bar_def,f2py_init_bar)); -} -\end{verbatim} -where auxiliary Fortran function \texttt{f2pyinitbar} is defined as follows -\begin{verbatim} -subroutine f2pyinitbar(setupfunc) -external setupfunc -integer i -common /bar/ i -call setupfunc(i) -end -\end{verbatim} -and it is called in \texttt{PyFortranObject\_New}. - - -\section{Fortran 90 module subroutine} -\label{sec:f90modsubrout} - -Consider -\begin{verbatim} -module fun - subroutine bar() - end subroutine bar -end module fun -\end{verbatim} -\texttt{PyFortranObject} is defined as follows -\begin{verbatim} -static char doc_fun_bar[] = "fun.bar()"; -static PyObject *c_fun_bar(PyObject *self, PyObject *args, - PyObject *keywds, void (*f2py_func)()) { - static char *kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(args,keywds,"",kwlist)) - return NULL; - (*f2py_func)(); - return Py_BuildValue(""); -} -static FortranDataDef f2py_fun_def[] = { - {"bar",-1,{-1},0,NULL,(void *)c_fun_bar,doc_fun_bar}, - {NULL} -}; -static void f2py_setup_fun(char *bar) { - f2py_fun_def[0].data = bar; -} -extern void F_FUNC(f2pyinitfun,F2PYINITFUN)(); -static void f2py_init_fun() { - F_FUNC(f2pyinitfun,F2PYINITFUN)(f2py_setup_fun); -} -void initfoo () { - <snip> - PyDict_SetItemString(d, "fun", PyFortranObject_New(f2py_fun_def,f2py_init_fun)); -} -\end{verbatim} -where auxiliary Fortran function \texttt{f2pyinitfun} is defined as -follows -\begin{verbatim} -subroutine f2pyinitfun(f2pysetupfunc) -use fun -external f2pysetupfunc -call f2pysetupfunc(bar) -end subroutine f2pyinitfun -\end{verbatim} -The following Python session demonstrates how to call Fortran 90 -module function \texttt{bar}: -\begin{verbatim} ->>> import foo ->>> foo.fun.bar() -\end{verbatim} - -\section{Fortran 90 module function} -\label{sec:f90modfunc} - -Consider -\begin{verbatim} -module fun - function bar() - complex bar - end subroutine bar -end module fun -\end{verbatim} -\texttt{PyFortranObject} is defined as follows -\begin{verbatim} -static char doc_fun_bar[] = "bar = fun.bar()"; -static PyObject *c_fun_bar(PyObject *self, PyObject *args, - PyObject *keywds, void (*f2py_func)()) { - complex_float bar; - static char *kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(args,keywds,"",kwlist)) - return NULL; - (*f2py_func)(&bar); - return Py_BuildValue("O",pyobj_from_complex_float1(bar)); -} -static FortranDataDef f2py_fun_def[] = { - {"bar",-1,{-1},0,NULL,(void *)c_fun_bar,doc_fun_bar}, - {NULL} -}; -static void f2py_setup_fun(char *bar) { - f2py_fun_def[0].data = bar; -} -extern void F_FUNC(f2pyinitfun,F2PYINITFUN)(); -static void f2py_init_fun() { - F_FUNC(f2pyinitfun,F2PYINITFUN)(f2py_setup_fun); -} -void initfoo() { - <snip> - PyDict_SetItemString(d, "fun", PyFortranObject_New(f2py_fun_def,f2py_init_fun)); -} -\end{verbatim} -where -\begin{verbatim} -subroutine f2pywrap_fun_bar (barf2pywrap) -use fun -complex barf2pywrap -barf2pywrap = bar() -end - -subroutine f2pyinitfun(f2pysetupfunc) -external f2pysetupfunc,f2pywrap_fun_bar -call f2pysetupfunc(f2pywrap_fun_bar) -end -\end{verbatim} - - -\section{Fortran 90 module data} -\label{sec:f90moddata} - -Consider -\begin{verbatim} -module fun - integer i -end module fun -\end{verbatim} -Then -\begin{verbatim} -static FortranDataDef f2py_fun_def[] = { - {"i",0,{-1},PyArray_INT}, - {NULL} -}; -static void f2py_setup_fun(char *i) { - f2py_fun_def[0].data = i; -} -extern void F_FUNC(f2pyinitfun,F2PYINITFUN)(); -static void f2py_init_fun() { - F_FUNC(f2pyinitfun,F2PYINITFUN)(f2py_setup_fun); -} -void initfoo () { - <snip> - PyDict_SetItemString(d, "fun", - PyFortranObject_New(f2py_fun_def,f2py_init_fun)); -} -\end{verbatim} -where -\begin{verbatim} -subroutine f2pyinitfun(f2pysetupfunc) -use fun -external f2pysetupfunc -call f2pysetupfunc(i) -end subroutine f2pyinitfun -\end{verbatim} -Example usage in Python: -\begin{verbatim} ->>> import foo ->>> foo.fun.i = 4 -\end{verbatim} - -\section{Fortran 90 module allocatable array} -\label{sec:f90modallocarr} - -Consider -\begin{verbatim} -module fun - real, allocatable :: r(:) -end module fun -\end{verbatim} -Then -\begin{verbatim} -static FortranDataDef f2py_fun_def[] = { - {"r",1,{-1},PyArray_FLOAT}, - {NULL} -}; -static void f2py_setup_fun(void (*r)()) { - f2py_fun_def[0].func = r; -} -extern void F_FUNC(f2pyinitfun,F2PYINITFUN)(); -static void f2py_init_fun() { - F_FUNC(f2pyinitfun,F2PYINITFUN)(f2py_setup_fun); -} -void initfoo () { - <snip> - PyDict_SetItemString(d, "fun", PyFortranObject_New(f2py_fun_def,f2py_init_fun)); -} -\end{verbatim} -where -\begin{verbatim} -subroutine f2py_fun_getdims_r(r,s,f2pysetdata) -use fun, only: d => r -external f2pysetdata -logical ns -integer s(*),r,i,j -ns = .FALSE. -if (allocated(d)) then - do i=1,r - if ((size(d,r-i+1).ne.s(i)).and.(s(i).ge.0)) then - ns = .TRUE. - end if - end do - if (ns) then - deallocate(d) - end if -end if -if ((.not.allocated(d)).and.(s(1).ge.1)) then - allocate(d(s(1))) -end if -if (allocated(d)) then - do i=1,r - s(i) = size(d,r-i+1) - end do -end if -call f2pysetdata(d,allocated(d)) -end subroutine f2py_fun_getdims_r - -subroutine f2pyinitfun(f2pysetupfunc) -use fun -external f2pysetupfunc,f2py_fun_getdims_r -call f2pysetupfunc(f2py_fun_getdims_r) -end subroutine f2pyinitfun -\end{verbatim} -Usage in Python: -\begin{verbatim} ->>> import foo ->>> foo.fun.r = [1,2,3,4] -\end{verbatim} - -\section{Callback subroutine} -\label{sec:cbsubr} - -Thanks to Travis Oliphant for working out the basic idea of the -following callback mechanism. - -Consider -\begin{verbatim} -subroutine fun(bar) -external bar -call bar(1) -end -\end{verbatim} -Then -\begin{verbatim} -static char doc_foo8_fun[] = " -Function signature: - fun(bar,[bar_extra_args]) -Required arguments: - bar : call-back function -Optional arguments: - bar_extra_args := () input tuple -Call-back functions: - def bar(e_1_e): return - Required arguments: - e_1_e : input int"; -static PyObject *foo8_fun(PyObject *capi_self, PyObject *capi_args, - PyObject *capi_keywds, void (*f2py_func)()) { - PyObject *capi_buildvalue = NULL; - PyObject *bar_capi = Py_None; - PyTupleObject *bar_xa_capi = NULL; - PyTupleObject *bar_args_capi = NULL; - jmp_buf bar_jmpbuf; - int bar_jmpbuf_flag = 0; - int bar_nofargs_capi = 0; - static char *capi_kwlist[] = {"bar","bar_extra_args",NULL}; - - if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\ - "O!|O!:foo8.fun",\ - capi_kwlist,&PyFunction_Type,&bar_capi,&PyTuple_Type,&bar_xa_capi)) - goto capi_fail; - - bar_nofargs_capi = cb_bar_in_fun__user__routines_nofargs; - if (create_cb_arglist(bar_capi,bar_xa_capi,1,0, - &cb_bar_in_fun__user__routines_nofargs,&bar_args_capi)) { - if ((PyErr_Occurred())==NULL) - PyErr_SetString(foo8_error,"failed in processing argument list for call-back bar." ); - goto capi_fail; - } - - SWAP(bar_capi,cb_bar_in_fun__user__routines_capi,PyObject); - SWAP(bar_args_capi,cb_bar_in_fun__user__routines_args_capi,PyTupleObject); - memcpy(&bar_jmpbuf,&cb_bar_in_fun__user__routines_jmpbuf,sizeof(jmp_buf)); - bar_jmpbuf_flag = 1; - - if ((setjmp(cb_bar_in_fun__user__routines_jmpbuf))) { - if ((PyErr_Occurred())==NULL) - PyErr_SetString(foo8_error,"Failure of a callback function"); - goto capi_fail; - } else - (*f2py_func)(cb_bar_in_fun__user__routines); - - capi_buildvalue = Py_BuildValue(""); -capi_fail: - - if (bar_jmpbuf_flag) { - cb_bar_in_fun__user__routines_capi = bar_capi; - Py_DECREF(cb_bar_in_fun__user__routines_args_capi); - cb_bar_in_fun__user__routines_args_capi = bar_args_capi; - cb_bar_in_fun__user__routines_nofargs = bar_nofargs_capi; - memcpy(&cb_bar_in_fun__user__routines_jmpbuf,&bar_jmpbuf,sizeof(jmp_buf)); - bar_jmpbuf_flag = 0; - } - return capi_buildvalue; -} -extern void F_FUNC(fun,FUN)(); -static FortranDataDef f2py_routine_defs[] = { - {"fun",-1,{-1},0,(char *)F_FUNC(fun,FUN),(void *)foo8_fun,doc_foo8_fun}, - {NULL} -}; -void initfoo8 () { - <snip> - PyDict_SetItemString(d, f2py_routine_defs[0].name, - PyFortranObject_NewAsAttr(&f2py_routine_defs[0])); -} -\end{verbatim} -where -\begin{verbatim} -PyObject *cb_bar_in_fun__user__routines_capi = Py_None; -PyTupleObject *cb_bar_in_fun__user__routines_args_capi = NULL; -int cb_bar_in_fun__user__routines_nofargs = 0; -jmp_buf cb_bar_in_fun__user__routines_jmpbuf; -static void cb_bar_in_fun__user__routines (int *e_1_e_cb_capi) { - PyTupleObject *capi_arglist = cb_bar_in_fun__user__routines_args_capi; - PyObject *capi_return = NULL; - PyObject *capi_tmp = NULL; - int capi_j,capi_i = 0; - - int e_1_e=(*e_1_e_cb_capi); - if (capi_arglist == NULL) - goto capi_fail; - if (cb_bar_in_fun__user__routines_nofargs>capi_i) - if (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_int1(e_1_e))) - goto capi_fail; - - capi_return = PyEval_CallObject(cb_bar_in_fun__user__routines_capi, - (PyObject *)capi_arglist); - - if (capi_return == NULL) - goto capi_fail; - if (capi_return == Py_None) { - Py_DECREF(capi_return); - capi_return = Py_BuildValue("()"); - } - else if (!PyTuple_Check(capi_return)) { - capi_tmp = capi_return; - capi_return = Py_BuildValue("(O)",capi_tmp); - Py_DECREF(capi_tmp); - } - capi_j = PyTuple_Size(capi_return); - capi_i = 0; - goto capi_return_pt; -capi_fail: - fprintf(stderr,"Call-back cb_bar_in_fun__user__routines failed.\n"); - Py_XDECREF(capi_return); - longjmp(cb_bar_in_fun__user__routines_jmpbuf,-1); -capi_return_pt: - ; -} -\end{verbatim} -Usage in Python: -\begin{verbatim} ->>> import foo8 as foo ->>> def bar(i): print 'In bar i=',i -... ->>> foo.fun(bar) -In bar i= 1 -\end{verbatim} - -\end{document} - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: diff --git a/numpy/f2py/doc/index.html b/numpy/f2py/doc/index.html deleted file mode 100644 index e162ed41a..000000000 --- a/numpy/f2py/doc/index.html +++ /dev/null @@ -1,264 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> -<HTML> -<HEAD> -<META name="Author" content="Pearu Peterson"> -<!-- You may add here some keywords (comma separeted list) --> -<META name="Keywords" content="fortran,python,interface,f2py,f2py2e,wrapper,fpig"> -<TITLE>F2PY - Fortran to Python Interface Generator</TITLE> -<LINK rel="stylesheet" type="text/css" href="/styles/userstyle.css"> -</HEAD> - -<BODY> -<!-- Begin of user text --> -<H1>F2PY ­ Fortran to Python Interface Generator</H1> -by <em>Pearu Peterson</em> - -<h2>What's new?</h2> - -See <a href="NEWS.txt">NEWS.txt</a> for the latest changes in <code>f2py</code>. -<dl> - <dt> July ??, 2002 - <dd> Implemented prototype calculator, complete tests for scalar F77 - functions, --help-compiler option. Fixed number of bugs and - removed obsolete features. - <dt> April 4, 2002 - <dd> Fixed a nasty bug of copying one-dimensional non-contiguous arrays. - (Thanks to Travis O. for pointing this out). - <dt> March 26, 2002 - <dd> Bug fixes, turned off F2PY_REPORT_ATEXIT by default. - <dt> March 13, 2002 - <dd> MAC support, fixed incomplete dependency calculator, minor bug fixes. - <dt> March 3, 2002 - <dd> Fixed memory leak and copying of multi-dimensional complex arrays. - <dt> <a href="oldnews.html">Old news</a>. -</dl> - -<h2>Introduction</h2> - -Writing Python C/API wrappers for Fortran routines can be a very -tedious task, especially if a Fortran routine takes more than 20 -arguments but only few of them are relevant for the problems that they -solve. So, I have developed a tool that generates the C/API modules -containing wrapper functions of Fortran routines. I call this -tool as <em>F2PY ­ Fortran to Python Interface Generator</em>. -It is completely written in <a href="http://www.python.org">Python</a> -language and can be called from the command line as <code>f2py</code>. -<em>F2PY</em> (in NumPy) is released under the terms of the NumPy License. - - -<h2><code>f2py</code>, Second Edition</h2> - -The development of <code>f2py</code> started in summer of 1999. -For now (January, 2000) it has reached to stage of being a -complete tool: it scans real Fortran code, creates signature file -that the user can modify, constructs C/API module that can be -complied and imported to Python, and it creates LaTeX documentation -for wrapper functions. Below is a bit longer list of -<code>f2py</code> features: -<ol> - <li> <code>f2py</code> scans real Fortran codes and produces the signature files. - The syntax of the signature files is borrowed from the Fortran 90/95 - language specification with some extensions. - <li> <code>f2py</code> generates a GNU Makefile that can be used - for building shared modules (see below for a list of supported - platforms/compilers). Starting from the third release, - <code>f2py</code> generates <code>setup_modulename.py</code> for - building extension modules using <code>distutils</code> tools. - <li> <code>f2py</code> uses the signature files to produce the wrappers for - Fortran 77 routines and their <code>COMMON</code> blocks. - <li> For <code>external</code> arguments <code>f2py</code> constructs a very flexible - call-back mechanism so that Python functions can be called from - Fortran. - <li> You can pass in almost arbitrary Python objects to wrapper - functions. If needed, <code>f2py</code> takes care of type-casting and - non-contiguous arrays. - <li> You can modify the signature files so that <code>f2py</code> will generate - wrapper functions with desired signatures. <code>depend()</code> - attribute is introduced to control the initialization order of the - variables. <code>f2py</code> introduces <code>intent(hide)</code> - attribute to remove - the particular argument from the argument list of the wrapper - function and <code>intent(c)</code> that is useful for wrapping C -libraries. In addition, <code>optional</code> and -<code>required</code> - attributes are introduced and employed. - <li> <code>f2py</code> supports almost all standard Fortran 77/90/95 constructs - and understands all basic Fortran types, including - (multi-dimensional, complex) arrays and character strings with - adjustable and assumed sizes/lengths. - <li> <code>f2py</code> generates a LaTeX document containing the - documentations of the wrapped functions (argument types, dimensions, - etc). The user can easily add some human readable text to the - documentation by inserting <code>note(<LaTeX text>)</code> attribute to - the definition of routine signatures. - <li> With <code>f2py</code> one can access also Fortran 90/95 - module subroutines from Python. -</ol> - -For more information, see the <a href="usersguide.html">User's -Guide</a> of the tool. Windows users should also take a look at -<a href="win32_notes.txt">f2py HOWTO for Win32</a> (its latest version -can be found <a -href="http://www.numpy.org/Members/eric/f2py_win32">here</a>). - -<h3>Requirements</h3> -<ol> - <li> You'll need <a - href="http://www.python.org/download/">Python</a> - (1.5.2 or later, 2.2 is recommended) to run <code>f2py</code> - (because it uses exchanged module <code>re</code>). - To build generated extension modules with distutils setup script, - you'll need Python 2.x. - <li> You'll need <a - href="http://sourceforge.net/project/?group_id=1369">Numerical - Python</a> - (version 13 or later, 20.3 is recommended) to compile - C/API modules (because they use function - <code>PyArray_FromDimsAndDataAndDescr</code>) -</ol> - -<h3>Download</h3> - -<dl> - <dt> User's Guide: - <dd> <a href="usersguide.html">usersguide.html</a>, - <a href="usersguide.pdf">usersguide.pdf</a>, - <a href="usersguide.ps.gz">usersguide.ps.gz</a>, - <a href="usersguide.dvi">usersguide.dvi</a>. - <dt> Snapshots of the fifth public release: - <dd> <a href="2.x">2.x</a>/<a href="2.x/F2PY-2-latest.tar.gz">F2PY-2-latest.tar.gz</a> - <dt> Snapshots of earlier releases: - <dd> <a href="rel-5.x">rel-5.x</a>, <a href="rel-4.x">rel-4.x</a>, - <a href="rel-3.x">rel-3.x</a>, - <a href="rel-2.x">rel-2.x</a>,<a href="rel-1.x">rel-1.x</a>, - <a href="rel-0.x">rel-0.x</a> -</dl> - -<h3>Installation</h3> - -Unpack the source file, change to directory <code>f2py-?-???</code> -and run <code>python setup.py install</code>. That's it! - -<h3>Platform/Compiler Related Notes</h3> - -<code>f2py</code> has been successfully tested on -<ul> - <li> Intel Linux (MD7.0,RH6.1,RH4.2,Debian woody), Athlon Linux (RH6.1), Alpha Linux (RH5.2,RH6.1) with <a -href="http://gcc.gnu.org/">gcc</a> (versions egcs-2.91.60,egcs-2.91.66, and 2.95.2). - <li> Intel Linux (MD7.0) with <a - href="http://www.psrv.com/index.html">Pacific-Sierra - Research</a> <a href="http://www.psrv.com/lnxf90.html">Personal - Linux VAST/f90 Fortran 90 compiler</a> (version V3.4N5). - <li> Intel Linux (RH6.1) with <a href="http://www.absoft.com/">Absoft F77/F90</a> compilers for Linux. - <li> IRIX64 with <a href="http://gcc.gnu.org/">gcc</a> (2.95.2) and <a -href="http://www.sgi.com/developers/devtools/languages/mipspro.html">MIPSpro -7 Compilers</a> (f77,f90,cc versions 7.30). - <li> Alpha Linux (RH5.2,RH6.1) with <a href="http://www.digital.com/fortran/linux/">Compaq Fortran </a> compiler (version V1.0-920). - <li> Linux with <a href="http://www.nag.co.uk/">NAGWare</a> Fortran - 95 compiler. - <li> <a href="http://developer.intel.com/software/products/compilers/f50/linux/"> - Intel(R) Fortran Compiler for Linux</a> - <li> Windows 2000 with <a href="http://www.mingw.org">mingw32</a>. -</ul> -<code>f2py</code> will probably run on other UN*X systems as -well. Additions to the list of platforms/compilers where -<code>f2py</code> has been successfully used are most welcome. -<P> -<em>Note:</em> -Using Compaq Fortran -compiler on Alpha Linux is succesful unless when -wrapping Fortran callback functions returning -<code>COMPLEX</code>. This applies also for IRIX64. -<P> -<em>Note:</em> -Fortran 90/95 module support is currently tested with Absoft F90, VAST/f90, Intel F90 compilers on Linux (MD7.0,Debian woody). - - -<h3><a name="f2py-users">Mailing list</a></h3> - -There is a mailing list <a -href="http://cens.ioc.ee/pipermail/f2py-users/">f2py-users</a> -available for the users of the <code>f2py</code> -program and it is open for discussion, questions, and answers. You can subscribe -the list <a href="http://cens.ioc.ee/mailman/listinfo/f2py-users">here</a>. - -<h3><a href="http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/">CVS Repository</a></h3> - -<code>f2py</code> is being developed under <a href="http://www.sourcegear.com/CVS">CVS</a> and those who are -interested in the really latest version of <code>f2py</code> (possibly -unstable) can get it from the repository as follows: -<ol> - <li> First you need to login (the password is <code>guest</code>): -<pre> -> cvs -d :pserver:anonymous@cens.ioc.ee:/home/cvs login -</pre> - <li> and then do the checkout: -<pre> -> cvs -z6 -d :pserver:anonymous@cens.ioc.ee:/home/cvs checkout f2py2e -</pre> - <li> In the directory <code>f2py2e</code> you can get the updates by hitting -<pre> -> cvs -z6 update -P -d -</pre> -</ol> -You can browse <code>f2py</code> CVS repository <a href="http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/">here</a>. - -<h2>Related sites</h2> - -<ol> - <li> <a href="http://pfdubois.com/numpy/" target="_top">Numerical Python</a>. - <li> <a href="http://pyfortran.sourceforge.net/" target="_top">Pyfort</a> -- The Python-Fortran connection tool. - <li> <a href="http://starship.python.net/crew/hinsen/scientific.html" target="_top">Scientific Python</a>. - <li> <a href="http://numpy.org/" target="_top">SciPy</a> -- Scientific tools for Python (includes Multipack). - <li> <a href="http://www.fortran.com/fortran/" target="_top">The Fortran Company</a>. - <li> <a href="http://www.j3-fortran.org/" target="_top">Fortran Standards</a>. - - <li> <a href="http://www.fortran.com/fortran/F77_std/rjcnf.html">American National Standard Programming Language FORTRAN ANSI(R) X3.9-1978</a> - <li> <a href="http://www.mathtools.net" target="_top">Mathtools.net</a> -- A technical computing portal for all scientific and engineering needs. - -</ol> - -<!-- End of user text --> -<HR> -<ADDRESS> -<A href="http://validator.w3.org/"><IMG border=0 align=right src="/icons/vh40.gif" alt="Valid HTML 4.0!" height=31 width=88></A> -<A href="http://cens.ioc.ee/~pearu/" target="_top">Pearu Peterson</A> -<A href="mailto:pearu(at)ioc.ee"><pearu(at)ioc.ee></A><BR> -<!-- hhmts start --> -Last modified: Fri Jan 20 14:55:12 MST 2006 -<!-- hhmts end --> -</ADDRESS> -<!-- You may want to comment the following line out when the document is final--> -<!-- Check that the reference is right --> -<!--A href="http://validator.w3.org/check?uri=http://cens.ioc.ee/projects/f2py2e/index.html;ss"> Submit this page for validation</A--> - -<p> -<center> -This <a href="http://www.ctv.es/USERS/irmina/pythonring.html">Python -ring</a> site owned by <a href="mailto:pearu(at)ioc.ee">Pearu Peterson</a>. -<br> -[ - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;id=12;prev5">Previous 5 Sites</a> -| - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;id=12;prev">Previous</a> -| - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;id=12;next">Next</a> -| - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;id=12;next5">Next 5 Sites</a> -| - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;random">Random Site</a> -| - <a href="http://nav.webring.org/cgi-bin/navcgi?ring=python_ring;list">List Sites</a> -] -</center> -<p> - - - -</BODY> - - -</HTML> - - - diff --git a/numpy/f2py/doc/intro.tex b/numpy/f2py/doc/intro.tex deleted file mode 100644 index d9625b09c..000000000 --- a/numpy/f2py/doc/intro.tex +++ /dev/null @@ -1,158 +0,0 @@ - -\section{Introduction} -\label{sec:intro} - -\fpy is a command line tool that generates Python C/API modules for -interfacing Fortran~77/90/95 codes and Fortran~90/95 modules from -Python. In general, using \fpy an -interface is produced in three steps: -\begin{itemize} -\item[(i)] \fpy scans Fortran sources and creates the so-called - \emph{signature} file; the signature file contains the signatures of - Fortran routines; the signatures are given in the free format of the - Fortran~90/95 language specification. Latest version of \fpy - generates also a make file for building shared module. - About currently supported compilers see the \fpy home page -\item[(ii)] Optionally, the signature files can be modified manually - in order to dictate how the Fortran routines should be called or - seemed from the Python environment. -\item[(iii)] \fpy reads the signature files and generates Python C/API - modules that can be compiled and imported to Python code. In - addition, a LaTeX document is generated that contains the - documentation of wrapped functions. -\end{itemize} -(Note that if you are satisfied with the default signature that \fpy -generates in step (i), all three steps can be covered with just -one call to \fpy --- by not specifying `\texttt{-h}' flag). -Latest versions of \fpy support so-called \fpy directive that allows -inserting various information about wrapping directly to Fortran -source code as comments (\texttt{<comment char>f2py <signature statement>}). - -The following diagram illustrates the usage of the tool: -\begin{verbatim} -! Fortran file foo.f: - subroutine foo(a) - integer a - a = a + 5 - end -\end{verbatim} -\begin{verbatim} -! Fortran file bar.f: - function bar(a,b) - integer a,b,bar - bar = a + b - end -\end{verbatim} -\begin{itemize} -\item[(i)] \shell{\fpy foo.f bar.f -m foobar -h foobar.pyf} -\end{itemize} -\begin{verbatim} -!%f90 -! Signature file: foobar.pyf -python module foobar ! in - interface ! in :foobar - subroutine foo(a) ! in :foobar:foo.f - integer intent(inout) :: a - end subroutine foo - function bar(a,b) ! in :foobar:bar.f - integer :: a - integer :: b - integer :: bar - end function bar - end interface -end python module foobar -\end{verbatim} -\begin{itemize} -\item[(ii)] Edit the signature file (here I made \texttt{foo}s - argument \texttt{a} to be \texttt{intent(inout)}, see - Sec.~\ref{sec:attributes}). -\item[(iii)] \shell{\fpy foobar.pyf} -\end{itemize} -\begin{verbatim} -/* Python C/API module: foobarmodule.c */ -... -\end{verbatim} -\begin{itemize} -\item[(iv)] \shell{make -f Makefile-foobar} -%\shell{gcc -shared -I/usr/include/python1.5/ foobarmodule.c\bs\\ -%foo.f bar.f -o foobarmodule.so} -\end{itemize} -\begin{verbatim} -Python shared module: foobarmodule.so -\end{verbatim} -\begin{itemize} -\item[(v)] Usage in Python: -\end{itemize} -\vspace*{-4ex} -\begin{verbatim} ->>> import foobar ->>> print foobar.__doc__ -This module 'foobar' is auto-generated with f2py (version:1.174). -The following functions are available: - foo(a) - bar = bar(a,b) -. ->>> print foobar.bar(2,3) -5 ->>> from Numeric import * ->>> a = array(3) ->>> print a,foobar.foo(a),a -3 None 8 -\end{verbatim} -Information about how to call \fpy (steps (i) and (iii)) can be -obtained by executing\\ -\shell{\fpy}\\ -This will print the usage instructions. - Step (iv) is system dependent -(compiler and the locations of the header files \texttt{Python.h} and -\texttt{arrayobject.h}), and so you must know how to compile a shared -module for Python in you system. - -The next Section describes the step (ii) in more detail in order to -explain how you can influence to the process of interface generation -so that the users can enjoy more writing Python programs using your -wrappers that call Fortran routines. Step (v) is covered in -Sec.~\ref{sec:notes}. - - -\subsection{Features} -\label{sec:features} - -\fpy has the following features: -\begin{enumerate} -\item \fpy scans real Fortran codes and produces the signature files. - The syntax of the signature files is borrowed from the Fortran~90/95 - language specification with some extensions. -\item \fpy uses the signature files to produce the wrappers for - Fortran~77 routines and their \texttt{COMMON} blocks. -\item For \texttt{external} arguments \fpy constructs a very flexible - call-back mechanism so that Python functions can be called from - Fortran. -\item You can pass in almost arbitrary Python objects to wrapper - functions. If needed, \fpy takes care of type-casting and - non-contiguous arrays. -\item You can modify the signature files so that \fpy will generate - wrapper functions with desired signatures. \texttt{depend()} - attribute is introduced to control the initialization order of the - variables. \fpy introduces \texttt{intent(hide)} attribute to remove - the particular argument from the argument list of the wrapper - function. In addition, \texttt{optional} and \texttt{required} - attributes are introduced and employed. -\item \fpy supports almost all standard Fortran~77/90/95 constructs - and understands all basic Fortran types, including - (multi-dimensional, complex) arrays and character strings with - adjustable and assumed sizes/lengths. -\item \fpy generates a LaTeX document containing the - documentations of the wrapped functions (argument types, dimensions, - etc). The user can easily add some human readable text to the - documentation by inserting \texttt{note(<LaTeX text>)} attribute to - the definition of routine signatures. -\item \fpy generates a GNU make file that can be used for building - shared modules calling Fortran functions. -\item \fpy supports wrapping Fortran 90/95 module routines. -\end{enumerate} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: diff --git a/numpy/f2py/doc/multiarray/array_from_pyobj.c b/numpy/f2py/doc/multiarray/array_from_pyobj.c deleted file mode 100644 index 7e0de9a74..000000000 --- a/numpy/f2py/doc/multiarray/array_from_pyobj.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * File: array_from_pyobj.c - * - * Description: - * ------------ - * Provides array_from_pyobj function that returns a contigious array - * object with the given dimensions and required storage order, either - * in row-major (C) or column-major (Fortran) order. The function - * array_from_pyobj is very flexible about its Python object argument - * that can be any number, list, tuple, or array. - * - * array_from_pyobj is used in f2py generated Python extension - * modules. - * - * Author: Pearu Peterson <pearu@cens.ioc.ee> - * Created: 13-16 January 2002 - * $Id: array_from_pyobj.c,v 1.1 2002/01/16 18:57:33 pearu Exp $ - */ - - -#define ARR_IS_NULL(arr,mess) \ -if (arr==NULL) { \ - fprintf(stderr,"array_from_pyobj:" mess); \ - return NULL; \ -} - -#define CHECK_DIMS_DEFINED(rank,dims,mess) \ -if (count_nonpos(rank,dims)) { \ - fprintf(stderr,"array_from_pyobj:" mess); \ - return NULL; \ -} - -#define HAS_PROPER_ELSIZE(arr,type_num) \ - ((PyArray_DescrFromType(type_num)->elsize) == (arr)->descr->elsize) - -/* static */ -/* void f2py_show_args(const int type_num, */ -/* const int *dims, */ -/* const int rank, */ -/* const int intent) { */ -/* int i; */ -/* fprintf(stderr,"array_from_pyobj:\n\ttype_num=%d\n\trank=%d\n\tintent=%d\n",\ */ -/* type_num,rank,intent); */ -/* for (i=0;i<rank;++i) */ -/* fprintf(stderr,"\tdims[%d]=%d\n",i,dims[i]); */ -/* } */ - -static -int count_nonpos(const int rank, - const int *dims) { - int i=0,r=0; - while (i<rank) { - if (dims[i] <= 0) ++r; - ++i; - } - return r; -} - -static void lazy_transpose(PyArrayObject* arr); -static int check_and_fix_dimensions(const PyArrayObject* arr, - const int rank, - int *dims); -static -int array_has_column_major_storage(const PyArrayObject *ap); - -static -PyArrayObject* array_from_pyobj(const int type_num, - int *dims, - const int rank, - const int intent, - PyObject *obj) { - /* Note about reference counting - ----------------------------- - If the caller returns the array to Python, it must be done with - Py_BuildValue("N",arr). - Otherwise, if obj!=arr then the caller must call Py_DECREF(arr). - */ - -/* f2py_show_args(type_num,dims,rank,intent); */ - - if (intent & F2PY_INTENT_CACHE) { - /* Don't expect correct storage order or anything reasonable when - returning cache array. */ - if ((intent & F2PY_INTENT_HIDE) - || (obj==Py_None)) { - PyArrayObject *arr = NULL; - CHECK_DIMS_DEFINED(rank,dims,"optional,intent(cache) must" - " have defined dimensions.\n"); - arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num); - ARR_IS_NULL(arr,"FromDims failed: optional,intent(cache)\n"); - if (intent & F2PY_INTENT_OUT) - Py_INCREF(arr); - return arr; - } - if (PyArray_Check(obj) - && ISCONTIGUOUS((PyArrayObject *)obj) - && HAS_PROPER_ELSIZE((PyArrayObject *)obj,type_num) - ) { - if (check_and_fix_dimensions((PyArrayObject *)obj,rank,dims)) - return NULL; /*XXX: set exception */ - if (intent & F2PY_INTENT_OUT) - Py_INCREF(obj); - return (PyArrayObject *)obj; - } - ARR_IS_NULL(NULL,"intent(cache) must be contiguous array with a proper elsize.\n"); - } - - if (intent & F2PY_INTENT_HIDE) { - PyArrayObject *arr = NULL; - CHECK_DIMS_DEFINED(rank,dims,"intent(hide) must have defined dimensions.\n"); - arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num); - ARR_IS_NULL(arr,"FromDims failed: intent(hide)\n"); - if (intent & F2PY_INTENT_OUT) { - if ((!(intent & F2PY_INTENT_C)) && (rank>1)) { - lazy_transpose(arr); - arr->flags &= ~CONTIGUOUS; - } - Py_INCREF(arr); - } - return arr; - } - - if (PyArray_Check(obj)) { /* here we have always intent(in) or - intent(inout) */ - - PyArrayObject *arr = (PyArrayObject *)obj; - int is_cont = (intent & F2PY_INTENT_C) ? - (ISCONTIGUOUS(arr)) : (array_has_column_major_storage(arr)); - - if (check_and_fix_dimensions(arr,rank,dims)) - return NULL; /*XXX: set exception */ - - if ((intent & F2PY_INTENT_COPY) - || (! (is_cont - && HAS_PROPER_ELSIZE(arr,type_num) - && PyArray_CanCastSafely(arr->descr->type_num,type_num)))) { - PyArrayObject *tmp_arr = NULL; - if (intent & F2PY_INTENT_INOUT) { - ARR_IS_NULL(NULL,"intent(inout) array must be contiguous and" - " with a proper type and size.\n") - } - if ((rank>1) && (! (intent & F2PY_INTENT_C))) - lazy_transpose(arr); - if (PyArray_CanCastSafely(arr->descr->type_num,type_num)) { - tmp_arr = (PyArrayObject *)PyArray_CopyFromObject(obj,type_num,0,0); - ARR_IS_NULL(arr,"CopyFromObject failed: array.\n"); - } else { - tmp_arr = (PyArrayObject *)PyArray_FromDims(arr->nd, - arr->dimensions, - type_num); - ARR_IS_NULL(tmp_arr,"FromDims failed: array with unsafe cast.\n"); - if (copy_ND_array(arr,tmp_arr)) - ARR_IS_NULL(NULL,"copy_ND_array failed: array with unsafe cast.\n"); - } - if ((rank>1) && (! (intent & F2PY_INTENT_C))) { - lazy_transpose(arr); - lazy_transpose(tmp_arr); - tmp_arr->flags &= ~CONTIGUOUS; - } - arr = tmp_arr; - } - if (intent & F2PY_INTENT_OUT) - Py_INCREF(arr); - return arr; - } - - if ((obj==Py_None) && (intent & F2PY_OPTIONAL)) { - PyArrayObject *arr = NULL; - CHECK_DIMS_DEFINED(rank,dims,"optional must have defined dimensions.\n"); - arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num); - ARR_IS_NULL(arr,"FromDims failed: optional.\n"); - if (intent & F2PY_INTENT_OUT) { - if ((!(intent & F2PY_INTENT_C)) && (rank>1)) { - lazy_transpose(arr); - arr->flags &= ~CONTIGUOUS; - } - Py_INCREF(arr); - } - return arr; - } - - if (intent & F2PY_INTENT_INOUT) { - ARR_IS_NULL(NULL,"intent(inout) argument must be an array.\n"); - } - - { - PyArrayObject *arr = (PyArrayObject *) \ - PyArray_ContiguousFromObject(obj,type_num,0,0); - ARR_IS_NULL(arr,"ContiguousFromObject failed: not a sequence.\n"); - if (check_and_fix_dimensions(arr,rank,dims)) - return NULL; /*XXX: set exception */ - if ((rank>1) && (! (intent & F2PY_INTENT_C))) { - PyArrayObject *tmp_arr = NULL; - lazy_transpose(arr); - arr->flags &= ~CONTIGUOUS; - tmp_arr = (PyArrayObject *) PyArray_CopyFromObject((PyObject *)arr,type_num,0,0); - Py_DECREF(arr); - arr = tmp_arr; - ARR_IS_NULL(arr,"CopyFromObject(Array) failed: intent(fortran)\n"); - lazy_transpose(arr); - arr->flags &= ~CONTIGUOUS; - } - if (intent & F2PY_INTENT_OUT) - Py_INCREF(arr); - return arr; - } - -} - - /*****************************************/ - /* Helper functions for array_from_pyobj */ - /*****************************************/ - -static -int array_has_column_major_storage(const PyArrayObject *ap) { - /* array_has_column_major_storage(a) is equivalent to - transpose(a).iscontiguous() but more efficient. - - This function can be used in order to decide whether to use a - Fortran or C version of a wrapped function. This is relevant, for - example, in choosing a clapack or flapack function depending on - the storage order of array arguments. - */ - int sd; - int i; - sd = ap->descr->elsize; - for (i=0;i<ap->nd;++i) { - if (ap->dimensions[i] == 0) return 1; - if (ap->strides[i] != sd) return 0; - sd *= ap->dimensions[i]; - } - return 1; -} - -static -void lazy_transpose(PyArrayObject* arr) { - /* - Changes the order of array strides and dimensions. This - corresponds to the lazy transpose of a Numeric array in-situ. - Note that this function is assumed to be used even times for a - given array. Otherwise, the caller should set flags &= ~CONTIGUOUS. - */ - int rank,i,s,j; - rank = arr->nd; - if (rank < 2) return; - - for(i=0,j=rank-1;i<rank/2;++i,--j) { - s = arr->strides[i]; - arr->strides[i] = arr->strides[j]; - arr->strides[j] = s; - s = arr->dimensions[i]; - arr->dimensions[i] = arr->dimensions[j]; - arr->dimensions[j] = s; - } -} - -static -int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,int *dims) { - /* - This function fills in blanks (that are -1's) in dims list using - the dimensions from arr. It also checks that non-blank dims will - match with the corresponding values in arr dimensions. - */ - const int arr_size = (arr->nd)?PyArray_Size((PyObject *)arr):1; - - if (rank > arr->nd) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */ - int new_size = 1; - int free_axe = -1; - int i; - /* Fill dims where -1 or 0; check dimensions; calc new_size; */ - for(i=0;i<arr->nd;++i) { - if (dims[i] >= 0) { - if (dims[i]!=arr->dimensions[i]) { - fprintf(stderr,"%d-th dimension must be fixed to %d but got %d\n", - i,dims[i],arr->dimensions[i]); - return 1; - } - if (!dims[i]) dims[i] = 1; - } else { - dims[i] = arr->dimensions[i] ? arr->dimensions[i] : 1; - } - new_size *= dims[i]; - } - for(i=arr->nd;i<rank;++i) - if (dims[i]>1) { - fprintf(stderr,"%d-th dimension must be %d but got 0 (not defined).\n", - i,dims[i]); - return 1; - } else if (free_axe<0) - free_axe = i; - else - dims[i] = 1; - if (free_axe>=0) { - dims[free_axe] = arr_size/new_size; - new_size *= dims[free_axe]; - } - if (new_size != arr_size) { - fprintf(stderr,"confused: new_size=%d, arr_size=%d (maybe too many free" - " indices)\n",new_size,arr_size); - return 1; - } - } else { - int i; - for (i=rank;i<arr->nd;++i) - if (arr->dimensions[i]>1) { - fprintf(stderr,"too many axes: %d, expected rank=%d\n",arr->nd,rank); - return 1; - } - for (i=0;i<rank;++i) - if (dims[i]>=0) { - if (arr->dimensions[i]!=dims[i]) { - fprintf(stderr,"%d-th dimension must be fixed to %d but got %d\n", - i,dims[i],arr->dimensions[i]); - return 1; - } - if (!dims[i]) dims[i] = 1; - } else - dims[i] = arr->dimensions[i]; - } - return 0; -} - -/* End of file: array_from_pyobj.c */ diff --git a/numpy/f2py/doc/multiarray/bar.c b/numpy/f2py/doc/multiarray/bar.c deleted file mode 100644 index 350636ea6..000000000 --- a/numpy/f2py/doc/multiarray/bar.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include <stdio.h> - -void bar(int *a,int m,int n) { - int i,j; - printf("C:"); - printf("m=%d, n=%d\n",m,n); - for (i=0;i<m;++i) { - printf("Row %d:\n",i+1); - for (j=0;j<n;++j) - printf("a(i=%d,j=%d)=%d\n",i,j,a[n*i+j]); - } - if (m*n) - a[0] = 7777; -} diff --git a/numpy/f2py/doc/multiarray/foo.f b/numpy/f2py/doc/multiarray/foo.f deleted file mode 100644 index f8c39c4d1..000000000 --- a/numpy/f2py/doc/multiarray/foo.f +++ /dev/null @@ -1,13 +0,0 @@ - subroutine foo(a,m,n) - integer a(m,n), m,n,i,j - print*, "F77:" - print*, "m=",m,", n=",n - do 100,i=1,m - print*, "Row ",i,":" - do 50,j=1,n - print*, "a(i=",i,",j=",j,") = ",a(i,j) - 50 continue - 100 continue - if (m*n.gt.0) a(1,1) = 77777 - end - diff --git a/numpy/f2py/doc/multiarray/fortran_array_from_pyobj.txt b/numpy/f2py/doc/multiarray/fortran_array_from_pyobj.txt deleted file mode 100644 index c7b945c84..000000000 --- a/numpy/f2py/doc/multiarray/fortran_array_from_pyobj.txt +++ /dev/null @@ -1,284 +0,0 @@ - - _____________________________________________________________ - / Proposed internal structure for f2py generated extension \ - < modules regarding the issues with different storage-orders > - \ of multi-dimensional matrices in Fortran and C. / - ============================================================= - -Author: Pearu Peterson -Date: 14 January, 2001 - -Definitions: -============ - -In the following I will use the following definitions: - -1) A matrix is a mathematical object that represents a collection of - objects (elements), usually visualized in a table form, and one can - define a set of various (algebraic,etc) operations for matrices. - One can think of a matrix as a defintion of a certain mapping: - (i) |--> A(i) - where i belongs to the set of indices (an index itself can be a - sequence of objects, for example, a sequence of integers) and A(i) - is an element from a specified set, for example, a set of fruits. - Symbol A then denotes a matrix of fruits. - -2) An array is a storage object that represents a collection of - objects stored in a certain systematic way, for example, as an - ordered sequence in computer memory. - -In order to manipulate matrices using computers, one must store matrix -elements in computer memory. In the following, I will assume that the -elements of a matrix is stored as an array. There is no unique way in -which order one should save matrix elements in the array. However, in -C and Fortran programming languages, two, unfortunately different, -conventions are used. - -Aim: -==== - -The purpose of this writing is to work out an interface for Python -language so that C and Fortran routines can be called without -bothering about how multi-dimensional matrices are stored in memory. -For example, accessing a matrix element A[i,j] in Python will be -equivalent to accessing the same matrix in C, using A[i][j], or in -Fortran, using A(i,j). - -External conditions: -==================== - -In C programming language, it is custom to think that matrices are -stored in the so-called row-major order, that is, a matrix is stored -row by row, each row is as a contiguous array in computer memory. - -In Fortran programming language, matrices are stored in the -column-major order: each column is a contiguous array in computer -memory. - -In Python programming language, matrices can be stored using Python -Numeric array() function that uses internally C approach, that is, -elements of matrices are stored in row-major order. For example, -A = array([[1,2,3],[4,5,6]]) represents a 2-by-3 matrix - - / 1 2 3 \ - | | - \ 4 5 6 / - -and its elements are stored in computer memory as the following array: - - 1 2 3 4 5 6 - -The same matrix, if used in Fortran, would be stored in computer -memory as the following array: - - 1 4 2 5 3 6 - -Problem and solution: -===================== - -A problem arises if one wants to use the same matrix both in C and in -Fortran functions. Then the difference in storage order of a matrix -elements must be taken into account. This technical detail can be very -confusing even for an experienced programmer. This is because when -passing a matrix to a Fortran subroutine, you must (mentally or -programmically) transpose the matrix and when the subroutine returns, -you must transpose it back. - -As will be discussed below, there is a way to overcome these -difficulties in Python by creating an interface between Python and -Fortran code layers that takes care of this transition internally. So -that if you will read the manual pages of the Fortran codes, then you -need not to think about how matrices are actually stored, the storage -order will be the same, seemingly. - -Python / C / Fortran interface: -=============================== - -The interface between Python and Fortran codes will use the following -Python Numeric feature: transposing a Numeric array does not involve -copying of its data but just permuting the dimensions and strides of -the array (the so-called lazy transpose). - -However, when passing a Numeric array data pointer to Fortran or C -function, the data must be contiguous in memory. If it is not, then -data is rearranged inplace. I don't think that it can be avoided. -This is certainly a penalty hit to performance. However, one can -easily avoid it by creating a Numeric array with the right storage -order, so that after transposing, the array data will be contiguous in -memory and the data pointer can safely passed on to the Fortran -subroutine. This lazy-transpose operation will be done within the -interface and users need not to bother about this detail anymore (that -is, after they initialize Numeric array with matrix elements using the -proper order. Of course, the proper order depends on the target -function: C or Fortran). The interface should be smart enough to -minimize the need of real-transpose operations and the need to -additional memory storage as well. - -Statement of the problem: -========================= - -Consider a M-by-N matrix A of integers, where M and N are the number A -rows and columns, respectively. - -In Fortran language, the storing array of this matrix can be defined -as follows: - - integer A(M,N) - -in C: - - int A[M][N]; - -and in Python: - - A = Numeric.zeros((M,N),'i') - -Consider also the corresponding Fortran and C functions that -that use matrix arguments: - -Fortran: - subroutine FUN(A,M,N) - integer A(M,N) - ... - end -C: - void cun(int *a,int m,int n) { - ... - } - -and the corresponding Python interface signatures: - - def py_fun(a): - ... - def py_cun(a): - ... - -Main goal: -========== - -Our goal is to generate Python C/API functions py_fun and py_cun such -that their usage in Python would be identical. The cruical part of -their implementation are in functions that take a PyObject and -return a PyArrayObject such that it is contiguous and its data pointer -is suitable for passing on to the arguments of C or Fortran functions. -The prototypes of these functions are: - -PyArrayObject* fortran_array_from_pyobj( - int typecode, - int *dims, - int rank, - int intent, - PyObject *obj); - -and - -PyArrayObject* c_array_from_pyobj( - int typecode, - int *dims, - int rank, - int intent, - PyObject *obj); - -for wrapping Fortran and C functions, respectively. - -Pseudo-code for fortran_array_from_pyobj: -========================================= - -if type(obj) is ArrayType: - #raise not check(len(ravel(obj)) >= dims[0]*dims[1]*...*dims[rank-1]) - if obj.typecode is typecode: - if is_contiguous(obj): - transpose_data_inplace(obj) # real-transpose - set_transpose_strides(obj) # lazy-transpose - Py_INCREF(obj); - return obj - set_transpose_strides(obj) - if is_contiguous(obj): - set_transpose_strides(obj) - Py_INCREF(obj); - return obj - else: - tmp_obj = PyArray_ContiguousFromObject(obj,typecode,0,0) - swap_datapointer_and_typeinfo(obj,tmp_obj) - Py_DECREF(tmp_obj); - set_transpose_strides(obj) - Py_INCREF(obj); - return obj - else: - tmp_obj = PyArray_FromDims(rank,dims,typecode) - set_transpose_strides(tmp_obj) - if intent in [in,inout]: - copy_ND_array(obj,tmp_obj) - swap_datapointer_and_typeinfo(obj,tmp_obj) - Py_DECREF(tmp_obj); - Py_INCREF(obj); - return obj -elif obj is None: # happens when only intent is 'hide' - tmp_obj = PyArray_FromDims(rank,dims,typecode) - if intent is out: - set_transpose_strides(tmp_obj) - # otherwise tmp_obj->data is used as a work array - Py_INCREF(tmp_obj) - return tmp_obj -else: - tmp_obj = PyArray_ContiguousFromObject(obj,typecode,0,0) - #raise not check(len(ravel(obj)) >= dims[0]*dims[1]*...*dims[rank-1]) - set_transpose_strides(tmp_obj) - transpose_data_inplace(tmp_obj) - Py_INCREF(tmp_obj) - return tmp_obj - -Notes: - 1) CPU expensive tasks are in transpose_data_inplace and - copy_ND_array, PyArray_ContiguousFromObject. - 2) Memory expensive tasks are in PyArray_FromDims, - PyArray_ContiguousFromObject - 3) Side-effects are expected when set_transpose_strides and - transpose_data_inplace are used. For example: - >>> a = Numeric([[1,2,3],[4,5,6]],'d') - >>> a.is_contiguous() - 1 - >>> py_fun(a) - >>> a.typecode() - 'i' - >>> a.is_contiguous() - 0 - >>> transpose(a).is_contiguous() - 1 - -Pseudo-code for c_array_from_pyobj: -=================================== - -if type(obj) is ArrayType: - #raise not check(len(ravel(obj)) >= dims[0]*dims[1]*...*dims[rank-1]) - if obj.typecode is typecode: - if is_contiguous(obj): - Py_INCREF(obj); - return obj - else: - tmp_obj = PyArray_ContiguousFromObject(obj,typecode,0,0) - swap_datapointer_and_typeinfo(obj,tmp_obj) - Py_DECREF(tmp_obj); - Py_INCREF(obj); - return obj - else: - tmp_obj = PyArray_FromDims(rank,dims,typecode) - if intent in [in,inout]: - copy_ND_array(obj,tmp_obj) - swap_datapointer_and_typeinfo(obj,tmp_obj) - Py_DECREF(tmp_obj); - Py_INCREF(obj); - return obj -elif obj is None: # happens when only intent is 'hide' - tmp_obj = PyArray_FromDims(rank,dims,typecode) - Py_INCREF(tmp_obj) - return tmp_obj -else: - tmp_obj = PyArray_ContiguousFromObject(obj,typecode,0,0) - #raise not check(len(ravel(obj)) >= dims[0]*dims[1]*...*dims[rank-1]) - Py_INCREF(tmp_obj) - return tmp_obj - - -14 January, 2002 -Pearu Peterson <pearu@cens.ioc.ee>
\ No newline at end of file diff --git a/numpy/f2py/doc/multiarray/fun.pyf b/numpy/f2py/doc/multiarray/fun.pyf deleted file mode 100644 index ed5d1923f..000000000 --- a/numpy/f2py/doc/multiarray/fun.pyf +++ /dev/null @@ -1,89 +0,0 @@ -!%f90 -*- f90 -*- - -! Example: -! Using f2py for wrapping multi-dimensional Fortran and C arrays -! [NEW APPROACH, use it with f2py higher than 2.8.x] -! $Id: fun.pyf,v 1.3 2002/01/18 10:06:50 pearu Exp $ - -! Usage (with gcc compiler): -! f2py -c fun.pyf foo.f bar.c - -python module fun ! in - interface ! in :fun - -! >>> from Numeric import * -! >>> import fun -! >>> a=array([[1,2,3],[4,5,6]]) - - subroutine foo(a,m,n) ! in :fun:foo.f - integer dimension(m,n) :: a - intent(in,out,copy) :: a - integer optional,check(shape(a,0)==m),depend(a) :: m=shape(a,0) - integer optional,check(shape(a,1)==n),depend(a) :: n=shape(a,1) - end subroutine foo - -! >>> print fun.foo.__doc__ -! foo - Function signature: -! a = foo(a,[m,n]) -! Required arguments: -! a : input rank-2 array('i') with bounds (m,n) -! Optional arguments: -! m := shape(a,0) input int -! n := shape(a,1) input int -! Return objects: -! a : rank-2 array('i') with bounds (m,n) - -! >>> print fun.foo(a) -! F77: -! m= 2, n= 3 -! Row 1: -! a(i= 1,j= 1) = 1 -! a(i= 1,j= 2) = 2 -! a(i= 1,j= 3) = 3 -! Row 2: -! a(i= 2,j= 1) = 4 -! a(i= 2,j= 2) = 5 -! a(i= 2,j= 3) = 6 -! [[77777 2 3] -! [ 4 5 6]] - - - subroutine bar(a,m,n) - intent(c) - intent(c) bar - integer dimension(m,n) :: a - intent(in,out) :: a - integer optional,check(shape(a,0)==m),depend(a) :: m=shape(a,0) - integer optional,check(shape(a,1)==n),depend(a) :: n=shape(a,1) - intent(in) m,n - end subroutine bar - -! >>> print fun.bar.__doc__ -! bar - Function signature: -! a = bar(a,[m,n]) -! Required arguments: -! a : input rank-2 array('i') with bounds (m,n) -! Optional arguments: -! m := shape(a,0) input int -! n := shape(a,1) input int -! Return objects: -! a : rank-2 array('i') with bounds (m,n) - -! >>> print fun.bar(a) -! C:m=2, n=3 -! Row 1: -! a(i=0,j=0)=1 -! a(i=0,j=1)=2 -! a(i=0,j=2)=3 -! Row 2: -! a(i=1,j=0)=4 -! a(i=1,j=1)=5 -! a(i=1,j=2)=6 -! [[7777 2 3] -! [ 4 5 6]] - - end interface -end python module fun - -! This file was auto-generated with f2py (version:2.9.166). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/multiarray/run.pyf b/numpy/f2py/doc/multiarray/run.pyf deleted file mode 100644 index bb12a439b..000000000 --- a/numpy/f2py/doc/multiarray/run.pyf +++ /dev/null @@ -1,91 +0,0 @@ -!%f90 -*- f90 -*- - -! Example: -! Using f2py for wrapping multi-dimensional Fortran and C arrays -! [OLD APPROACH, do not use it with f2py higher than 2.8.x] -! $Id: run.pyf,v 1.1 2002/01/14 15:49:46 pearu Exp $ - -! Usage (with gcc compiler): -! f2py -c run.pyf foo.f bar.c -DNO_APPEND_FORTRAN - -python module run ! in - interface ! in :run - -! >>> from Numeric import * -! >>> import run -! >>> a=array([[1,2,3],[4,5,6]],'i') - - subroutine foo(a,m,n) - fortranname foo_ - integer dimension(m,n) :: a - integer optional,check(shape(a,1)==m),depend(a) :: m=shape(a,1) - integer optional,check(shape(a,0)==n),depend(a) :: n=shape(a,0) - end subroutine foo - -! >>> print run.foo.__doc__ -! foo - Function signature: -! foo(a,[m,n]) -! Required arguments: -! a : input rank-2 array('i') with bounds (n,m) -! Optional arguments: -! m := shape(a,1) input int -! n := shape(a,0) input int - -! >>> run.foo(a) -! F77: -! m= 3, n= 2 -! Row 1: -! a(i= 1,j= 1) = 1 -! a(i= 1,j= 2) = 4 -! Row 2: -! a(i= 2,j= 1) = 2 -! a(i= 2,j= 2) = 5 -! Row 3: -! a(i= 3,j= 1) = 3 -! a(i= 3,j= 2) = 6 - -! >>> run.foo(transpose(a)) -! F77: -! m= 2, n= 3 -! Row 1: -! a(i= 1,j= 1) = 1 -! a(i= 1,j= 2) = 2 -! a(i= 1,j= 3) = 3 -! Row 2: -! a(i= 2,j= 1) = 4 -! a(i= 2,j= 2) = 5 -! a(i= 2,j= 3) = 6 - - subroutine bar(a,m,n) - intent(c) - integer dimension(m,n) :: a - integer optional,check(shape(a,0)==m),depend(a) :: m=shape(a,0) - integer optional,check(shape(a,1)==n),depend(a) :: n=shape(a,1) - end subroutine bar - -! >>> print run.bar.__doc__ -! bar - Function signature: -! bar(a,[m,n]) -! Required arguments: -! a : rank-2 array('i') with bounds (m,n) -! Optional arguments: -! m := shape(a,0) int -! n := shape(a,1) int - -! >>> run.bar(a) -! C:m=2, n=3 -! Row 1: -! a(i=0,j=0)=1 -! a(i=0,j=1)=2 -! a(i=0,j=2)=3 -! Row 2: -! a(i=1,j=0)=4 -! a(i=1,j=1)=5 -! a(i=1,j=2)=6 - - - end interface -end python module run - -! This file was auto-generated with f2py (version:2.8.172). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/doc/multiarray/transpose.txt b/numpy/f2py/doc/multiarray/transpose.txt deleted file mode 100644 index a8d41e6df..000000000 --- a/numpy/f2py/doc/multiarray/transpose.txt +++ /dev/null @@ -1,1127 +0,0 @@ -From: Phil Garner (garner@signal.dra.hmg.gb) - Subject: In place matrix transpose - Newsgroups: sci.math.num-analysis - Date: 1993-08-05 06:35:06 PST - - -Someone was talking about matrix transposes earlier on. It's a -curious subject. I found that an in-place transpose is about 12 times -slower than the trivial copying method. - -Here's somthing I nicked from netlib and translated into C to do the -in-place one for those that are interested: (matrix must be in one -block) - - -typedef float scalar; /* float -> double for double precision */ - -/* - * In Place Matrix Transpose - * From: Algorithm 380 collected algorithms from ACM. - * Converted to C by Phil Garner - * - * Algorithm appeared in comm. ACM, vol. 13, no. 05, - * p. 324. - */ -int trans(scalar *a, unsigned m, unsigned n, int *move, int iwrk) -{ - scalar b; - int i, j, k, i1, i2, ia, ib, ncount, kmi, Max, mn; - - /* - * a is a one-dimensional array of length mn=m*n, which - * contains the m by n matrix to be transposed. - * move is a one-dimensional array of length iwrk - * used to store information to speed up the process. the - * value iwrk=(m+n)/2 is recommended. Return val indicates the - * success or failure of the routine. - * normal return = 0 - * errors - * -2, iwrk negative or zero. - * ret > 0, (should never occur). in this case - * we set ret equal to the final value of i when the search - * is completed but some loops have not been moved. - * check arguments and initialise - */ - - /* Function Body */ - if (n < 2 || m < 2) - return 0; - if (iwrk < 1) - return -2; - - /* If matrix is square, exchange elements a(i,j) and a(j,i). */ - if (n == m) - { - for (i = 0; i < m - 1; ++i) - for (j = i + 1; j < m; ++j) - { - i1 = i + j * m; - i2 = j + i * m; - b = a[i1]; - a[i1] = a[i2]; - a[i2] = b; - } return 0; - } - - /* Non square matrix */ - ncount = 2; - for (i = 0; i < iwrk; ++i) - move[i] = 0; - - if (n > 2) - /* Count number,ncount, of single points. */ - for (ia = 1; ia < n - 1; ++ia) - { - ib = ia * (m - 1) / (n - 1); - if (ia * (m - 1) != ib * (n - 1)) - continue; - ++ncount; - i = ia * m + ib; - if (i > iwrk) - continue; - move[i] = 1; - } - - /* Set initial values for search. */ - mn = m * n; - k = mn - 1; - kmi = k - 1; - Max = mn; - i = 1; - - while (1) - { - /* Rearrange elements of a loop. */ - /* At least one loop must be re-arranged. */ - i1 = i; - while (1) - { - b = a[i1]; - while (1) - { - i2 = n * i1 - k * (i1 / m); - if (i1 <= iwrk) - move[i1 - 1] = 2; - ++ncount; - if (i2 == i || i2 >= kmi) - { - if (Max == kmi || i2 == i) - break; - Max = kmi; - } - a[i1] = a[i2]; - i1 = i2; - } - - /* Test for symmetric pair of loops. */ - a[i1] = b; - if (ncount >= mn) - return 0; - if (i2 == Max || Max == kmi) - break; - Max = kmi; - i1 = Max; - } - - /* Search for loops to be rearranged. */ - while (1) - { - Max = k - i; - ++i; - kmi = k - i; - if (i > Max) - return i; - if (i <= iwrk) - { - if (move[i-1] < 1) - break; - continue; - } - if (i == n * i - k * (i / m)) - continue; - i1 = i; - while (1) - { - i2 = n * i1 - k * (i1 / m); - if (i2 <= i || i2 >= Max) - break; - i1 = i2; - } - if (i2 == i) - break; - } - } /* End never reached */ -} - --- - ,----------------------------- ______ - ____ | Phil Garner. \___| |/ \ \ ____ -/__/ `--, _L__L\_ | garner@signal.dra.hmg.gb | _|`---' \_/__/ `--, -`-0---0-' `-0--0-' `--OO-------------------O-----' `---0---' `-0---0-' - - From: Murray Dow (mld900@anusf.anu.edu.au) - Subject: Re: In place matrix transpose - Newsgroups: sci.math.num-analysis - Date: 1993-08-09 19:45:57 PST - - -In article <23qmp3INN3gl@mentor.dra.hmg.gb>, garner@signal.dra.hmg.gb (Phil Garner) writes: -|> Someone was talking about matrix transposes earlier on. It's a -|> curious subject. I found that an in-place transpose is about 12 times -|> slower than the trivial copying method. -|> - -Algorithm 380 from CACM is sloweer than ALG 467. Here are my times -from a VP2200 vector computer. Note that the CACM algorithms are scalar. -Times are in seconds, for a 900*904 matrix: - -380 NAG 467 disc copy -1.03 1.14 .391 .177 - -Compare two vector algortihms, one I wrote and the second a matrix -copy: - -My Alg Matrix copy -.0095 .0097 - -Conclusions: dont use Alg 380 from Netlib. If you have the available memory, -do a matrix copy. If you don't have the memory, I will send you my algorithm -when I have published it. --- -Murray Dow GPO Box 4 Canberra ACT 2601 Australia -Supercomputer Facility Phone: +61 6 2495028 -Australian National University Fax: +61 6 2473425 -mld900@anusf.anu.edu.au - -============================================================================= - -From: Mark Smotherman (mark@hubcap.clemson.edu) - Subject: Matrix transpose benchmark [was Re: MIPS R8000 == TFP?] - Newsgroups: comp.arch, comp.benchmarks, comp.sys.super - Date: 1994-07-01 06:35:51 PST - - -mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes: - -> ->Of course, these results are all for the naive algorithm. I would be ->interested to see what an efficient blocked algorithm looks like. ->Anyone care to offer one? There is clearly a lot of performance ->to be gained by the effort.... - -Here is a matrix transpose benchmark generator. Enter something like - - 10d10eij; - -and you get a benchmark program with tiles of size 10 for the i and j -inner loops. Please email code improvements and flames. - -Enjoy! - - -/*--------------------------------------------------------------------------- - - Matrix Transpose Generator - - Copyright 1993, Dept. of Computer Science, Clemson University - - Permission to use, copy, modify, and distribute this software and - its documentation for any purpose and without fee is hereby granted, - provided that the above copyright notice appears in all copies. - - Clemson University and its Dept. of Computer Science make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied warranty. - - Original author: Mark Smotherman - - -------------------------------------------------------------------------*/ - - -/* tpgen.c version 1.0 - * - * generate a matrix transpose loop nest, with tiling and unrolling - * (timing code using getrusage is included in the generated program) - * - * mark smotherman - * mark@cs.clemson.edu - * clemson university - * 9 july 1993 - * - * a loop nest can be described by the order of its loop indices, so - * this program takes as input a simple language describing these indices: - * <number>d ==> generate tiling loop for index i with step size of <number> - * <number>e ==> generate tiling loop for index j with step size of <number> - * <number>i ==> generate loop for index i with unrolling factor of <number> - * <number>j ==> generate loop for index j with unrolling factor of <number> - * ; ==> input terminator (required) - * rules are: - * i,j tokens must appear - * if d appears, it must appear before i - * if e appears, it must appear before j - * ; must appear - * matrix size is controlled by #define N in this program. - * - * this code was adapted from mmgen.c v1.2 and extended to generate pre- - * condition loops for unrolling factors that do not evenly divide the - * matrix size (or the tiling step size for loop nests with a tiling loop). - * note that this program only provides a preconditioning loop for the - * innermost loop. unrolling factors for non-innermost loops that do not - * evenly divide the matrix size (or step size) are not supported. - * - * my interest in this program generator is to hook it to a sentence - * generator and a minimum execution time finder, that is - * while((sentence=sgen())!=NULL){ - * genprogram=tpgen(sentence); - * system("cc -O4 genprogram.c"); - * system("a.out >> tpresults"); - * } - * findmintime(tpresults); - * this will find the optimum algorithm for the host system via an - * exhaustive search. - * - * please report bugs and suggestions for enhancements to me. - */ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#define N 500 - -#define ALLOC1 temp1=(struct line *)malloc(sizeof(struct line));\ -temp1->indentcnt=indentcnt; - -#define LINK1 temp1->next=insertbefore;\ -insertafter->next=temp1;\ -insertafter=temp1; - -#define INSERT1 temp1->next=start;\ -start=temp1; - -#define ALLOC2 temp1=(struct line *)malloc(sizeof(struct line));\ -temp2=(struct line *)malloc(sizeof(struct line));\ -temp1->indentcnt=indentcnt;\ -temp2->indentcnt=indentcnt++; - -#define LINK2 temp1->next=temp2;\ -temp2->next=insertbefore;\ -insertafter->next=temp1;\ -insertafter=temp1;\ -insertbefore=temp2; - -struct line{ int indentcnt; char line[256]; struct line *next; }; - -int indentcnt; -int iflag,jflag; -int ijflag,jiflag; -int dflag,eflag; -int counter; -int iistep,jjstep; -int iunroll,junroll; -int precond; - -char c; -int i,ttp,nt; -char *p0; -char tptype[80]; -char number[10]; - -struct line *start,*head,*insertafter,*insertbefore,*temp1,*temp2; - -void processloop(); -void processstmt(); - -main(){ - - indentcnt=0; - iflag=jflag=0; - ijflag=jiflag=0; - dflag=eflag=0; - iunroll=junroll=0; - counter=1; - precond=0; - ttp=0; - - start=NULL; - ALLOC2 - sprintf(temp1->line,"/* begin */\nt_start=second();\n"); - sprintf(temp2->line,"/* end */\nt_end = second();\n"); - head=temp1; temp1->next=temp2; temp2->next=NULL; - insertafter=temp1; insertbefore=temp2; - - while((c=getchar())!=';'){ - tptype[ttp++]=c; - if(isdigit(c)){ - nt=0; - while(isdigit(c)){ - number[nt++]=c; - c=getchar(); - if(c==';'){ fprintf(stderr,"unexpected ;!\n"); exit(1); } - tptype[ttp++]=c; - } - number[nt]='\0'; - sscanf(number,"%d",&counter); - } - switch(c){ - case 'd': - if(iflag){ fprintf(stderr,"d cannot appear after i!\n"); exit(1); } - dflag++; - ALLOC1 - sprintf(temp1->line,"#define IISTEP %d\n",counter); - INSERT1 - iistep=counter; - counter=1; - ALLOC2 - sprintf(temp1->line,"for(ii=0;ii<%d;ii+=IISTEP){\n",N); - sprintf(temp2->line,"}\n",N); - LINK2 - ALLOC1 - sprintf(temp1->line,"it=min(ii+IISTEP,%d);\n",N); - LINK1 - break; - case 'e': - if(jflag){ fprintf(stderr,"e cannot appear after j!\n"); exit(1); } - eflag++; - ALLOC1 - sprintf(temp1->line,"#define JJSTEP %d\n",counter); - INSERT1 - jjstep=counter; - counter=1; - ALLOC2 - sprintf(temp1->line,"for(jj=0;jj<%d;jj+=JJSTEP){\n",N); - sprintf(temp2->line,"}\n",N); - LINK2 - ALLOC1 - sprintf(temp1->line,"jt=min(jj+JJSTEP,%d);\n",N); - LINK1 - break; - case 'i': - iunroll=counter; - counter=1; - iflag++; if(jflag) jiflag++; - if(dflag) precond=iistep%iunroll; else precond=N%iunroll; - if(precond&&(jiflag==0)){ - fprintf(stderr,"unrolling factor for outer loop i\n"); - fprintf(stderr," does not evenly divide matrix/step size!\n"); - exit(1); - } - if(dflag&&(iunroll>1)&&(N%iistep)){ - fprintf(stderr,"with unrolling of i, step size for tiled loop ii\n"); - fprintf(stderr," does not evenly divide matrix size!\n"); - exit(1); - } - processloop('i',dflag,iunroll,precond,junroll); - break; - case 'j': - junroll=counter; - counter=1; - jflag++; if(iflag) ijflag++; - if(eflag) precond=jjstep%junroll; else precond=N%junroll; - if(precond&&(ijflag==0)){ - fprintf(stderr,"unrolling factor for outer loop j\n"); - fprintf(stderr," does not evenly divide matrix/step size!\n"); - exit(1); - } - if(eflag&&(junroll>1)&&(N%jjstep)){ - fprintf(stderr,"with unrolling of j, step size for tiled loop jj\n"); - fprintf(stderr," does not evenly divide matrix size!\n"); - exit(1); - } - processloop('j',eflag,junroll,precond,iunroll); - break; - default: break; - } - } - processstmt(); - - tptype[ttp++]=c; - - if((iflag==0)||(jflag==0)){ - fprintf(stderr, - "one of the loops (i,j) was not specified!\n"); - exit(1); - } - - temp1=start; - while(temp1!=NULL){ - printf("%s",temp1->line); - temp1=temp1->next; - } - printf("#include <stdio.h>\n"); - printf("#include <sys/time.h>\n"); - printf("#include <sys/resource.h>\n"); - if(dflag|eflag) printf("#define min(a,b) ((a)<=(b)?(a):(b))\n"); - printf("double second();\n"); - printf("double t_start,t_end,t_total;\n"); - printf("int times;\n"); - printf("\ndouble b[%d][%d],dummy[10000],bt[%d][%d];\n\nmain(){\n" - ,N,N,N,N); - if(precond) printf(" int i,j,n;\n"); else printf(" int i,j;\n"); - if(dflag) printf(" int ii,it;\n"); - if(eflag) printf(" int jj,jt;\n"); - printf("/* set coefficients so that result matrix should have \n"); - printf(" * column entries equal to column index\n"); - printf(" */\n"); - printf(" for (i=0;i<%d;i++){\n",N); - printf(" for (j=0;j<%d;j++){\n",N); - printf(" b[i][j] = (double) i;\n"); - printf(" }\n"); - printf(" }\n"); - printf("\n t_total=0.0;\n for(times=0;times<10;times++){\n\n",N); - printf("/* try to flush cache */\n"); - printf(" for(i=0;i<10000;i++){\n",N); - printf(" dummy[i] = 0.0;\n"); - printf(" }\n"); - printf("%s",head->line); - temp1=head->next; - while(temp1!=NULL){ - for(i=0;i<temp1->indentcnt;i++) printf(" "); - while((p0=strstr(temp1->line,"+0"))!=NULL){ - *p0++=' '; *p0=' '; - } - printf("%s",temp1->line); - temp1=temp1->next; - } - printf("\n t_total+=t_end-t_start;\n }\n"); - printf("/* check result */\n"); - printf(" for (j=0;j<%d;j++){\n",N); - printf(" for (i=0;i<%d;i++){\n",N); - printf(" if (bt[i][j]!=((double)j)){\n"); - printf(" fprintf(stderr,\"error in bt[%cd][%cd]",'%','%'); - printf("\\n\",i,j);\n"); - printf(" fprintf(stderr,\" for %s\\n\");\n",tptype); - printf(" exit(1);\n"); - printf(" }\n"); - printf(" }\n"); - printf(" }\n"); - tptype[ttp]='\0'; - printf(" printf(\"%c10.2f secs\",t_total);\n",'%'); - printf(" printf(\" for 10 runs of %s\\n\");\n",tptype); - printf("}\n"); - printf("double second(){\n"); - printf(" void getrusage();\n"); - printf(" struct rusage ru;\n"); - printf(" double t;\n"); - printf(" getrusage(RUSAGE_SELF,&ru);\n"); - printf(" t = ((double)ru.ru_utime.tv_sec) +\n"); - printf(" ((double)ru.ru_utime.tv_usec)/1.0e6;\n"); - printf(" return t;\n"); - printf("}\n"); - -} - -void processloop(index,flag,unroll,precond,unroll2) -char index; -int flag,unroll,precond,unroll2; -{ - char build[80],temp[40]; - int n; - if(precond){ - ALLOC1 - sprintf(temp1->line,"/* preconditioning loop for unrolling factor */\n"); - LINK1 - if(unroll2==1){ - build[0]='\0'; - if(flag){ - if(index='i') - sprintf(temp,"n=IISTEP%c%d; ",'%',unroll); - else - sprintf(temp,"n=JJSTEP%c%d; ",'%',unroll); - strcat(build,temp); - sprintf(temp,"for(%c=%c%c;%c<%c%c+n;%c++) ",index,index,index, - index,index,index,index); - strcat(build,temp); - }else{ - sprintf(temp,"n=%d%c%d; ",N,'%',unroll); - strcat(build,temp); - sprintf(temp,"for(%c=0;%c<n;%c++) ",index,index,index); - strcat(build,temp); - } - sprintf(temp,"bt[i][j]=b[j][i];\n"); - strcat(build,temp); - ALLOC1 - sprintf(temp1->line,"%s\n",build); - LINK1 - }else{ - if(flag){ - ALLOC1 - if(index=='i') - sprintf(temp1->line,"n=IISTEP%c%d;\n",'%',unroll); - else - sprintf(temp1->line,"n=JJSTEP%c%d;\n",'%',unroll); - LINK1 - ALLOC1 - sprintf(temp1->line,"for(%c=%c%c;%c<%c%c+n;%c++){\n",index,index,index, - index,index,index,index); - LINK1 - }else{ - ALLOC1 - sprintf(temp1->line,"n=%d%c%d;\n",N,'%',unroll); - LINK1 - ALLOC1 - sprintf(temp1->line,"for(%c=0;%c<n;%c++){\n",index,index,index); - LINK1 - } - if(index=='i'){ - for(n=0;n<unroll2;n++){ - ALLOC1 - sprintf(temp1->line," bt[i][j+%d]=b[j+%d][i];\n",n,n); - LINK1 - } - }else{ - for(n=0;n<unroll2;n++){ - ALLOC1 - sprintf(temp1->line," bt[i+%d][j]=b[j][i+%d];\n",n,n); - LINK1 - } - } - ALLOC1 - sprintf(temp1->line,"}\n"); - LINK1 - } - ALLOC2 - if(flag){ - sprintf(temp1->line,"for(%c=%c%c+n;%c<%ct;%c+=%d){\n",index,index,index, - index,index,index,unroll); - }else{ - sprintf(temp1->line,"for(%c=n;%c<%d;%c+=%d){\n",index,index,N,index, - unroll); - } - sprintf(temp2->line,"}\n",N); - LINK2 - }else{ - ALLOC2 - if(unroll==1){ - if(flag){ - sprintf(temp1->line,"for(%c=%c%c;%c<%ct;%c++){\n",index,index,index, - index,index,index); - }else{ - sprintf(temp1->line,"for(%c=0;%c<%d;%c++){\n",index,index,N,index); - } - }else{ - if(flag){ - sprintf(temp1->line,"for(%c=%c%c;%c<%ct;%c+=%d){\n",index,index,index, - index,index,index,unroll); - }else{ - sprintf(temp1->line,"for(%c=0;%c<%d;%c+=%d){\n",index,index,N,index, - unroll); - } - } - sprintf(temp2->line,"}\n",N); - LINK2 - } -} - -void processstmt() -{ - int i,j; - for(i=0;i<iunroll;i++){ - for(j=0;j<junroll;j++){ - ALLOC1 - sprintf(temp1->line,"bt[i+%d][j+%d]=b[j+%d][i+%d];\n",i,j,j,i); - LINK1 - } - } -} --- -Mark Smotherman, Computer Science Dept., Clemson University, Clemson, SC - -======================================================================= -From: has (h.genceli@bre.com) - Subject: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -If I have a matrix nrows x ncols, I can store it in a vector. -so A(i,j) is really a[i*ncols+j]. So really TRANS of A -(say B) is really is also a vector B where - -0<=i b[j*nrows+i] <nrows, 0<=j<ncols -b[j*nrows+i] = a[i*ncols+j]. - -Fine but I want to use only one array a to do this transformation. - -i.e a[j*nrows+i] = a[i*ncols+j]. this will itself -erase some elements so each time a swap is necessary in a loop. - -temp = a[j*nrows+i] -a[j*nrows+i] = a[i*ncols+j] -a[i*ncols+j] = temp - -but still this will lose some info as it is, so indexing -should have more intelligence in it ???? anybody -can give me a lead here, thanks. - -Has - - From: wei-choon ng (wng@ux8.cso.uiuc.edu) - Subject: Re: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -has <h.genceli@bre.com> wrote: -> If I have a matrix nrows x ncols, I can store it in a vector. -> so A(i,j) is really a[i*ncols+j]. So really TRANS of A -> (say B) is really is also a vector B where - -[snip] - -Hey, if you just want to do a transpose-matrix vector multiply, there is -no need to explicitly store the transpose matrix in another array and -doubling the storage! - -W.C. --- - - From: Robin Becker (robin@jessikat.fsnet.co.uk) - Subject: Re: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -In article <snr532fo3j1180@corp.supernews.com>, has <h.genceli@bre.com> -writes ->If I have a matrix nrows x ncols, I can store it in a vector. ->so A(i,j) is really a[i*ncols+j]. So really TRANS of A ->(say B) is really is also a vector B where -> ->0<=i b[j*nrows+i] <nrows, 0<=j<ncols ->b[j*nrows+i] = a[i*ncols+j]. -> ->Fine but I want to use only one array a to do this transformation. -> ->i.e a[j*nrows+i] = a[i*ncols+j]. this will itself ->erase some elements so each time a swap is necessary in a loop. -> ->temp = a[j*nrows+i] ->a[j*nrows+i] = a[i*ncols+j] ->a[i*ncols+j] = temp -> ->but still this will lose some info as it is, so indexing ->should have more intelligence in it ???? anybody ->can give me a lead here, thanks. -> ->Has -> -> -> - -void dmx_transpose(unsigned n, unsigned m, double* a, double* b) -{ - unsigned size = m*n; - if(b!=a){ - real *bmn, *aij, *anm; - bmn = b + size; /*b+n*m*/ - anm = a + size; - while(b<bmn) for(aij=a++;aij<anm; aij+=n ) *b++ = *aij; - } - else if(size>3){ - unsigned i,row,column,current; - for(i=1, size -= 2;i<size;i++){ - current = i; - do { - /*current = row+n*column*/ - column = current/m; - row = current%m; - current = n*row + column; - } while(current < i); - - if (current >i) { - real temp = a[i]; - a[i] = a[current]; - a[current] = temp; - } - } - } -} --- -Robin Becker - - From: E. Robert Tisdale (edwin@netwood.net) - Subject: Re: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -Take a look at -The C++ Scalar, Vector, Matrix and Tensor class library - - http://www.netwood.net/~edwin/svmt/ - -<Type><System>SubVector& - <Type><System>SubVector::transpose(Extent p, Extent q) { - <Type><System>SubVector& - v = *this; - if (1 < p && 1 < q) { - // A vector v of extent n = qp is viewed as a q by p matrix U and - // a p by q matrix V where U_{ij} = v_{p*i+j} and V_{ij} = v_{q*i+j}. - // The vector v is modified in-place so that V is the transpose of U. - // The algorithm searches for every sequence k_s of S indices - // such that a circular shift of elements v_{k_s} <-- v_{k_{s+1}} - // and v_{k_{S-1}} <-- v_{k_0} effects an in-place transpose. - Extent n = q*p; - Extent m = 0; // count up to n-2 - Offset l = 0; // 1 <= l <= n-2 - while (++l < n-1 && m < n-2) { - Offset k = l; - Offset j = k; - while (l < (k = (j%p)*q + j/p)) { // Search backward for k < l. - j = k; - } - // If a sequence of indices beginning with l has any index k < l, - // it has already been transposed. The sequence length S = 1 - // and diagonal element v_k is its own transpose if k = j. - // Skip every index sequence that has already been transposed. - if (k == l) { // a new sequence - if (k < j) { // with 1 < S - TYPE x = v[k]; // save v_{k_0} - do { - v[k] = v[j]; // v_{k_{s}} <-- v_{k_{s+1}} - k = j; - ++m; - } while (l < (j = (k%q)*p + k/q)); - v[k] = x; // v_{k_{S-1}} <-- v_{k_0} - } - ++m; - } - } - } return v; - } - - - -<Type><System>SubVector& - -Read the rest of this message... (50 more lines) - - From: Victor Eijkhout (eijkhout@disco.cs.utk.edu) - Subject: Re: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -"Alan Miller" <amiller @ vic.bigpond.net.au> writes: - -> The attached routine does an in situ transpose. -> begin 666 Dtip.f90 -> M4U5"4D]55$E.12!D=&EP("AA+"!N,2P@;C(L(&YD:6TI#0HA("TM+2TM+2TM - -Hm. F90? You're not silently allocating a temporary I hope? - -(Why did you have to encode this? Now I have to save, this decode, ... -and all for plain ascii?) - --- -Victor Eijkhout -"When I was coming up, [..] we knew exactly who the they were. It was us -versus them, and it was clear who the them was were. Today, we are not -so sure who the they are, but we know they're there." [G.W. Bush] - - From: Alan Miller (amiller_@_vic.bigpond.net.au) - Subject: Re: transpose of a nxm matrix stored in a vector !!! - Newsgroups: sci.math.num-analysis - Date: 2000/07/25 - - -Victor Eijkhout wrote in message ... ->"Alan Miller" <amiller @ vic.bigpond.net.au> writes: -> ->> The attached routine does an in situ transpose. ->> begin 666 Dtip.f90 ->> M4U5"4D]55$E.12!D=&EP("AA+"!N,2P@;C(L(&YD:6TI#0HA("TM+2TM+2TM -> ->Hm. F90? You're not silently allocating a temporary I hope? -> ->(Why did you have to encode this? Now I have to save, this decode, ... ->and all for plain ascii?) -> - -I know the problem. -I sometimes use a Unix system, and have to use decode64 to read -attachments. On the other hand, Windows wraps lines around, -formats then and generally makes the code unreadable. - -The straight code for dtip (double transpose in place) is attached -this time. - ->-- ->Victor Eijkhout - - --- -Alan Miller, Retired Scientist (Statistician) -CSIRO Mathematical & Information Sciences -Alan.Miller -at- vic.cmis.csiro.au -http://www.ozemail.com.au/~milleraj -http://users.bigpond.net.au/amiller/ - - -================================================================= - -From: Darran Edmundson (dedmunds@sfu.ca) - Subject: array reordering algorithm? - Newsgroups: sci.math.num-analysis - Date: 1995/04/30 - - -A code I've written refers to a complex array as two separate real arrays. -However, I have a canned subroutine which expects a single array where the -real and imaginary values alternate. Essentially I have a case of mismatched -data structures, yet for reasons that I'd rather not go into, I'm stuck with them. - -Assuming that the two real arrays A and B are sequential in memory, and -that the single array of alternating real/imaginary values C shares the same -space, what I need is a porting subroutine that remaps the data from one format -to the other - using as little space as possible. - -I think of the problem as follows. Imagine an array of dimension 10 containing -the values 1,3,5,7,9,2,4,6,8,10 in this order. - - A(1) / 1 \ C(1) - A(2) | 3 | C(2) - A(3) | 5 | C(3) - A(4) | 7 | C(4) - A(5) \ 9 | C(5) - | - B(1) / 2 | C(6) - B(2) | 4 | C(7) - B(3) | 6 | C(8) - B(4) | 8 | C(9) - B(5) \ 10 / C(10) - -Given that I know this initial pattern, I want to sort the array C in-place *without -making comparisons*. That is, the algorithm can only depend on the initial -knowledge of the pattern. Do you see what a sort is going to do? It will -make the A and B arrays alternate, i.e. C(1)=A(1), C(2)=B(1), C(3)=A(2), -C(4)=B(2), etc. It's not a real sort though because I can't actually refer to the -values above (i.e. no comparisons) because A and B will be holding real data, -not this contrived pattern. The pattern above exists though - it's the -natural ordering in memory of A and B. - -Either pair swapping only or a small amount of workspace can be used. The -in-place is important - imagine scaling this problem up to an -array of 32 or 64 million double precision values and you can easily see how -duplicating the array is not a feasible solution. - -Any ideas? I've been stumped on this for a day and a half now. - -Darran Edmundson -dedmunds@sfu.ca - - From: Roger Critchlow (rec@elf115.elf.org) - Subject: Re: array reordering algorithm? - Newsgroups: sci.math.num-analysis - Date: 1995/04/30 - - - Any ideas? I've been stumped on this for a day and a half now. - -Here's some code for in situ permutations of arrays that I wrote -a few years ago. It all started from the in situ transposition -algorithms in the Collected Algorithms of the ACM, the references -for which always get lost during the decryption from fortran. - -This is the minimum space algorithm. All you need to supply is -a function which computes the new order array index from the old -order array index. - -If you can spare n*m bits to record the indexes of elements which -have been permuted, then you can speed things up. - --- rec -- - ------------------------------------------------------------------------- -/* -** Arbitrary in situ permutations of an m by n array of base type TYPE. -** Copyright 1995 by Roger E Critchlow Jr, rec@elf.org, San Francisco, CA. -** Fair use permitted, caveat emptor. -*/ -typedef int TYPE; - -int transposition(int ij, int m, int n) /* transposition about diagonal from upper left to lower right */ -{ return ((ij%m)*n+ (ij/m)); } - -int countertrans(int ij, int m, int n) /* transposition about diagonal from upper right to lower left */ -{ return ((m-1-(ij%m))*n+ (n-1-(ij/m))); } - -int rotate90cw(int ij, int m, int n) /* 90 degree clockwise rotation */ -{ return ((m-1-(ij%m))*n+ (ij/m)); } - -int rotate90ccw(int ij, int m, int n) /* 90 degree counter clockwise rotation */ -{ return ((ij%m)*n+ (n-1-(ij/m))); } - -int rotate180(int ij, int m, int n) /* 180 degree rotation */ -{ return ((m-1-(ij/n))*n+ (n-1-(ij%n))); } - -int reflecth(int ij, int m, int n) /* reflection across horizontal plane */ -{ return ((m-1-(ij/n))*n+ (ij%n)); } - -int reflectv(int ij, int m, int n) /* reflection across vertical plane */ -{ return ((ij/n)*n+ (n-1-(ij%n))); } - -int in_situ_permutation(TYPE a[], int m, int n, int (*origination)(int ij, int m, int n)) -{ - int ij, oij, dij, n_to_do; - TYPE b; - n_to_do = m*n; - for (ij = 0; ij < m*n && n_to_do > 0; ij += 1) { - /* Test for previously permuted */ - for (oij = origination(ij,m,n); oij > ij; oij = origination(oij,m,n)) - ; - if (oij < ij) - continue; - /* Chase the cycle */ - dij = ij; - b = a[ij]; - for (oij = origination(dij,m,n); oij != ij; oij = origination(dij,m,n)) { - a[dij] = a[oij]; - dij = oij; - n_to_do -= 1; - } - a[dij] = b; - n_to_do -= 1; - } return 0; -} - -#define TESTING 1 -#if TESTING - -/* fill a matrix with sequential numbers, row major ordering */ -void fill_matrix_rows(a, m, n) TYPE *a; int m, n; -{ - int i, j; - for (i = 0; i < m; i += 1) - for (j = 0; j < n; j += 1) - a[i*n+j] = i*n+j; -} - -/* fill a matrix with sequential numbers, column major ordering */ -void fill_matrix_cols(a, m, n) TYPE *a; int m, n; -{ - int i, j; - for (i = 0; i < m; i += 1) - for (j = 0; j < n; j += 1) - a[i*n+j] = j*m+i; -} - -/* test a matrix for sequential numbers, row major ordering */ -int test_matrix_rows(a, m, n) TYPE *a; int m, n; -{ - int i, j, o; - for (o = i = 0; i < m; i += 1) - for (j = 0; j < n; j += 1) - o += a[i*n+j] != i*n+j; - return o; -} - -/* test a matrix for sequential numbers, column major ordering */ -int test_matrix_cols(a, m, n) TYPE *a; int m, n; -{ - int i, j, o; - for (o = i = 0; i < m; i += 1) - for (j = 0; j < n; j += 1) - o += a[i*n+j] != j*m+i; - return o; -} - -/* print a matrix */ -void print_matrix(a, m, n) TYPE *a; int m, n; -{ - char *format; - int i, j; - if (m*n < 10) format = "%2d"; - if (m*n < 100) format = "%3d"; - if (m*n < 1000) format = "%4d"; - if (m*n < 10000) format = "%5d"; - for (i = 0; i < m; i += 1) { - for (j = 0; j < n; j += 1) - printf(format, a[i*n+j]); - printf("\n"); - } -} - -#if TEST_TRANSPOSE -#define MAXSIZE 1000 - -main() -{ - int i, j, m, n, o; - TYPE a[MAXSIZE]; - for (m = 1; m < sizeof(a)/sizeof(a[0]); m += 1) - for (n = 1; m*n < sizeof(a)/sizeof(a[0]); n += 1) { - fill_matrix_rows(a, m, n); /* {0 1} {2 3} */ - if (o = transpose(a, m, n)) - printf(">> transpose returned %d for a[%d][%d], row major\n", o, m, n); - if ((o = test_matrix_cols(a, n, m)) != 0) /* {0 2} {1 3} */ - printf(">> transpose made %d mistakes for a[%d][%d], row major\n", o, m, n); - /* column major */ - fill_matrix_rows(a, m, n); - if (o = transpose(a, m, n)) - printf(">> transpose returned %d for a[%d][%d], column major\n", o, m, n); - if ((o = test_matrix_cols(a, n, m)) != 0) - printf(">> transpose made %d mistakes for a[%d][%d], column major\n", o, m, n); - } return 0; -} -#endif /* TEST_TRANSPOSE */ - - -#define TEST_DISPLAY 1 -#if TEST_DISPLAY -main(argc, argv) int argc; char *argv[]; -{ - TYPE *a; - int m = 5, n = 5; - extern void *malloc(); - if (argc > 1) { - m = atoi(argv[1]); - if (argc > 2) - n = atoi(argv[2]); - } - a = malloc(m*n*sizeof(TYPE)); - - printf("matrix\n"); - fill_matrix_rows(a, m, n); - print_matrix(a, m, n); - printf("transposition\n"); - in_situ_permutation(a, m, n, transposition); - print_matrix(a, n, m); - - printf("counter transposition\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, countertrans); - print_matrix(a, n, m); - - printf("rotate 90 degrees clockwise\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, rotate90cw); - print_matrix(a, n, m); - - printf("rotate 90 degrees counterclockwise\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, rotate90ccw); - print_matrix(a, n, m); - - printf("rotate 180 degrees\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, rotate180); - print_matrix(a, m, n); - - printf("reflect across horizontal\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, reflecth); - print_matrix(a, m, n); - - printf("reflect across vertical\n"); - fill_matrix_rows(a, m, n); - in_situ_permutation(a, m, n, reflectv); - print_matrix(a, m, n); - - return 0; -} - -#endif -#endif - diff --git a/numpy/f2py/doc/multiarrays.txt b/numpy/f2py/doc/multiarrays.txt deleted file mode 100644 index 704208976..000000000 --- a/numpy/f2py/doc/multiarrays.txt +++ /dev/null @@ -1,120 +0,0 @@ -From pearu@ioc.ee Thu Dec 30 09:58:01 1999 -Date: Fri, 26 Nov 1999 12:02:42 +0200 (EET) -From: Pearu Peterson <pearu@ioc.ee> -To: Users of f2py2e -- Curtis Jensen <cjensen@be-research.ucsd.edu>, - Vladimir Janku <vjanku@kvet.sk>, - Travis Oliphant <Oliphant.Travis@mayo.edu> -Subject: Multidimensional arrays in f2py2e - - -Hi! - -Below I will describe how f2py2e wraps Fortran multidimensional arrays as -it constantly causes confusion. As for example, consider Fortran code - - subroutine foo(l,m,n,a) - integer l,m,n - real*8 a(l,m,n) - .. - end -Running f2py2e with -h flag, it generates the following signature - -subroutine foo(l,m,n,a) - integer optional,check(shape(a,2)==l),depend(a) :: l=shape(a,2) - integer optional,check(shape(a,1)==m),depend(a) :: m=shape(a,1) - integer optional,check(shape(a,0)==n),depend(a) :: n=shape(a,0) - real*8 dimension(l,m,n),check(rank(a)==3) :: a -end subroutine foo - -where parameters l,m,n are considered optional and they are initialized in -Python C/API code using the array a. Note that a can be also a proper -list, that is, asarray(a) should result in a rank-3 array. But then there -is an automatic restriction that elements of a (in Python) are not -changeable (in place) even if Fortran subroutine changes the array a (in -C,Fortran). - -Hint: you can attribute the array a with 'intent(out)' which causes foo to -return the array a (in Python) if you are to lazy to define a=asarray(a) -before the call to foo (in Python). - -Calling f2py2e without the switch -h, a Python C/API module will be -generated. After compiling it and importing it to Python ->>> print foo.__doc__ -shows -None = foo(a,l=shape(a,2),m=shape(a,1),n=shape(a,0)) - -You will notice that f2py2e has changed the order of arguments putting the -optional ones at the end of the argument list. -Now, you have to be careful when specifying the parameters l,m,n (though -situations where you need this should be rare). A proper definition -of the array a should be, say - - a = zeros(n,m,l) - -Note that the dimensions l,m,n are in reverse, that is, the array a should -be transposed when feeding it to the wrapper. - -Hint (and a performance hit): To be always consistent with fortran -arrays, you can define, for example - a = zeros(l,m,n) -and call from Python - foo(transpose(a),l,m,n) -which is equivalent with the given Fortran call - call foo(l,m,n,a) - -Another hint (not recommended, though): If you don't like optional -arguments feature at all and want to be strictly consistent with Fortran -signature, that is, you want to call foo from Python as - foo(l,m,n,a) -then you should edit the signature to -subroutine foo(l,m,n,a) - integer :: l - integer :: m - integer :: n - real*8 dimension(l,m,n),check(rank(a)==3),depend(l,m,n), & - check(shape(a,2)==l,shape(a,1)==m,shape(a,0)==n):: a -end -Important! Note that now the array a should depend on l,m,n -so that the checks can be performed in the proper order. -(you cannot check, say, shape(a,2)==l before initializing a or l) -(There are other ways to edit the signature in order to get the same -effect but they are not so safe and I will not discuss about them here). - -Hint: If the array a should be a work array (as used frequently in -Fortran) and you a too lazy (its good lazyness;) to provide it (in Python) -then you can define it as optional by ediding the signature: -subroutine foo(l,m,n,a) - integer :: l - integer :: m - integer :: n - real*8 dimension(l,m,n),check(rank(a)==3),depend(l,m,n), & - check(shape(a,2)==l,shape(a,1)==m,shape(a,0)==n):: a - optional a -end -Note again that the array a must depend on l,m,n. Then the array a will be -allocated in the Python C/API module. Not also that ->>> print foo.__doc__ -shows then -None = foo(l,m,n,a=) -Performance hint: If you call the given foo lots of times from Python then -you don't want to allocate/deallocate the memory in each call. So, it is -then recommended to define a temporary array in Python, for instance ->>> tmp = zeros(n,m,l) ->>> for i in ...: ->>> foo(l,m,n,a=tmp) - -Important! It is not good at all to define - >>> tmp = transpose(zeros(l,m,n)) -because tmp will be then a noncontiguous array and there will be a -huge performance hit as in Python C/API a new array will be allocated and -also a copying of arrays will be performed elementwise! -But - >>> tmp = asarray(transpose(zeros(l,m,n))) -is still ok. - -I hope that the above answers lots of your (possible) questions about -wrapping Fortran multidimensional arrays with f2py2e. - -Regards, - Pearu - diff --git a/numpy/f2py/doc/notes.tex b/numpy/f2py/doc/notes.tex deleted file mode 100644 index 2746b049d..000000000 --- a/numpy/f2py/doc/notes.tex +++ /dev/null @@ -1,310 +0,0 @@ - -\section{Calling wrapper functions from Python} -\label{sec:notes} - -\subsection{Scalar arguments} -\label{sec:scalars} - -In general, for scalar argument you can pass in in -addition to ordinary Python scalars (like integers, floats, complex -values) also arbitrary sequence objects (lists, arrays, strings) --- -then the first element of a sequence is passed in to the Fortran routine. - -It is recommended that you always pass in scalars of required type. This -ensures the correctness as no type-casting is needed. -However, no exception is raised if type-casting would produce -inaccurate or incorrect results! For example, in place of an expected -complex value you can give an integer, or vice-versa (in the latter case only -a rounded real part of the complex value will be used). - -If the argument is \texttt{intent(inout)} then Fortran routine can change the -value ``in place'' only if you pass in a sequence object, for -instance, rank-0 array. Also make sure that the type of an array is of -correct type. Otherwise type-casting will be performed and you may -get inaccurate or incorrect results. The following example illustrates this -\begin{verbatim} ->>> a = array(0) ->>> calculate_pi(a) ->>> print a -3 -\end{verbatim} - -If you pass in an ordinary Python scalar in place of -\texttt{intent(inout)} variable, it will be used as an input argument -since -Python -scalars cannot not be changed ``in place'' (all Python scalars -are immutable objects). - -\subsection{String arguments} -\label{sec:strings} - -You can pass in strings of arbitrary length. If the length is greater than -required, only a required part of the string is used. If the length -is smaller than required, additional memory is allocated and fulfilled -with `\texttt{\bs0}'s. - -Because Python strings are immutable, \texttt{intent(inout)} argument -expects an array version of a string --- an array of chars: -\texttt{array("<string>")}. -Otherwise, the change ``in place'' has no effect. - - -\subsection{Array arguments} -\label{sec:arrays} - -If the size of an array is relatively large, it is \emph{highly - recommended} that you pass in arrays of required type. Otherwise, -type-casting will be performed which includes the creation of new -arrays and their copying. If the argument is also -\texttt{intent(inout)}, the wasted time is doubled. So, pass in arrays -of required type! - -On the other hand, there are situations where it is perfectly all -right to ignore this recommendation: if the size of an array is -relatively small or the actual time spent in Fortran routine takes -much longer than copying an array. Anyway, if you want to optimize -your Python code, start using arrays of required types. - -Another source of performance hit is when you use non-contiguous -arrays. The performance hit will be exactly the same as when using -incorrect array types. This is because a contiguous copy is created -to be passed in to the Fortran routine. - -\fpy provides a feature such that the ranks of array arguments need -not to match --- only the correct total size matters. For example, if -the wrapper function expects a rank-1 array \texttt{array([...])}, -then it is correct to pass in rank-2 (or higher) arrays -\texttt{array([[...],...,[...]])} assuming that the sizes will match. -This is especially useful when the arrays should contain only one -element (size is 1). Then you can pass in arrays \texttt{array(0)}, -\texttt{array([0])}, \texttt{array([[0]])}, etc and all cases are -handled correctly. In this case it is correct to pass in a Python -scalar in place of an array (but then ``change in place'' is ignored, -of course). - -\subsubsection{Multidimensional arrays} - -If you are using rank-2 or higher rank arrays, you must always -remember that indexing in Fortran starts from the lowest dimension -while in Python (and in C) the indexing starts from the highest -dimension (though some compilers have switches to change this). As a -result, if you pass in a 2-dimensional array then the Fortran routine -sees it as the transposed version of the array (in multi-dimensional -case the indexes are reversed). - -You must take this matter into account also when modifying the -signature file and interpreting the generated Python signatures: - -\begin{itemize} -\item First, when initializing an array using \texttt{init\_expr}, the index -vector \texttt{\_i[]} changes accordingly to Fortran convention. -\item Second, the result of CPP-macro \texttt{shape(<array>,0)} - corresponds to the last dimension of the Fortran array, etc. -\end{itemize} -Let me illustrate this with the following example:\\ -\begin{verbatim} -! Fortran file: arr.f - subroutine arr(l,m,n,a) - integer l,m,n - real*8 a(l,m,n) - ... - end -\end{verbatim} -\fpy will generate the following signature file:\\ -\begin{verbatim} -!%f90 -! Signature file: arr.f90 -python module arr ! in - interface ! in :arr - subroutine arr(l,m,n,a) ! in :arr:arr.f - integer optional,check(shape(a,2)==l),depend(a) :: l=shape(a,2) - integer optional,check(shape(a,1)==m),depend(a) :: m=shape(a,1) - integer optional,check(shape(a,0)==n),depend(a) :: n=shape(a,0) - real*8 dimension(l,m,n) :: a - end subroutine arr - end interface -end python module arr -\end{verbatim} -and the following wrapper function will be produced -\begin{verbatim} -None = arr(a,l=shape(a,2),m=shape(a,1),n=shape(a,0)) -\end{verbatim} - -In general, I would suggest not to specify the given optional -variables \texttt{l,m,n} when calling the wrapper function --- let the -interface find the values of the variables \texttt{l,m,n}. But there -are occasions when you need to specify the dimensions in Python. - -So, in Python a proper way to create an array from the given -dimensions is -\begin{verbatim} ->>> a = zeros(n,m,l,'d') -\end{verbatim} -(note that the dimensions are reversed and correct type is specified), -and then a complete call to \texttt{arr} is -\begin{verbatim} ->>> arr(a,l,m,n) -\end{verbatim} - -From the performance point of view, always be consistent with Fortran -indexing convention, that is, use transposed arrays. But if you do the -following -\begin{verbatim} ->>> a = transpose(zeros(l,m,n,'d')) ->>> arr(a) -\end{verbatim} -then you will get a performance hit! The reason is that here the -transposition is not actually performed. Instead, the array \texttt{a} -will be non-contiguous which means that before calling a Fortran -routine, internally a contiguous array is created which -includes memory allocation and copying. In addition, if -the argument array is also \texttt{intent(inout)}, the results are -copied back to the initial array which doubles the -performance hit! - -So, to improve the performance: always pass in -arrays that are contiguous. - -\subsubsection{Work arrays} - -Often Fortran routines use the so-called work arrays. The -corresponding arguments can be declared as optional arguments, but be -sure that all dimensions are specified (bounded) and defined before -the initialization (dependence relations). - -On the other hand, if you call the Fortran routine many times then you -don't want to allocate/deallocate the memory of the work arrays on -every call. In this case it is recommended that you create temporary -arrays with proper sizes in Python and use them as work arrays. But be -careful when specifying the required type and be sure that the -temporary arrays are contiguous. Otherwise the performance hit would -be even harder than the hit when not using the temporary arrays from -Python! - - - -\subsection{Call-back arguments} -\label{sec:cbargs} - -\fpy builds a very flexible call-back mechanisms for call-back -arguments. If the wrapper function expects a call-back function \texttt{fun} -with the following Python signature to be passed in -\begin{verbatim} -def fun(a_1,...,a_n): - ... - return x_1,...,x_k -\end{verbatim} -but the user passes in a function \texttt{gun} with the signature -\begin{verbatim} -def gun(b_1,...,b_m): - ... - return y_1,...,y_l -\end{verbatim} -and the following extra arguments (specified as additional optional -argument for the wrapper function): -\begin{verbatim} -fun_extra_args = (e_1,...,e_p) -\end{verbatim} -then the actual call-back is constructed accordingly to the following rules: -\begin{itemize} -\item if \texttt{p==0} then \texttt{gun(a\_1,...,a\_q)}, where - \texttt{q=min(m,n)}; -\item if \texttt{n+p<=m} then \texttt{gun(a\_1,...,a\_n,e\_1,...,e\_p)}; -\item if \texttt{p<=m<n+p} then \texttt{gun(a\_1,...,a\_q,e\_1,...,e\_p)}, - where \texttt{q=m-p}; -\item if \texttt{p>m} then \texttt{gun(e\_1,...,e\_m)}; -\item if \texttt{n+p} is less than the number of required arguments - of the function \texttt{gun}, an exception is raised. -\end{itemize} - -A call-back function \texttt{gun} may return any number of objects as a tuple: -if \texttt{k<l}, then objects \texttt{y\_k+1,...,y\_l} are ignored; -if \texttt{k>l}, then only objects \texttt{x\_1,...,x\_l} are set. - - -\subsection{Obtaining information on wrapper functions} -\label{sec:info} - -From the previous sections we learned that it is useful for the -performance to pass in arguments of expected type, if possible. To -know what are the expected types, \fpy generates a complete -documentation strings for all wrapper functions. You can read them -from Python by printing out \texttt{\_\_doc\_\_} attributes of the -wrapper functions. For the example in Sec.~\ref{sec:intro}: -\begin{verbatim} ->>> print foobar.foo.__doc__ -Function signature: - foo(a) -Required arguments: - a : in/output rank-0 array(int,'i') ->>> print foobar.bar.__doc__ -Function signature: - bar = bar(a,b) -Required arguments: - a : input int - b : input int -Return objects: - bar : int -\end{verbatim} - -In addition, \fpy generates a LaTeX document -(\texttt{<modulename>module.tex}) containing a bit more information on -the wrapper functions. See for example Appendix that contains a result -of the documentation generation for the example module -\texttt{foobar}. Here the file \texttt{foobar-smart.f90} (modified -version of \texttt{foobar.f90}) is used --- it contains -\texttt{note(<LaTeX text>)} attributes for specifying some additional -information. - -\subsection{Wrappers for common blocks} -\label{sec:wrapcomblock} - -[See examples \texttt{test-site/e/runme*}] - -What follows is obsolute for \fpy version higher that 2.264. - -\fpy generates wrapper functions for common blocks. For every common -block with a name \texttt{<commonname>} a function -\texttt{get\_<commonname>()} is constructed that takes no arguments -and returns a dictionary. The dictionary represents maps between the -names of common block fields and the arrays containing the common -block fields (multi-dimensional arrays are transposed). So, in order -to access to the common block fields, you must first obtain the -references -\begin{verbatim} -commonblock = get_<commonname>() -\end{verbatim} -and then the fields are available through the arrays -\texttt{commonblock["<fieldname>"]}. -To change the values of common block fields, you can use for scalars -\begin{verbatim} -commonblock["<fieldname>"][0] = <new value> -\end{verbatim} -and for arrays -\begin{verbatim} -commonblock["<fieldname>"][:] = <new array> -\end{verbatim} -for example. - -For more information on the particular common block wrapping, see -\texttt{get\_<commonname>.\_\_doc\_\_}. - -\subsection{Wrappers for F90/95 module data and routines} -\label{sec:wrapf90modules} - -[See example \texttt{test-site/mod/runme\_mod}] - -\subsection{Examples} -\label{sec:examples} - -Examples on various aspects of wrapping Fortran routines to Python can -be found in directories \texttt{test-site/d/} and -\texttt{test-site/e/}: study the shell scripts \texttt{runme\_*}. See -also files in \texttt{doc/ex1/}. - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: diff --git a/numpy/f2py/doc/oldnews.html b/numpy/f2py/doc/oldnews.html deleted file mode 100644 index 0e09c032f..000000000 --- a/numpy/f2py/doc/oldnews.html +++ /dev/null @@ -1,121 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> -<HTML> -<HEAD> -<META name="Author" content="Pearu Peterson"> -<!-- You may add here some keywords (comma separeted list) --> -<META name="Keywords" content="fortran,python,interface,f2py,f2py2e,wrapper,fpig"> -<TITLE>F2PY - Fortran to Python Interface Generator</TITLE> -<LINK rel="stylesheet" type="text/css" href="/styles/userstyle.css"> -</HEAD> - -<body> -<h2><a href="http://cens.ioc.ee/projects/f2py2e">F2PY</a> old news.</h2> - -<dl> - <dt> February 23, 2002 - <dd> Fixed a bug of incorrect shapes of multi-dimensional arrays - when returning from Fortran routine (thanks to Eric for pointing - this out). - <code>F2PY_REPORT_ATEXIT</code> is disabled by default under Win32. - <dt> February 14, 2002 - <dd> Introduced <code>callprotoargument</code> statement so that - proper prototypes can be specified (this fixes SEGFAULTs when - wrapping C functions with <code>f2py</code>, see <a - href="NEWS.txt">NEWS.txt</a> for more details). Updated for the - latest <code>numpy_distutils</code>. Fixed few bugs. - <dt> February 3, 2002 - <dd> Introduced <code>intent(overwrite),intent(out=name)</code> - attributes, <code>callstatement C-expr;</code> statement, and - reviewed reference counting in callback mechanism. Fixed bugs. - <dt> January 18, 2002 - <dd> Introduced extra keyword argument <code>copy_#varname#=1</code> - for <code>intent(copy)</code> variables, - <code>-DF2PY_REPORT_ATEXIT</code> for reporting <code>f2py</code> - performance, - <code>has_column_major_storage</code> member function for generated - modules, and <a href="http://dmalloc.com/">dmalloc</a> support. - <dt> January 16, 2002 - <dd> BREAKING NEWS! Solved long lasted dilemma of wrapping - multi-dimensional arrays where different - storage orders in C and Fortran come into account. From now on - this difference is dealt automatically by the f2py generated - module and in a very efficient way. For example, the corresponding - element A(i,j) of a Fortran array can be accessed in Python as - A[i,j]. - <dt> January 13, 2002 - <dd> Fifth Public Release is coming soon..., a snapshot is available - for download, now with updates. - <dt> December 17, 2001 - <dd> <a href="Release-4.x.txt">Fourth Public Release</a>: Win32 support. - <dd> Making <code>f2py2e</code> a module. Currently it has only one - member function <code>run_main(comline_list)</code>. - <dd> Removed command line arguments <code>-fix,-f90,-f77</code> - and introduced many new ones. See <a href="NEWS.txt">NEWS.txt</a>. - <dd> <code>intent(..)</code> statement with empty name list defines - default <code>intent(..)</code> attribute for all routine arguments. - <dd> Refinements in Win32 support. Eric Jones has provided a f2py - HOWTO for Windows users. See <a href="win32_notes.txt">win32_notes.txt</a>. - <dd> Major rewrote of the code generator to achieve - a higher quality of generated C/API modules (-Wall messages are - considerably reduced, especially for callback functions). - <dd> Many bugs were fixed. - <dt> December 12, 2001 - <dd> Win32 support (thanks to Eric Jones and Tiffany Kamm). Minor - cleanups and fixes. - <dt> December 4, 2001 - <dd> <a href="Release-3.x.txt">Third Public Release</a>: <code>f2py</code> supports <code>distutils</code>. It can be - installed with one and it generates <code>setup_modulename.py</code> - to be used for building Python extension modules. - <dd> Introduced <code>threadsafe</code>, <code>fortranname</code>, - and <code>intent(c)</code> statements. - <dt> August 13, 2001 - <dd> Changed the name FPIG to F2PY for avoiding confusion with project names. - <dd> Updated <code>f2py</code> for use with Numeric version 20.x. - <dt> January 12, 2001 - <dd> Example usages of <a href="pyfobj.html"><code>PyFortranObject</code></a>. - Fixed bugs. Updated the - <a href="f2python9.html">Python 9 Conference paper</a> (F2PY paper). - <dt> December 9, 2000 - <dd> Implemented support for <code>PARAMETER</code> statement. - <dt> November 6, 2000 - <dd> Submitted a paper for 9th Python Conference (accepted). It is available in <a - href="f2python9.html">html</a>, <a href="f2python9.pdf">PDF</a>, - and <a href="f2python9.ps.gz">Gzipped PS</a> formats. - <dt> September 17, 2000 - <dd> Support for F90/95 module data and routines. COMMON block - wrapping is rewritten. New signature file syntax: - <code>pythonmodule</code>. Signature files generated with - f2py-2.264 or earlier, are incompatible (need replacement - <code>module</code> with - <code>pythonmodule</code>). - <dt> September 12, 2000 - <dd> The second public release of <code>f2py</code> is out. See <a - href="Release-2.x.txt">Release notes</a>. - <dt> September 11, 2000 - <dd> Now <code>f2py</code> supports wrapping Fortran 90/95 module routines - (support for F90/95 module data coming soon) - <dt> June 12, 2000 - <dd> Now <code>f2py</code> has a mailing list <a -href="#f2py-users">f2py-users</a> open for discussion. - -</dl> - - -<!-- End of user text --> -<HR> -<ADDRESS> -<A href="http://validator.w3.org/"><IMG border=0 align=right src="/icons/vh40.gif" alt="Valid HTML 4.0!" height=31 width=88></A> -<A href="http://cens.ioc.ee/~pearu/" target="_top">Pearu Peterson</A> -<A href="mailto:pearu (at) ioc.ee"><pearu(at)ioc.ee></A><BR> -<!-- hhmts start --> -Last modified: Mon Dec 3 19:40:26 EET 2001 -<!-- hhmts end --> -</ADDRESS> -<!-- You may want to comment the following line out when the document is final--> -<!-- Check that the reference is right --> -<!--A href="http://validator.w3.org/check?uri=http://cens.ioc.ee/projects/f2py2e/index.html;ss"> Submit this page for validation</A--> - -</BODY> - - -</HTML> diff --git a/numpy/f2py/doc/options.tex b/numpy/f2py/doc/options.tex deleted file mode 100644 index 84d9410f8..000000000 --- a/numpy/f2py/doc/options.tex +++ /dev/null @@ -1,63 +0,0 @@ - -\section{\fpy command line options} -\label{sec:opts} - -\fpy has the following command line syntax (run \fpy without arguments -to get up to date options!!!): -\begin{verbatim} -f2py [<options>] <fortran files> [[[only:]||[skip:]] <fortran functions> ]\ - [: <fortran files> ...] -\end{verbatim} -where -\begin{description} -\item[\texttt{<options>}] --- the following options are available: - \begin{description} - \item[\texttt{-f77}] --- \texttt{<fortran files>} are in Fortran~77 - fixed format (default). - \item[\texttt{-f90}] --- \texttt{<fortran files>} are in - Fortran~90/95 free format (default for signature files). - \item[\texttt{-fix}] --- \texttt{<fortran files>} are in - Fortran~90/95 fixed format. - \item[\texttt{-h <filename>}] --- after scanning the - \texttt{<fortran files>} write the signatures of Fortran routines - to file \texttt{<filename>} and exit. If \texttt{<filename>} - exists, \fpy quits without overwriting the file. Use - \texttt{-{}-overwrite-signature} to overwrite. - \item[\texttt{-m <modulename>}] --- specify the name of the module - when scanning Fortran~77 codes for the first time. \fpy will - generate Python C/API module source \texttt{<modulename>module.c}. - \item[\texttt{-{}-lower/-{}-no-lower}] --- lower/do not lower the cases - when scanning the \texttt{<fortran files>}. Default when - \texttt{-h} flag is specified/unspecified (that is for Fortran~77 - codes/signature files). - \item[\texttt{-{}-short-latex}] --- use this flag when you want to - include the generated LaTeX document to another LaTeX document. - \item[\texttt{-{}-debug-capi}] --- create a very verbose C/API - code. Useful for debbuging. -% \item[\texttt{-{}-h-force}] --- if \texttt{-h <filename>} is used then -% overwrite the file \texttt{<filename>} (if it exists) and continue -% with constructing the C/API module source. - \item[\texttt{-makefile <options>}] --- run \fpy without arguments - for more information. - \item[\texttt{-{}-use-libs}] --- see \texttt{-makefile}. - \item[\texttt{-{}-overwrite-makefile}] --- overwrite existing - \texttt{Makefile-<modulename>}. - \item[\texttt{-v}] --- print \fpy version number and exit. - \item[\texttt{-pyinc}] --- print Python include path and exit. - \end{description} -\item[\texttt{<fortran files>}] --- are the paths to Fortran files or - to signature files that will be scanned for \texttt{<fortran - functions>} in order to determine their signatures. -\item[\texttt{<fortran functons>}] --- are the names of Fortran - routines for which Python C/API wrapper functions will be generated. - Default is all that are found in \texttt{<fortran files>}. -\item[\texttt{only:}/\texttt{skip:}] --- are flags for filtering - in/out the names of fortran routines to be wrapped. Run \fpy without - arguments for more information about the usage of these flags. -\end{description} - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: diff --git a/numpy/f2py/doc/python9.tex b/numpy/f2py/doc/python9.tex deleted file mode 100644 index cda3cd18b..000000000 --- a/numpy/f2py/doc/python9.tex +++ /dev/null @@ -1,1046 +0,0 @@ -\documentclass[twocolumn]{article}
-\usepackage{epsfig}
-\usepackage{xspace}
-\usepackage{verbatim}
-
-
-\headsep=0pt
-\topmargin=0pt
-\headheight=0pt
-\oddsidemargin=0pt
-\textwidth=6.5in
-\textheight=9in
-%%tth:\newcommand{\xspace}{ }
-\newcommand{\fpy}{\texttt{f2py}\xspace}
-\newcommand{\bs}{\symbol{`\\}}
-% need bs here:
-%%tth:\newcommand{\bs}{\texttt{<backslash>}}
-
-\newcommand{\tthhide}[1]{#1}
-\newcommand{\latexhide}[1]{}
-%%tth:\newcommand{\tthhide}[1]{}
-%%tth:\newcommand{\latexhide}[1]{#1}
-
-\newcommand{\shell}[1]{
-\latexhide{
- \special{html:
-<BLOCKQUOTE>
-<pre>
-sh> #1
-</pre>
-</BLOCKQUOTE>}
-}
-\tthhide{
- \\[1ex]
- \hspace*{1em}
- \texttt{sh> \begin{minipage}[t]{0.8\textwidth}#1\end{minipage}}\\[1ex]
-}
-}
-
-\newcommand{\email}[1]{\special{html:<A href="mailto:#1">}\texttt{<#1>}\special{html:</A>}}
-\newcommand{\wwwsite}[1]{\special{html:<A href="#1">}{#1}\special{html:</A>}}
-\title{Fortran to Python Interface Generator with
-an Application to Aerospace Engineering}
-\author{
-\large Pearu Peterson\\
-\small \email{pearu@cens.ioc.ee}\\
-\small Center of Nonlinear Studies\\
-\small Institute of Cybernetics at TTU\\
-\small Akadeemia Rd 21, 12618 Tallinn, ESTONIA\\[2ex]
-\large Joaquim R. R. A. Martins and Juan J. Alonso\\
-\small \email{joaquim.martins@stanford.edu}, \email{jjalonso@stanford.edu}\\
-\small Department of Aeronautics and Astronautics\\
-\small Stanford University, CA
-}
-\date{$Revision: 1.17 $\\\today}
-\begin{document}
-
-\maketitle
-
-\special{html: Other formats of this document:
-<A href=f2python9.ps.gz>Gzipped PS</A>,
-<A href=f2python9.pdf>PDF</A>
-}
-
-\begin{abstract}
- FPIG --- Fortran to Python Interface Generator --- is a tool for
- generating Python C/API extension modules that interface
- Fortran~77/90/95 codes with Python. This tool automates the process
- of interface generation by scanning the Fortran source code to
- determine the signatures of Fortran routines and creating a
- Python C/API module that contains the corresponding interface
- functions. FPIG also attempts to find dependence relations between
- the arguments of a Fortran routine call (e.g. an array and its
- dimensions) and constructs interface functions with potentially
- fewer arguments. The tool is extremely flexible since the user has
- control over the generation process of the interface by specifying the
- desired function signatures. The home page for FPIG can be found at
- \wwwsite{http://cens.ioc.ee/projects/f2py2e/}.
-
- FPIG has been used successfully to wrap a large number of Fortran
- programs and libraries. Advances in computational science have led
- to large improvements in the modeling of physical systems which are
- often a result of the coupling of a variety of physical models that
- were typically run in isolation. Since a majority of the available
- physical models have been previously written in Fortran, the
- importance of FPIG in accomplishing these couplings cannot be
- understated. In this paper, we present an application of FPIG to
- create an object-oriented framework for aero-structural analysis and
- design of aircraft.
-\end{abstract}
-
-%%tth:
-\tableofcontents
-
-\section{Preface}
-\label{sec:preface}
-
-The use of high-performance computing has made it possible to tackle
-many important problems and discover new physical phenomena in science
-and engineering. These accomplishments would not have been achieved
-without the computer's ability to process large amounts of data in a
-reasonably short time. It can safely be said that the computer has
-become an essential tool for scientists and engineers. However, the
-diversity of problems in science and engineering has left its mark as
-computer programs have been developed in different programming
-languages, including languages developed to describe certain specific
-classes of problems.
-
-In interdisciplinary fields it is not uncommon for scientists and
-engineers to face problems that have already been solved in a
-different programming environment from the one they are familiar with.
-Unfortunately, researchers may not have the time or willingness to
-learn a new programming language and typically end up developing the
-corresponding tools in the language that they normally use. This
-approach to the development of new software can substantially impact
-the time to develop and the quality of the resulting product: firstly,
-it usually takes longer to develop and test a new tool than to learn a
-new programming environment, and secondly it is very unlikely that a
-non-specialist in a given field can produce a program that is more
-efficient than more established tools.
-
-To avoid situations such as the one described above, one alternative
-would be to provide automatic or semi-automatic interfaces between programming
-languages. Another possibility would be to provide language
-translators, but these obviously require more work than interface
-generators --- a translator must understand all language constructs
-while an interface generator only needs to understand a subset of these
-constructs. With an automatic interface between two languages, scientists or
-engineers can effectively use programs written in other programming
-languages without ever having to learn them.
-
-Although it is clear that it is impossible to interface arbitrary programming
-languages with each other, there is no reason for doing so. Low-level languages such as C and Fortran are well known for
-their speed and are therefore suitable for applications where
-performance is critical. High-level scripting languages, on the other
-hand, are generally slower but much easier to learn and use,
-especially when performing interactive analysis. Therefore, it makes
-sense to create interfaces only in one direction: from lower-level
-languages to higher-level languages.
-
-In an ideal world, scientists and engineers would use higher-level
-languages for the manipulation of the mathematical formulas in a problem
-rather than having to struggle with tedious programming details. For tasks
-that are computationally demanding, they would use interfaces to
-high-performance routines that are written in a lower-level language
-optimized for execution speed.
-
-
-\section{Introduction}
-\label{sec:intro}
-
-This paper presents a tool that has been developed for the creation of
-interfaces between Fortran and Python.
-
-
-The Fortran language is popular in
-scientific computing, and is used mostly in applications that use
-extensive matrix manipulations (e.g. linear algebra). Since Fortran
- has been the standard language among scientists and engineers for
- at least three decades, there is a large number of legacy codes available that
- perform a variety of tasks using very sophisticated algorithms (see
-e.g. \cite{netlib}).
-
-The Python language \cite{python}, on the other hand, is a relatively
-new programming language. It is a very high-level scripting language
-that supports object-oriented programming. What makes Python
-especially appealing is its very clear and natural syntax, which makes it
-easy to learn and use. With Python one can implement relatively
-complicated algorithms and tasks in a short time with very compact
-source code.
-
-Although there are ongoing projects for extending Python's usage in
-scientific computation, it lacks reliable tools that are common in
-scientific and engineering such as ODE integrators, equation solvers,
-tools for FEM, etc. The implementation of all of these tools in Python
-would be not only too time-consuming but also inefficient. On the
-other hand, these tools are already developed in other,
-computationally more efficient languages such as Fortran or C.
-Therefore, the perfect role for Python in the context of scientific
-computing would be that of a ``gluing'' language. That is, the role
-of providing high-level interfaces to C, C++ and Fortran libraries.
-
-There are a number of widely-used tools that can be used for interfacing
-software libraries to Python. For binding C libraries with various
-scripting languages, including Python, the tool most often used is
-SWIG \cite{swig}. Wrapping Fortran routines with Python is less
-popular, mainly because there are many platform and compiler-specific
-issues that need to be addressed. Nevertheless, there is great
-interest in interfacing Fortran libraries because they provide
-invaluable tools for scientific computing. At LLNL, for example, a tool
-called PyFort has been developed for connecting Fortran and
-Python~\cite{pyfort}.
-
-The tools mentioned above require an input file describing signatures
-of functions to be interfaced. To create these input files, one needs
-to have a good knowledge of either C or Fortran. In addition,
-binding libraries that have thousands of routines can certainly constitute a
-very tedious task, even with these tools.
-
-The tool that is introduced in this paper, FPIG (Fortran to Python
-Interface Generator)~\cite{fpig}, automatically generates interfaces
-between Fortran and Python. It is different from the tools mentioned
-above in that FPIG can create signature files automatically by
-scanning the source code of the libraries and then construct Python
-C/API extension modules. Note that the user need not be experienced
-in C or even Fortran. In addition, FPIG is designed to wrap large
-Fortran libraries containing many routines with only one or two
-commands. This process is very flexible since one can always modify
-the generated signature files to insert additional attributes in order
-to achieve more sophisticated interface functions such as taking care
-of optional arguments, predicting the sizes of array arguments and
-performing various checks on the correctness of the input arguments.
-
-The organization of this paper is as follows. First, a simple example
-of FPIG usage is given. Then FPIG's basic features are described and
-solutions to platform and compiler specific issues are discussed.
-Unsolved problems and future work on FPIG's development are also
-addressed. Finally, an application to a large aero-structural solver
-is presented as real-world example of FPIG's usage.
-
-\section{Getting Started}
-\label{sec:getstart}
-
-To get acquainted with FPIG, let us consider the simple Fortran~77
-subroutine shown in Fig. \ref{fig:exp1.f}.
-\begin{figure}[htb]
- \latexhide{\label{fig:exp1.f}}
- \special{html:<BLOCKQUOTE>}
- \verbatiminput{examples/exp1.f}
- \special{html:</BLOCKQUOTE>}
- \caption{Example Fortran code \texttt{exp1.f}. This routine calculates
- the simplest rational lower and upper approximations to $e$ (for
- details of
- the algorithm see \cite{graham-etal}, p.122)}
- \tthhide{\label{fig:exp1.f}}
-\end{figure}
-In the sections that follow, two ways of creating interfaces to this
-Fortran subroutine are described. The first and simplest way is
-suitable for Fortran codes that are developed in connection with \fpy.
-The second and not much more difficult method, is suitable for
-interfacing existing Fortran libraries which might have been developed
-by other programmers.
-
-Numerical Python~\cite{numpy} is needed in order to compile extension
-modules generated by FPIG.
-
-\subsection{Interfacing Simple Routines}
-\label{sec:example1}
-
-In order to call the Fortran routine \texttt{exp1} from Python, let us
-create an interface to it by using \fpy (FPIG's front-end program). In
-order to do this, we issue the following command, \shell{f2py -m foo
-exp1.f} where the option \texttt{-m foo} sets the name of the Python
-C/API extension module that \fpy will create to
-\texttt{foo}. To learn more about the \fpy command line options, run \fpy
-without arguments.
-
-The output messages in Fig. \ref{fig:f2pyoutmess}
-illustrate the procedure followed by \fpy:
- (i) it scans the Fortran source code specified in the command line,
- (ii) it analyses and determines the routine signatures,
- (iii) it constructs the corresponding Python C/API extension modules,
- (iv) it writes documentation to a LaTeX file, and
- (v) it creates a GNU Makefile for building the shared modules.
-\begin{figure}[htb]
- \latexhide{\label{fig:f2pyoutmess}}
- \special{html:<BLOCKQUOTE>}
- {\tthhide{\small}
- \verbatiminput{examples/exp1mess.txt}
- }
- \special{html:</BLOCKQUOTE>}
- \caption{Output messages of \texttt{f2py -m foo exp1.f}.}
- \tthhide{\label{fig:f2pyoutmess}}
-\end{figure}
-
-Now we can build the \texttt{foo} module:
-\shell{make -f Makefile-foo}
-
-Figure \ref{fig:exp1session} illustrates a sample session for
- calling the Fortran routine \texttt{exp1} from Python.
-\begin{figure}[htb]
- \latexhide{\label{fig:exp1session}}
- \special{html:<BLOCKQUOTE>}
- \verbatiminput{examples/exp1session.txt}
- \special{html:</BLOCKQUOTE>}
- \caption{Calling Fortran routine \texttt{exp1} from Python. Here
- \texttt{l[0]/l[1]} gives an estimate to $e$ with absolute error
- less than \texttt{u[0]/u[1]-l[0]/l[1]} (this value may depend on
- the platform and compiler used).}
- \tthhide{\label{fig:exp1session}}
-\end{figure}
-
-Note the difference between the signatures of the Fortran routine
-\texttt{exp1(l,u,n)} and the corresponding wrapper function
-\texttt{l,u=exp1([n])}. Clearly, the later is more informative to
-the user: \texttt{exp1} takes one optional argument \texttt{n} and it
-returns \texttt{l}, \texttt{u}. This exchange of signatures is
-achieved by special comment lines (starting with \texttt{Cf2py}) in
-the Fortran source code --- these lines are interpreted by \fpy as
-normal Fortran code. Therefore, in the given example the line \texttt{Cf2py
- integer*4 :: n = 1} informs \fpy that the variable \texttt{n} is
-optional with a default value equal to one. The line \texttt{Cf2py
- intent(out) l,u} informs \fpy that the variables \texttt{l,u} are to be
-returned to Python after calling Fortran function \texttt{exp1}.
-
-\subsection{Interfacing Libraries}
-\label{sec:example2}
-
-In our example the Fortran source \texttt{exp1.f} contains \fpy
-specific information, though only as comments. When interfacing
-libraries from other parties, it is not recommended to modify their
-source. Instead, one should use a special auxiliary file to collect
-the signatures of all Fortran routines and insert \fpy specific
-declaration and attribute statements in that file. This auxiliary file
-is called a \emph{signature file} and is identified by the extension
-\texttt{.pyf}.
-
-We can use \fpy to generate these signature files by using the
-\texttt{-h <filename>.pyf} option.
-In our example, \fpy could have been called as follows,
-\shell{f2py -m foo -h foo.pyf exp1.f}
-where the option \texttt{-h foo.pyf} requests \fpy to read the
-routine signatures, save them to the file \texttt{foo.pyf}, and then
-exit.
-If \texttt{exp1.f} in Fig.~\ref{fig:exp1.f} were to
-contain no lines starting with \texttt{Cf2py}, the corresponding
-signature file \texttt{foo.pyf} would be as shown in Fig.~\ref{fig:foo.pyf}.
-In order to obtain the exchanged and more convenient signature
-\texttt{l,u=foo.exp1([n])}, we would edit \texttt{foo.pyf} as shown in
-Fig.~\ref{fig:foom.pyf}.
-The Python C/API extension module \texttt{foo} can be constructed by
-applying \fpy to the signature file with the following command:
-\shell{f2py foo.pyf}
-The procedure for building the corresponding shared module and using
-it in Python is identical to the one described in the previous section.
-
-\begin{figure}[htb]
- \latexhide{\label{fig:foo.pyf}}
- \special{html:<BLOCKQUOTE>}
- \verbatiminput{examples/foo.pyf}
- \special{html:</BLOCKQUOTE>}
- \caption{Raw signature file \texttt{foo.pyf} generated with
- \texttt{f2py -m foo -h foo.pyf exp1.f}}
- \tthhide{\label{fig:foo.pyf}}
-\end{figure}
-\begin{figure}[htb]
- \latexhide{\label{fig:foom.pyf}}
- \special{html:<BLOCKQUOTE>}
- \verbatiminput{examples/foom.pyf}
- \special{html:</BLOCKQUOTE>}
- \caption{Modified signature file \texttt{foo.pyf}}
- \tthhide{\label{fig:foom.pyf}}
-\end{figure}
-
-As we can see, the syntax of the signature file is an
-extension of the Fortran~90/95 syntax. This means that only a few new
-constructs are introduced for \fpy in addition to all standard Fortran
-constructs; signature files can even be written in fixed form. A
-complete set of constructs that are used when creating interfaces, is
-described in the \fpy User's Guide \cite{f2py-ug}.
-
-
-\section{Basic Features}
-\label{sec:features}
-
-In this section a short overview of \fpy features is given.
-\begin{enumerate}
-\item All basic Fortran types are supported. They include
-the following type specifications:
-\begin{verbatim}
-integer[ | *1 | *2 | *4 | *8 ]
-logical[ | *1 | *2 | *4 | *8 ]
-real[ | *4 | *8 | *16 ]
-complex[ | *8 | *16 | *32 ]
-double precision, double complex
-character[ |*(*)|*1|*2|*3|...]
-\end{verbatim}
-In addition, they can all be in the kind-selector form
-(e.g. \texttt{real(kind=8)}) or char-selector form
-(e.g. \texttt{character(len=5)}).
-\item Arrays of all basic types are supported. Dimension
- specifications can be of form \texttt{<dimension>} or
- \texttt{<start>:<end>}. In addition, \texttt{*} and \texttt{:}
- dimension specifications can be used for input arrays.
- Dimension specifications may contain also \texttt{PARAMETER}'s.
-\item The following attributes are supported:
- \begin{itemize}
- \item
- \texttt{intent(in)}: used for input-only arguments.
- \item
- \texttt{intent(inout)}: used for arguments that are changed in
- place.
- \item
- \texttt{intent(out)}: used for return arguments.
- \item
- \texttt{intent(hide)}: used for arguments to be removed from
- the signature of the Python function.
- \item
- \texttt{intent(in,out)}, \texttt{intent(inout,out)}: used for
- arguments with combined behavior.
- \item
- \texttt{dimension(<dimspec>)}
- \item
- \texttt{depend([<names>])}: used
- for arguments that depend on other arguments in \texttt{<names>}.
- \item
- \texttt{check([<C booleanexpr>])}: used for checking the
- correctness of input arguments.
- \item
- \texttt{note(<LaTeX text>)}: used for
- adding notes to the module documentation.
- \item
- \texttt{optional}, \texttt{required}
- \item
- \texttt{external}: used for call-back arguments.
- \item
- \texttt{allocatable}: used for Fortran 90/95 allocatable arrays.
- \end{itemize}
-\item Using \fpy one can call arbitrary Fortran~77/90/95 subroutines
- and functions from Python, including Fortran 90/95 module routines.
-\item Using \fpy one can access data in Fortran~77 COMMON blocks and
- variables in Fortran 90/95 modules, including allocatable arrays.
-\item Using \fpy one can call Python functions from Fortran (call-back
- functions). \fpy supports very flexible hooks for call-back functions.
-\item Wrapper functions perform the necessary type conversations for their
- arguments resulting in contiguous Numeric arrays that are suitable for
- passing to Fortran routines.
-\item \fpy generates documentation strings
-for \texttt{\_\_doc\_\_} attributes of the wrapper functions automatically.
-\item \fpy scans Fortran codes and creates the signature
- files. It automatically detects the signatures of call-back functions,
- solves argument dependencies, decides the order of initialization of
- optional arguments, etc.
-\item \fpy automatically generates GNU Makefiles for compiling Fortran
- and C codes, and linking them to a shared module.
- \fpy detects available Fortran and C compilers. The
- supported compilers include the GNU project C Compiler (gcc), Compaq
- Fortran, VAST/f90 Fortran, Absoft F77/F90, and MIPSpro 7 Compilers, etc.
- \fpy has been tested to work on the following platforms: Intel/Alpha
- Linux, HP-UX, IRIX64.
-\item Finally, the complete \fpy User's Guide is available in various
- formats (ps, pdf, html, dvi). A mailing list,
- \email{f2py-users@cens.ioc.ee}, is open for support and feedback. See
- the FPIG's home page for more information \cite{fpig}.
-\end{enumerate}
-
-
-\section{Implementation Issues}
-\label{sec:impl}
-
-The Fortran to Python interface can be thought of as a three layer
-``sandwich'' of different languages: Python, C, and Fortran. This
-arrangement has two interfaces: Python-C and C-Fortran. Since Python
-itself is written in C, there are no basic difficulties in
-implementing the Python-C interface~\cite{python-doc:ext}. The C-Fortran
-interface, on the other hand, results in many platform and compiler specific
-issues that have to be dealt with. We will now discuss these issues
-in some detail and describe how they are solved in FPIG.
-
-\subsection{Mapping Fortran Types to C Types}
-\label{sec:mapF2Ctypes}
-
-Table \ref{tab:mapf2c} defines how Fortran types are mapped to C types
-in \fpy.
-\begin{table}[htb]
- \begin{center}
- \begin{tabular}[c]{l|l}
- Fortran type & C type \\\hline
- \texttt{integer *1} & \texttt{char}\\
- \texttt{byte} & \texttt{char}\\
- \texttt{integer *2} & \texttt{short}\\
- \texttt{integer[ | *4]} & \texttt{int}\\
- \texttt{integer *8} & \texttt{long long}\\
- \texttt{logical *1} & \texttt{char}\\
- \texttt{logical *2} & \texttt{short}\\
- \texttt{logical[ | *4]} & \texttt{int}\\
- \texttt{logical *8} & \texttt{int}\\
- \texttt{real[ | *4]} & \texttt{float}\\
- \texttt{real *8} & \texttt{double}\\
- \texttt{real *16} & \texttt{long double}\\
- \texttt{complex[ | *8]} & \texttt{struct \{float r,i;\}}\\
- \texttt{complex *16} & \texttt{struct \{double r,i;\}}\\
- \texttt{complex *32} & \texttt{struct \{long double r,i;\}}\\
- \texttt{character[*...]} & \texttt{char *}\\
- \end{tabular}
- \caption{Mapping Fortran types to C types.}
- \label{tab:mapf2c}
- \end{center}
-\end{table}
-Users may redefine these mappings by creating a \texttt{.f2py\_f2cmap}
-file in the working directory. This file should contain a Python
-dictionary of dictionaries, e.g. \texttt{\{'real':\{'low':'float'\}\}},
-that informs \fpy to map Fortran type \texttt{real(low)}
-to C type \texttt{float} (here \texttt{PARAMETER low = ...}).
-
-
-\subsection{Calling Fortran (Module) Routines}
-\label{sec:callrout}
-
-When mixing Fortran and C codes, one has to know how function names
-are mapped to low-level symbols in their object files. Different
-compilers may use different conventions for this purpose. For example, gcc
-appends the underscore \texttt{\_} to a Fortran routine name. Other
-compilers may use upper case names, prepend or append different
-symbols to Fortran routine names or both. In any case, if the
-low-level symbols corresponding to Fortran routines are valid for the
-C language specification, compiler specific issues can be solved by
-using CPP macro features.
-
-Unfortunately, there are Fortran compilers that use symbols in
-constructing low-level routine names that are not valid for C. For
-example, the (IRIX64) MIPSpro 7 Compilers use `\$' character in the
-low-level names of module routines which makes it impossible (at
-least directly) to call such routines from C when using the MIPSpro 7
-C Compiler.
-
-In order to overcome this difficulty, FPIG introduces an unique
-solution: instead of using low-level symbols for calling Fortran
-module routines from C, the references to such routines are determined
-at run-time by using special wrappers. These wrappers are called once
-during the initialization of an extension module. They are simple
-Fortran subroutines that use a Fortran module and call another C
-function with Fortran module routines as arguments in order to save
-their references to C global variables that are later used for calling
-the corresponding Fortran module routines. This arrangement is
-set up as follows. Consider the following Fortran 90 module with the
-subroutine \texttt{bar}:
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
-module fun
- subroutine bar()
- end
-end
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
-Figure \ref{fig:capi-sketch} illustrates a Python C/API extension
-module for accessing the F90 module subroutine \texttt{bar} from Python.
-When the Python module \texttt{foo} is loaded, \texttt{finitbar} is
-called. \texttt{finitbar} calls \texttt{init\_bar} by passing the
-reference of the Fortran 90 module subroutine \texttt{bar} to C where it is
-saved to the variable \texttt{bar\_ptr}. Now, when one executes \texttt{foo.bar()}
-from Python, \texttt{bar\_ptr} is used in \texttt{bar\_capi} to call
-the F90 module subroutine \texttt{bar}.
-\begin{figure}[htb]
- \latexhide{\label{fig:capi-sketch}}
- \special{html:<BLOCKQUOTE>}
-\begin{verbatim}
-#include "Python.h"
-...
-char *bar_ptr;
-void init_bar(char *bar) {
- bar_ptr = bar;
-}
-static PyObject *
-bar_capi(PyObject *self,PyObject *args) {
- ...
- (*((void *)bar_ptr))();
- ...
-}
-static PyMethodDef
-foo_module_methods[] = {
- {"bar",bar_capi,METH_VARARGS},
- {NULL,NULL}
-};
-extern void finitbar_; /* GCC convention */
-void initfoo() {
- ...
- finitbar_(init_bar);
- Py_InitModule("foo",foo_module_methods);
- ...
-}
-\end{verbatim}
- \special{html:</BLOCKQUOTE>}
- \caption{Sketch of Python C/API for accessing F90 module subroutine
- \texttt{bar}. The Fortran function \texttt{finitbar} is defined in
- Fig.~\ref{fig:wrapbar}.}
- \tthhide{\label{fig:capi-sketch}}
-\end{figure}
-\begin{figure}[ht]
- \latexhide{\label{fig:wrapbar}}
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
- subroutine finitbar(cinit)
- use fun
- extern cinit
- call cinit(bar)
- end
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
- \caption{Wrapper for passing the reference of \texttt{bar} to C code.}
- \tthhide{\label{fig:wrapbar}}
-\end{figure}
-
-Surprisingly, mixing C code and Fortran modules in this way is as
-portable and compiler independent as mixing C and ordinary Fortran~77
-code.
-
-Note that extension modules generated by \fpy actually use
-\texttt{PyFortranObject} that implements above described scheme with
-exchanged functionalities (see Section \ref{sec:PFO}).
-
-
-\subsection{Wrapping Fortran Functions}
-\label{sec:wrapfunc}
-
-The Fortran language has two types of routines: subroutines and
-functions. When a Fortran function returns a composed type such as
-\texttt{COMPLEX} or \texttt{CHARACTER}-array then calling this
-function directly from C may not work for all compilers, as C
-functions are not supposed to return such references. In order to
-avoid this, FPIG constructs an additional Fortran wrapper subroutine
-for each such Fortran function. These wrappers call just the
-corresponding functions in the Fortran layer and return the result to
-C through its first argument.
-
-
-\subsection{Accessing Fortran Data}
-\label{sec:accsdata}
-
-In Fortran one can use \texttt{COMMON} blocks and Fortran module
-variables to save data that is accessible from other routines. Using
-FPIG, one can also access these data containers from Python. To achieve
-this, FPIG uses special wrapper functions (similar to the ones used
-for wrapping Fortran module routines) to save the references to these
-data containers so that they can later be used from C.
-
-FPIG can also handle \texttt{allocatable} arrays. For example, if a
-Fortran array is not yet allocated, then by assigning it in Python,
-the Fortran to Python interface will allocate and initialize the
-array. For example, the F90 module allocatable array \texttt{bar}
-defined in
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
-module fun
- integer, allocatable :: bar(:)
-end module
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
-can be allocated from Python as follows
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
->>> import foo
->>> foo.fun.bar = [1,2,3,4]
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
-
-\subsection{\texttt{PyFortranObject}}
-\label{sec:PFO}
-
-In general, we would like to access from Python the following Fortran
-objects:
-\begin{itemize}
-\item subroutines and functions,
-\item F90 module subroutines and functions,
-\item items in COMMON blocks,
-\item F90 module data.
-\end{itemize}
-Assuming that the Fortran source is available, we can determine the signatures
-of these objects (the full specification of routine arguments, the
-layout of Fortran data, etc.). In fact, \fpy gets this information
-while scanning the Fortran source.
-
-In order to access these Fortran objects from C, we need to determine
-their references. Note that the direct access of F90 module objects is
-extremely compiler dependent and in some cases even impossible.
-Therefore, FPIG uses various wrapper functions for obtaining the
-references to Fortran objects. These wrapper functions are ordinary
-F77 subroutines that can easily access objects from F90 modules and
-that pass the references to Fortran objects as C variables.
-
-
-\fpy generated Python C/API extension modules use
-\texttt{PyFortranObject} to store the references of Fortran objects.
-In addition to the storing functionality, the \texttt{PyFortranObject}
-also provides methods for accessing/calling Fortran objects from
-Python in a user-friendly manner. For example, the item \texttt{a} in
-\texttt{COMMON /bar/ a(2)} can be accessed from Python as
-\texttt{foo.bar.a}.
-
-Detailed examples of \texttt{PyFortranObject} usage can be found in
-\cite{PFO}.
-
-\subsection{Callback Functions}
-\label{sec:callback}
-
-Fortran routines may have arguments specified as \texttt{external}.
-These arguments are functions or subroutines names that the receiving Fortran routine
-will call from its body. For such arguments FPIG
-constructs a call-back mechanism (originally contributed by Travis
-Oliphant) that allows Fortran routines to call Python functions. This
-is actually realized using a C layer between Python and
-Fortran. Currently, the call-back mechanism is compiler independent
-unless a call-back function needs to return a composed type
-(e.g. \texttt{COMPLEX}).
-
-The signatures of call-back functions are determined when \fpy scans
-the Fortran source code. To illustrate this, consider the following
-example:
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
- subroutine foo(bar, fun, boo)
- integer i
- real r
- external bar,fun,boo
- call bar(i, 1.2)
- r = fun()
- call sun(boo)
- end
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
-\fpy recognizes the signatures of the user routines \texttt{bar} and
-\texttt{fun} using the information contained in the lines \texttt{call
- bar(i, 1.2)} and \texttt{r = fun()}:
-\special{html:<BLOCKQUOTE>}
-\begin{verbatim}
-subroutine bar(a,b)
- integer a
- real b
-end
-function fun()
- real fun
-end
-\end{verbatim}
-\special{html:</BLOCKQUOTE>}
-But \fpy cannot determine the signature of the user routine
-\texttt{boo} because the source contains no information at all about
-the \texttt{boo} specification. Here user needs to provide the
-signature of \texttt{boo} manually.
-
-\section{Future Work}
-\label{sec:future}
-
-FPIG can be used to wrap almost any Fortran code. However, there are
-still issues that need to be resolved. Some of them are listed below:
-\begin{enumerate}
-\item One of the FPIG's goals is to become as platform and compiler
- independent as possible. Currently FPIG can be used on
- any UN*X platform that has gcc installed in it. In the future, FPIG
- should be also tested on Windows systems.
-\item Another goal of FPIG is to become as simple to use as
- possible. To achieve that, FPIG should start using the facilities of
- \texttt{distutils}, the new Python standard to distribute and build
- Python modules. Therefore, a contribution to \texttt{distutils}
- that can handle Fortran extensions should be developed.
-\item Currently users must be aware of
- the fact that multi-dimensional arrays are stored differently in C
- and Fortran (they must provide transposed multi-dimensional arrays
- to wrapper functions). In the future a solution should be found such
- that users do not need to worry about this rather
- confusing and technical detail.
-\item Finally, a repository of signature files for widely-used Fortran
- libraries (e.g. BLAS, LAPACK, MINPACK, ODEPACK, EISPACK, LINPACK) should be
- provided.
-\end{enumerate}
-
-
-\section{Application to a Large Aero-Structural Analysis Framework}
-\label{sec:app}
-
-
-\subsection{The Need for Python and FPIG}
-\label{sec:appsub1}
-
-As a demonstration of the power and usefulness of FPIG, we will
-present work that has been done at the Aerospace Computing Laboratory
-at Stanford University. The focus of the research is on aircraft
-design optimization using high-fidelity analysis tools such as
-Computational Fluid Dynamics (CFD) and Computational Structural
-Mechanics (CSM)~\cite{reno99}.
-
-The group's analysis programs are written mainly in Fortran and are the result
-of many years of development. Until now, any researcher that needed
-to use these tools would have to learn a less than user-friendly
-interface and become relatively familiar with the inner workings of
-the codes before starting the research itself. The need to
-couple analyses of different disciplines revealed the additional
-inconvenience of gluing and scripting the different codes with
-Fortran.
-
-It was therefore decided that the existing tools should be wrapped
-using an object-oriented language in order to improve their ease of
-use and versatility. The use of several different languages such as
-C++, Java and Perl was investigated but Python seemed to provide the
-best solution. The fact that it combines scripting capability
-with a fully-featured object-oriented programming language, and that
-it has a clean syntax were factors that determined our choice. The
-introduction of tools that greatly facilitate the task of wrapping
-Fortran with Python provided the final piece needed to realize our
-objective.
-
-\subsection{Wrapping the Fortran Programs}
-
-In theory, it would have been possible to wrap our Fortran programs
-with C and then with Python by hand. However, this would have been a
-labor intensive task that would detract from our research. The use of
-tools that automate the task of wrapping has been extremely useful.
-
-The first such tool that we used was PyFort. This tool created the C
-wrappers and Python modules automatically, based on signature files
-(\texttt{.pyf}) provided by the user. Although it made the task of
-wrapping considerably easier, PyFort was limited by the fact that any
-Fortran data that was needed at the Python level had to be passed in
-the argument list of the Fortran subroutine. Since the bulk of the
-data in our programs is shared by using Fortran~77 common blocks and
-Fortran~90 modules, this required adding many more arguments to the
-subroutine headers. Furthermore, since Fortran does not allow common
-block variables or module data to be specified in a subroutine
-argument list, a dummy pointer for each desired variable had to be
-created and initialized.
-
-The search for a better solution to this problem led us to \fpy.
-Since \fpy provides a solution for accessing common block and module
-variables, there was no need to change the Fortran source anymore,
-making the wrapping process even easier. With \fpy we also
-experienced an increased level of automation since it produces the
-signature files automatically, as well as a Makefile for the joint
-compilation of the original Fortran and C wrapper codes. This increased
-automation did not detract from its flexibility since it was always
-possible to edit the signature files to provide different functionality.
-
-Once Python interfaces were created for each Fortran application
-by running \fpy, it was just a matter of using Python to achieve the
-final objective of developing an object-oriented framework for our
-multidisciplinary solvers. The Python modules that we designed are
-discussed in the following section.
-
-
-\subsection{Module Design}
-\label{ssec:module}
-
-The first objective of this effort was to design the classes for each
-type of analysis, each representing an independent Python module. In
-our case, we are interested in performing aero-structural analysis and
-optimization of aircraft wings. We therefore needed an analysis tool
-for the flow (CFD), another for analyzing the structure (CSM), as well
-as a geometry database. In addition, we needed to interface these two
-tools in order to analyze the coupled system. The object design for
-each of these modules should be general enough that the underlying
-analysis code in Fortran can be changed without changing the Python
-interface. Another requirement was that the modules be usable on
-their own for single discipline analysis.
-
-\subsubsection{Geometry}
-
-The \emph{Geometry} class provides a database for the outer mold
-geometry of the aircraft. This database needs to be accessed by both
-the flow and structural solvers. It contains a parametric description
-of the aircraft's surface as well as methods that extract and update
-this information.
-
-
-\subsubsection{Flow}
-
-The flow solver was wrapped in a class called \emph{Flow}. The class
-was designed so that it can wrap any type of CFD solver. It contains
-two main objects: the computational mesh and a solver object. A graph
-showing the hierarchy of the objects in \emph{Flow} is shown in
-Fig.~\ref{fig:flow}.
-\tthhide{
-\begin{figure}[h]
- \centering
- \epsfig{file=./flow.eps, angle=0, width=.7\linewidth}
- \caption{The \emph{Flow} container class.}
- \label{fig:flow}
-\end{figure}
-}
-\latexhide{
-\begin{figure}[h]
- \label{fig:flow}
-\special{html:
-<CENTER>
- <IMG SRC="flow.jpg" WIDTH="400">
-</CENTER>
-}
- \caption{The \emph{Flow} container class.}
-\end{figure}
-}
-Methods in the flow class include those used for the initialization of
-all the class components as well as methods that write the current
-solution to a file.
-
-
-\subsubsection{Structure}
-
-The \emph{Structure} class wraps a structural analysis code. The class
-stores the information about the structure itself in an object called
-\emph{Model} which also provides methods for changing and exporting
-its information. A list of the objects contained in this class can be
-seen in Fig.~\ref{fig:structure}.
-\tthhide{
-\begin{figure}[h]
- \centering
- \epsfig{file=./structure.eps, angle=0, width=.7\linewidth}
- \caption{The \emph{Structure} container class.}
- \label{fig:structure}
-\end{figure}
-}
-\latexhide{
-\begin{figure}[h]
- \label{fig:structure}
-\special{html:
-<CENTER>
- <IMG SRC="structure.jpg" WIDTH="400">
-</CENTER>
-}
- \caption{The \emph{Structure} container class.}
-\end{figure}
-}
-Since the \emph{Structure} class contains a
-dictionary of \emph{LoadCase} objects, it is able to store and solve
-multiple load cases, a capability that the original Fortran code
-does not have.
-
-
-\subsubsection{Aerostructure}
-
-The \emph{Aerostructure} class is the main class in the
-aero-structural analysis module and contains a \emph{Geometry}, a
-\emph{Flow} and a \emph{Structure}. In addition, the class defines
-all the functions that are necessary to translate aerodynamic
-loads to structural loads and structural displacements to
-geometry surface deformations.
-
-One of the main methods of this class is the one that solves the
-aeroelastic system. This method is printed below:
-\begin{verbatim}
-def Iterate(self, load_case):
- """Iterates the aero-structural solution."""
- self.flow.Iterate()
- self._UpdateStructuralLoads()
- self.structure.CalcDisplacements(load_case)
- self.structure.CalcStresses(load_case)
- self._UpdateFlowMesh()
- return
-\end{verbatim}
-This is indeed a very readable script, thanks to Python, and any
-high-level changes to the solution procedure can be easily
-implemented.
-The \emph{Aerostructure} class also contains methods that export all
-the information on the current solution for visualization, an example
-of which is shown in the next section.
-
-
-\subsection{Results}
-
-In order to visualize results, and because we needed to view results
-from multiple disciplines simultaneously, we selected OpenDX. Output
-files in DX format are written at the Python level and the result can
-be seen in Fig.~\ref{fig:aerostructure} for the case of a transonic
-airliner configuration.
-\tthhide{
-\begin{figure*}[t]
- \centering
- \epsfig{file=./aerostructure.eps, angle=-90, width=\linewidth}
- \caption{Aero-structural model and results.}
- \label{fig:aerostructure}
-\end{figure*}
-}
-\latexhide{
-\begin{figure}[h]
- \label{fig:aerostructure}
-\special{html:
-<CENTER>
- <IMG SRC="aerostructure.jpg" WIDTH="600">
-</CENTER>
-}
- \caption{Aero-structural model and results.}
-\end{figure}
-}
-
-
-The figure illustrates the multidisciplinary nature of the
-problem. The grid pictured in the background is the mesh used by the
-flow solver and is colored by the pressure values computed at the
-cell centers. The wing in the foreground and its outer surface is
-clipped to show the internal structural components which are colored
-by their stress value.
-
-In conclusion, \fpy and Python have been extremely useful tools in our
-pursuit for increasing the usability and flexibility of existing Fortran
-tools.
-
-
-\begin{thebibliography}{99}
-\bibitem{netlib}
-\newblock Netlib repository at UTK and ORNL.
-\newblock \\\wwwsite{http://www.netlib.org/}
-\bibitem{python}
-Python language.
-\newblock \\\wwwsite{http://www.python.org/}
-\bibitem{swig}
-SWIG --- Simplified Wrapper and Interface Generator.
-\newblock \\\wwwsite{http://www.swig.org/}
-\bibitem{pyfort}
-PyFort --- The Python-Fortran connection tool.
-\newblock \\\wwwsite{http://pyfortran.sourceforge.net/}
-\bibitem{fpig}
-FPIG --- Fortran to Python Interface Generator.
-\newblock \\\wwwsite{http://cens.ioc.ee/projects/f2py2e/}
-\bibitem{numpy}
-Numerical Extension to Python.
-\newblock \\\wwwsite{http://numpy.sourceforge.net/}
-\bibitem{graham-etal}
-R. L. Graham, D. E. Knuth, and O. Patashnik.
-\newblock {\em {C}oncrete {M}athematics: a foundation for computer science.}
-\newblock Addison-Wesley, 1988
-\bibitem{f2py-ug}
-P. Peterson.
-\newblock {\em {\tt f2py} - Fortran to Python Interface Generator. Second Edition.}
-\newblock 2000
-\newblock
-\\\wwwsite{http://cens.ioc.ee/projects/f2py2e/usersguide.html}
-\bibitem{python-doc:ext}
-Python Documentation: Extending and Embedding.
-\newblock \\\wwwsite{http://www.python.org/doc/ext/}
-\bibitem{PFO}
-P. Peterson. {\em {\tt PyFortranObject} example usages.}
-\newblock 2001
-\newblock \\\wwwsite{http://cens.ioc.ee/projects/f2py2e/pyfobj.html}
-\bibitem{reno99}
-Reuther, J., J. J. Alonso, J. R. R. A. Martins, and
-S. C. Smith.
-\newblock ``A Coupled Aero-Structural Optimization Method for
- Complete Aircraft Configurations'',
-\newblock {\em Proceedings of the 37th Aerospace Sciences Meeting},
-\newblock AIAA Paper 1999-0187. Reno, NV, January, 1999
-\end{thebibliography}
-
-%\end{multicols}
-
-%\begin{figure}[htbp]
-% \begin{center}
-% \epsfig{file=aerostructure2b.ps,width=0.75\textwidth}
-% \end{center}
-%\end{figure}
-
-
-
-\end{document}
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: t
-%%% End:
-
-
diff --git a/numpy/f2py/doc/signaturefile.tex b/numpy/f2py/doc/signaturefile.tex deleted file mode 100644 index 3cd16d890..000000000 --- a/numpy/f2py/doc/signaturefile.tex +++ /dev/null @@ -1,368 +0,0 @@ - -\section{Signature file} -\label{sec:signaturefile} - -The syntax of a signature file is borrowed from the Fortran~90/95 -language specification. Almost all Fortran~90/95 standard constructs -are understood. Recall that Fortran~77 is a subset of Fortran~90/95. -This tool introduces also some new attributes that are used for -controlling the process of Fortran to Python interface construction. -In the following, a short overview of the constructs -used in signature files will be given. - - -\subsection{Module block} -\label{sec:moduleblock} - -A signature file contains one or more \texttt{pythonmodule} blocks. A -\texttt{pythonmodule} block has the following structure: -\begin{verbatim} -python module <modulename> - interface - <routine signatures> - end [interface] - interface - module <F90/95 modulename> - <F90 module data type declarations> - <F90 module routine signatures> - end [module [<F90/95 modulename>]] - end [interface] -end [pythonmodule [<modulename>]] -\end{verbatim} -For each \texttt{pythonmodule} block \fpy will generate a C-file -\texttt{<modulename>module.c} (see step (iii)). (This is not true if -\texttt{<modulename>} contains substring \texttt{\_\_user\_\_}, see -Sec.~\ref{sec:cbmodule} and \texttt{external} attribute). - -\subsection{Signatures of Fortran routines and Python functions} -\label{sec:routineblock} - - -The signature of a Fortran routine has the following structure: -\begin{verbatim} -[<typespec>] function|subroutine <routine name> [([<arguments>])] \ - [result (<entityname>)] - [<argument type declarations>] - [<argument attribute statements>] - [<use statements>] - [<common block statements>] - [<other statements>] -end [function|subroutine [<routine name>]] -\end{verbatim} - -Let us introduce also the signature of the corresponding wrapper -function: -\begin{verbatim} -def <routine name>(<required arguments>[,<optional arguments>]): - ... - return <return variables> -\end{verbatim} - -Before you edit the signature file, you should first decide what is the -desired signature of the corresponding Python function. \fpy offers -many possibilities to control the interface construction process: you -may want to insert/change/remove various attributes in the -declarations of the arguments in order to change the appearance -of the arguments in the Python wrapper function. - -\begin{itemize} -\item -The definition of the \texttt{<argument type declaration>} is -\begin{verbatim} -<typespec> [[<attrspec>]::] <entitydecl> -\end{verbatim} -where -\begin{verbatim} -<typespec> := byte | character[<charselector>] - | complex[<kindselector>] | real[<kindselector>] - | double complex | double precision - | integer[<kindselector>] | logical[<kindselector>] -\end{verbatim} -\begin{verbatim} -<charselector> := *<charlen> | ([len=]<len>[,[kind]<kind>]) - | (kind=<kind>[,len=<len>]) -<kindselector> := *<intlen> | ([kind=]<kind>) -\end{verbatim} -(there is no sense to modify \texttt{<typespec>}s generated by \fpy). -\texttt{<attrspec>} is a comma separated list of attributes (see -Sec.~\ref{sec:attributes}); -\begin{verbatim} -<entitydecl> := <name> [[*<charlen>][(<arrayspec>)] - | [(<arrayspec>)]*<charlen>] - | [/<init_expr>/ | =<init_expr>] [,<entitydecl>] -\end{verbatim} -where \texttt{<arrayspec>} is a comma separated list of dimension -bounds; \texttt{<init\_expr>} is a C-expression (see -Sec.~\ref{sec:C-expr}). If an argument is not defined with -\texttt{<argument type declaration>}, its type is determined by -applying \texttt{implicit} rules (if it is not specifyied, then -standard rules are applied). - -\item The definition of the \texttt{<argument attribute statement>} is -a short form of the \texttt{<argument type declaration>}: -\begin{verbatim} -<attrspec> <entitydecl> -\end{verbatim} - -\item \texttt{<use statement>} is defined as follows -\begin{verbatim} -use <modulename> [,<rename_list> | ,ONLY:<only_list>] -<rename_list> := local_name=>use_name [,<rename_list>] -\end{verbatim} - Currently the \texttt{use} statement is used to link call-back - modules (Sec.~\ref{sec:cbmodule}) and the \texttt{external} - arguments (call-back functions). - -\item \texttt{<common block statement>} is defined as follows -\begin{verbatim} -common /<commonname>/ <shortentitydecl> -\end{verbatim} -where -\begin{verbatim} -<shortentitydecl> := <name> [(<arrayspec>)] [,<shortentitydecl>] -\end{verbatim} -One \texttt{module} block should not contain two or more -\texttt{common} blocks with the same name. Otherwise, the later ones -are ignored. The types of variables in \texttt{<shortentitydecl>} can -be defined in \texttt{<argument type declarations>}. Note that there -you can specify also the array specifications; then you don't need to -do that in \texttt{<shortentitydecl>}. -\end{itemize} - -\subsection{Attributes} -\label{sec:attributes} - -The following attributes are used by \fpy: -\begin{description} -\item[\texttt{optional}] --- the variable is moved to the end of - optional argument list of the wrapper function. Default value of an - optional argument can be specified using \texttt{<init\_expr>} in - \texttt{entitydecl}. You can use \texttt{optional} attribute also for - \texttt{external} arguments (call-back functions), but it is your - responsibility to ensure that it is given by the user if Fortran - routine wants to call it. -\item[\texttt{required}] --- the variable is considered as a required - argument (that is default). You will need this in order to overwrite - the \texttt{optional} attribute that is automatically set when - \texttt{<init\_expr>} is used. However, usage of this attribute - should be rare. -\item[\texttt{dimension(<arrayspec>)}] --- used when the variable is - an array. For unbounded dimensions symbols `\texttt{*}' or - `\texttt{:}' can be used (then internally the corresponding - dimensions are set to -1; you'll notice this when certain exceptions - are raised). -\item[\texttt{external}] --- the variable is a call-back function. \fpy will - construct a call-back mechanism for this function. Also call-back - functions must be defined by their signatures, and there are several - ways to do that. In most cases, \fpy will be able to determine the signatures - of call-back functions from the Fortran source code; then it - builds an additional \texttt{module} block with a name containing - string `\texttt{\_\_user\_\_}' (see Sec.~\ref{sec:cbmodule}) and - includes \texttt{use} statement to the routines signature. Anyway, - you should check that the generated signature is correct. - - Alternatively, you can specify the signature by inserting to the - routines block a ``model'' how the call-back function would be called - from Fortran. For subroutines you should use\\ - \hspace*{2em}\texttt{call <call-back name>(<arguments>)}\\ - and for functions\\% - \hspace*{2em}\texttt{<return value> = <call-back name>(<arguments>)}\\ - The variables in \texttt{<arguments>} and \texttt{<return value>} - must be defined as well. You can use the arguments of the main - routine, for instance. -\item[\texttt{intent(<intentspec>)}] --- this specifies the - ``intention'' of the variable. \texttt{<intentspec>} is a comma - separated list of the following specifications: - \begin{description} - \item[\texttt{in}] --- the variable is considered to be an input - variable (default). It means that the Fortran function uses only - the value(s) of the variable and is assumed not to change it. - \item[\texttt{inout}] --- the variable is considered to be an - input/output variable which means that Fortran routine may change - the value(s) of the variable. Note that in Python only array - objects can be changed ``in place''. (\texttt{intent(outin)} is - \texttt{intent(inout)}.) - \item[\texttt{out}] --- the value of the (output) variable is - returned by the wrapper function: it is appended to the list of - \texttt{<returned variables>}. If \texttt{out} is specified alone, - also \texttt{hide} is assumed. - \item[\texttt{hide}] --- use this if the variable \emph{should not} - or \emph{need not} to be in the list of wrapper function arguments - (not even in optional ones). For example, this is assumed if - \texttt{intent(out)} is used. You can ``hide'' an argument if it - has always a constant value specified in \texttt{<init\_expr>}, - for instance. - \end{description} - The following rules apply: - \begin{itemize} - \item if no \texttt{intent} attribute is specified, \texttt{intent(in)} is - assumed; - \item \texttt{intent(in,inout)} is \texttt{intent(in)}; - \item \texttt{intent(in,hide)}, \texttt{intent(inout,hide)} are \texttt{intent(hide)}; - \item \texttt{intent(out)} is \texttt{intent(out,hide)}; -\item \texttt{intent(inout)} is NOT \texttt{intent(in,out)}. - \end{itemize} - In conclusion, the following combinations are ``minimal'': - \texttt{intent(in)}, \texttt{intent(inout)}, \texttt{intent(out)}, - \texttt{intent(hide)}, \texttt{intent(in,out)}, and - \texttt{intent(inout,out)}. -\item[\texttt{check([<C-booleanexpr>])}] --- if - \texttt{<C-booleanexpr>} evaluates to zero, an exception is raised - about incorrect value or size or any other incorrectness of the - variable. If \texttt{check()} or \texttt{check} is used then \fpy - will not try to guess the checks automatically. -\item[\texttt{depend([<names>])}] --- the variable depends on other - variables listed in \texttt{<names>}. These dependence relations - determine the order of internal initialization of the variables. If - you need to change these relations then be careful not to break the - dependence relations of other relevant variables. If - \texttt{depend()} or \texttt{depend} is used then \fpy will not try - to guess the dependence relations automatically. -\item[\texttt{note(<LaTeX text>)}] --- with this attribute you can - include human readable documentation strings to the LaTeX document - that \fpy generates. Do not insert here information that \fpy can - establish by itself, such as, types, sizes, lengths of the - variables. Here you can insert almost arbitrary LaTeX text. Note - that \texttt{<LaTeX text>} is mainly used inside the LaTeX - \texttt{description} environment. Hint: you can use - \texttt{\bs{}texttt\{<name>\}} for typesetting variable \texttt{<name>} - in LaTeX. In order to get a new line to the LaTeX document, use - \texttt{\bs{}n} followed by a space. For longer text, you may want - to use line continuation feature of Fortran 90/95 language: set - \texttt{\&} (ampersand) - to be the last character in a line. -\item[\texttt{parameter}] --- the variable is parameter and it must - have a value. If the parameter is used in dimension specification, - it is replaced by its value. (Are there any other usages of - parameters except in dimension specifications? Let me know and I'll - add support for it). -\end{description} - - -\subsection{C-expressions} -\label{sec:C-expr} - -The signature of a routine may contain C-expressions in -\begin{itemize} -\item \texttt{<init\_expr>} for initializing particular variable, or in -\item \texttt{<C-booleanexpr>} of the \texttt{check} attribute, or in -\item \texttt{<arrayspec>} of the \texttt{dimension} attribute. -\end{itemize} -A C-expression may contain -\begin{itemize} -\item standard C-statement, -\item functions offered in \texttt{math.h}, -\item previously initialized variables (study -the dependence relations) from the argument list, and -\item the following CPP-macros: - \begin{description} - \item[\texttt{len(<name>)}] --- the length of an array \texttt{<name>}; - \item[\texttt{shape(<name>,<n>)}] --- the $n$-th dimension of an array - \texttt{<name>}; - \item[\texttt{rank(<name>)}] --- the rank of an array \texttt{<name>}; - \item[\texttt{slen(<name>)}] --- the length of a string \texttt{<name>}. - \end{description} -\end{itemize} - - -In addition, when initializing arrays, an index vector \texttt{int - \_i[rank(<name>)];} -is available: \texttt{\_i[0]} refers to -the index of the first dimension, \texttt{\_i[1]} to the index of -the second dimension, etc. For example, the argument type declaration\\ -\hspace*{2em}\texttt{integer a(10) = \_i[0]}\\ -is equivalent with the following Python statement\\ -\hspace*{2em}\texttt{a = array(range(10))} - - -\subsection{Required/optional arguments} -\label{sec:reqoptargs} - -When \texttt{optional} attribute is used (including the usage of -\texttt{<init\_expr>} without the \texttt{required} attribute), the -corresponding variable in the argument list of a Fortran routine is -appended to the optional argument list of the wrapper function. - -For optional array argument all dimensions must be bounded (not -\texttt{(*)} or \texttt{(:)}) and defined at the time of -initialization (dependence relations). - -If the \texttt{None} object is passed in in place of a required array -argument, it will be considered as optional: that is, the memory is -allocated (of course, if it has unbounded dimensions, an exception -will be raised), and if \texttt{<init\_expr>} is defined, -initialization is carried out. - - -\subsection{Internal checks} -\label{sec:intchecks} - -All array arguments are checked against the correctness of their rank. -If there is a mismatch, \fpy attempts to fix that by constructing an -array with a correct rank from the given array argument (there will be -no performance hit as no data is copied). The freedom to do so is -given only if some dimensions are unbounded or their value is 1. An -exception is raised when the sizes will not match. - -All bounded dimensions of an array are checked to be larger or equal -to the dimensions specified in the signature. - -So, you don't need to give explicit \texttt{check} attributes to check -these internal checks. - - -\subsection{Call-back modules} -\label{sec:cbmodule} - -A Fortran routine may have \texttt{external} arguments (call-back -functions). The signatures of the call-back functions must be defined -in a call-back \texttt{module} block (its name contains -\texttt{\_\_user\_\_}), in general; other possibilities are described -in the \texttt{external} attribute specification (see -Sec.~\ref{sec:attributes}). For the signatures of call-back -functions the following restrictions apply: -\begin{itemize} -\item Attributes \texttt{external}, \texttt{check(...)}, and - initialization statements are ignored. -\item Attribute \texttt{optional} is used only for changing the order - of the arguments. -\item For arrays all dimension bounds must be specified. They may be - C-expressions containing variables from the argument list. - Note that here CPP-macros \texttt{len}, \texttt{shape}, - \texttt{rank}, and \texttt{slen} are not available. -\end{itemize} - - -\subsection{Common blocks} -\label{sec:commonblocks} - -All fields in a common block are mapped to arrays of appropriate sizes -and types. Scalars are mapped to rank-0 arrays. For multi-dimensional -fields the corresponding arrays are transposed. In the type -declarations of the variables representing the common block fields, -only \texttt{dimension(<arrayspec>)}, \texttt{intent(hide)}, and -\texttt{note(<LaTeX text>)} attributes are used, others are ignored. - -\subsection{Including files} -\label{sec:include} - -You can include files to the signature file using -\begin{verbatim} -include '<filename>' -\end{verbatim} -statement. It can be used in any part of the signature file. -If the file \texttt{<filename>} does not exists or it is not in the path, -the \texttt{include} line is ignored. - -\subsection{\fpy directives} -\label{sec:directives} - -You can insert signature statements directly to Fortran source codes -as comments. Anything that follows \texttt{<comment char>f2py} is -regarded as normal statement for \fpy. - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "f2py2e" -%%% End: - diff --git a/numpy/f2py/doc/using_F_compiler.txt b/numpy/f2py/doc/using_F_compiler.txt deleted file mode 100644 index 3067f0776..000000000 --- a/numpy/f2py/doc/using_F_compiler.txt +++ /dev/null @@ -1,147 +0,0 @@ - -Title: Wrapping F compiled Fortran 90 modules with F2PY - ================================================ - -Rationale: The F compiler does not support external procedures which - makes it impossible to use it in F2PY in a normal way. - This document describes a workaround to this problem so - that F compiled codes can be still wrapped with F2PY. - -Author: Pearu Peterson -Date: May 8, 2002 - -Acknowledgement: Thanks to Siegfried Gonzi who hammered me to produce - this document. - -Normally wrapping Fortran 90 modules to Python using F2PY is carried -out with the following command - - f2py -c -m fun foo.f90 - -where file foo.f90 contains, for example, - -module foo - public :: bar - contains - subroutine bar (a) - integer,intent(inout) :: a - print *,"Hello from foo.bar" - print *,"a=",a - a = a + 5 - print *,"a=",a - end subroutine bar -end module foo - -Then with a supported F90 compiler (running `f2py -c --help-compiler' -will display the found compilers) f2py will generate an extension -module fun.so into the current directory and the Fortran module foo -subroutine bar can be called from Python as follows - ->>> import fun ->>> print fun.foo.bar.__doc__ -bar - Function signature: - bar(a) -Required arguments: - a : in/output rank-0 array(int,'i') - ->>> from Numeric import array ->>> a = array(3) ->>> fun.foo.bar(a) - Hello from foo.bar - a= 3 - a= 8 ->>> a -8 ->>> - -This works nicely with all supported Fortran compilers. - -However, the F compiler (http://www.fortran.com/F/compilers.html) is -an exception. Namely, the F compiler is designed to recognize only -module procedures (and main programs, of course) but F2PY needs to -compile also the so-called external procedures that it generates to -facilitate accessing Fortran F90 module procedures from C and -subsequently from Python. As a result, wrapping F compiled Fortran -procedures to Python is _not_ possible using the simple procedure as -described above. But, there is a workaround that I'll describe below -in five steps. - -1) Compile foo.f90: - - F -c foo.f90 - -This creates an object file foo.o into the current directory. - -2) Create the signature file: - - f2py foo.f90 -h foo.pyf - -This creates a file foo.pyf containing - -module foo ! in foo.f90 - real public :: bar - subroutine bar(a) ! in foo.f90:foo - integer intent(inout) :: a - end subroutine bar -end module foo - -3) Open the file foo.pyf with your favorite text editor and change the - above signature to - -python module foo - interface - subroutine bar(a) - fortranname foo_MP_bar - intent(c) bar - integer intent(in,out) :: a - end subroutine bar - end interface -end python module foo - -The most important modifications are - - a) adding `python' keyword everywhere before the `module' keyword - - b) including an `interface' block around the all subroutine blocks. - - c) specifying the real symbol name of the subroutine using - `fortranname' statement. F generated symbol names are in the form - <module name>_MP_<subroutine name> - - d) specifying that subroutine is `intent(c)'. - -Notice that the `intent(inout)' attribute is changed to -`intent(in,out)' that instructs the wrapper to return the modified -value of `a'. - -4) Build the extension module - - f2py -c foo.pyf foo.o --fcompiler=Gnu /opt/F/lib/quickfit.o \ - /opt/F/lib/libf96.a - -This will create the extension module foo.so into the current -directory. Notice that you must use Gnu compiler (gcc) for linking. -And the paths to F specific object files and libraries may differ for -your F installation. - -5) Finally, we can call the module subroutine `bar' from Python - ->>> import foo ->>> print foo.bar.__doc__ -bar - Function signature: - a = bar(a) -Required arguments: - a : input int -Return objects: - a : int - ->>> foo.bar(3) -8 ->>> - -Notice that the F compiled module procedures are called as ordinary -external procedures. Also I/O seems to be lacking for F compiled -Fortran modules. - -Enjoy, - Pearu diff --git a/numpy/f2py/doc/win32_notes.txt b/numpy/f2py/doc/win32_notes.txt deleted file mode 100644 index 1b7b9029c..000000000 --- a/numpy/f2py/doc/win32_notes.txt +++ /dev/null @@ -1,85 +0,0 @@ -The following notes are from Eric Jones.
-
-My Setup:
-
-For Python/Fortran development, I run Windows 2000 and use the mingw32
-(www.mingw.org) set of gcc/g77 compilers and tools (gcc 2.95.2) to build python
-extensions. I'll also ocassionally use MSVC for extension development, but
-rarely on projects that include Fortran code. This short HOWTO describes how
-I use f2py in the Windows environment. Pretty much everything is done from
-a CMD (DOS) prompt, so you'll need to be familiar with using shell commands.
-
-Installing f2py:
-
-Before installing f2py, you'll need to install python. I use python2.1 (maybe
-python2.2 will be out by the time you read this). Any version of Python beyond
-version 1.52 should be fine. See www.python.org for info on installing Python.
-
-You'll also need Numeric which is available at
-http://sourceforge.net/projects/numpy/. The latest version is 20.3.
-
-Since Pearu has moved to a setup.py script, installation is pretty easy. You
-can download f2py from http://cens.ioc.ee/projects/f2py2e/. The latest public
-release is http://cens.ioc.ee/projects/f2py2e/rel-3.x/f2py-3.latest.tgz. Even
-though this is a .tgz file instead of a .zip file, most standard compression
-utilities such as WinZip (www.winzip.com) handle unpacking .tgz files
-automatically. Here are the download steps:
-
- 1. Download the latest version of f2py and save it to disk.
-
- 2. Use WinZip or some other tool to open the "f2py.xxx.tgz" file.
- a. When WinZip says archive contains one file, "f2py.xxx.tar"
- and ask if it should open it, respond with "yes".
- b. Extract (use the extract button at the top) all the files
- in the archive into a file. I'll use c:\f2py2e
-
- 3. Open a cmd prompt by clicking start->run and typing "cmd.exe".
- Now type the following commands.
-
- C:\WINDOWS\SYSTEM32> cd c:\f2py2e
- C:\F2PY2E> python setup.py install
-
- This will install f2py in the c:\python21\f2py2e directory. It
- also copies a few scripts into the c:\python21\Scripts directory.
- Thats all there is to installing f2py. Now lets set up the environment
- so that f2py is easy to use.
-
- 4. You need to set up a couple of environement variables. The path
- "c:\python21\Scripts" needs to be added to your path variables.
- To do this, go to the enviroment variables settings page. This is
- where it is on windows 2000:
-
- Desktop->(right click)My Computer->Properties->Advanced->
- Environment Variables
-
- a. Add "c:\python21\Scripts" to the end of the Path variable.
- b. If it isn't already there, add ".py" to the PATHEXT variable.
- This tells the OS to execute f2py.py even when just "f2py" is
- typed at a command prompt.
-
- 5. Well, there actually isn't anything to be done here. The Python
- installation should have taken care of associating .py files with
- Python for execution, so you shouldn't have to do anything to
- registry settings.
-
-To test your installation, open a new cmd prompt, and type the following:
-
- C:\WINDOWS\SYSTEM32> f2py
- Usage:
- f2py [<options>] <fortran files> [[[only:]||[skip:]] \
- <fortran functions> ] \
- [: <fortran files> ...]
- ...
-
-This prints out the usage information for f2py. If it doesn't, there is
-something wrong with the installation.
-
-Testing:
-The f2py test scripts are kinda Unix-centric, so they don't work under windows.
-
-XXX include test script XXX.
-
-Compiler and setup.py issues:
-
-XXX
-
diff --git a/numpy/f2py/docs/FAQ.txt b/numpy/f2py/docs/FAQ.txt deleted file mode 100644 index 416560e92..000000000 --- a/numpy/f2py/docs/FAQ.txt +++ /dev/null @@ -1,615 +0,0 @@ - -====================================================================== - F2PY Frequently Asked Questions -====================================================================== - -.. contents:: - -General information -=================== - -Q: How to get started? ----------------------- - -First, install__ F2PY. Then check that F2PY installation works -properly (see below__). Try out a `simple example`__. - -Read `F2PY Users Guide and Reference Manual`__. It contains lots -of complete examples. - -If you have any questions/problems when using F2PY, don't hesitate to -turn to `F2PY users mailing list`__ or directly to me. - -__ index.html#installation -__ #testing -__ index.html#usage -__ usersguide/index.html -__ index.html#mailing-list - -Q: When to report bugs? ------------------------ - -* If F2PY scanning fails on Fortran sources that otherwise compile - fine. - -* After checking that you have the latest version of F2PY from its - CVS. It is possible that a bug has been fixed already. See also the - log entries in the file `HISTORY.txt`_ (`HISTORY.txt in CVS`_). - -* After checking that your Python and Numerical Python installations - work correctly. - -* After checking that your C and Fortran compilers work correctly. - - -Q: How to report bugs? ----------------------- - -You can send bug reports directly to me. Please, include information -about your platform (operating system, version) and -compilers/linkers, e.g. the output (both stdout/stderr) of -:: - - python -c 'import f2py2e.diagnose;f2py2e.diagnose.run()' - -Feel free to add any other relevant information. However, avoid -sending the output of F2PY generated ``.pyf`` files (unless they are -manually modified) or any binary files like shared libraries or object -codes. - -While reporting bugs, you may find the following notes useful: - -* `How To Ask Questions The Smart Way`__ by E. S. Raymond and R. Moen. - -* `How to Report Bugs Effectively`__ by S. Tatham. - -__ http://www.catb.org/~esr/faqs/smart-questions.html -__ http://www.chiark.greenend.org.uk/~sgtatham/bugs.html - -Installation -============ - -Q: How to use F2PY with different Python versions? --------------------------------------------------- - -Run the installation command using the corresponding Python -executable. For example, -:: - - python2.1 setup.py install - -installs the ``f2py`` script as ``f2py2.1``. - -See `Distutils User Documentation`__ for more information how to -install Python modules to non-standard locations. - -__ http://www.python.org/sigs/distutils-sig/doc/inst/inst.html - - -Q: Why F2PY is not working after upgrading? -------------------------------------------- - -If upgrading from F2PY version 2.3.321 or earlier then remove all f2py -specific files from ``/path/to/python/bin`` directory before -running installation command. - -Q: How to get/upgrade numpy_distutils when using F2PY from CVS? ---------------------------------------------------------------- - -To get numpy_distutils from SciPy CVS repository, run -:: - - cd cvs/f2py2e/ - make numpy_distutils - -This will checkout numpy_distutils to the current directory. - -You can upgrade numpy_distutils by executing -:: - - cd cvs/f2py2e/numpy_distutils - cvs update -Pd - -and install it by executing -:: - - cd cvs/f2py2e/numpy_distutils - python setup_numpy_distutils.py install - -In most of the time, f2py2e and numpy_distutils can be upgraded -independently. - -Testing -======= - -Q: How to test if F2PY is installed correctly? ----------------------------------------------- - -Run -:: - - f2py - -without arguments. If F2PY is installed correctly then it should print -the usage information for f2py. - -Q: How to test if F2PY is working correctly? --------------------------------------------- - -For a quick test, try out an example problem from Usage__ -section in `README.txt`_. - -__ index.html#usage - -For running F2PY unit tests, see `TESTING.txt`_. - - -Q: How to run tests and examples in f2py2e/test-suite/ directory? ---------------------------------------------------------------------- - -You shouldn't. These tests are obsolete and I have no intention to -make them work. They will be removed in future. - - -Compiler/Platform-specific issues -================================= - -Q: What are supported platforms and compilers? ----------------------------------------------- - -F2PY is developed on Linux system with a GCC compiler (versions -2.95.x, 3.x). Fortran 90 related hooks are tested against Intel -Fortran Compiler. F2PY should work under any platform where Python and -Numeric are installed and has supported Fortran compiler installed. - -To see a list of supported compilers, execute:: - - f2py -c --help-fcompiler - -Example output:: - - List of available Fortran compilers: - --fcompiler=gnu GNU Fortran Compiler (3.3.4) - --fcompiler=intel Intel Fortran Compiler for 32-bit apps (8.0) - List of unavailable Fortran compilers: - --fcompiler=absoft Absoft Corp Fortran Compiler - --fcompiler=compaq Compaq Fortran Compiler - --fcompiler=compaqv DIGITAL|Compaq Visual Fortran Compiler - --fcompiler=hpux HP Fortran 90 Compiler - --fcompiler=ibm IBM XL Fortran Compiler - --fcompiler=intele Intel Fortran Compiler for Itanium apps - --fcompiler=intelev Intel Visual Fortran Compiler for Itanium apps - --fcompiler=intelv Intel Visual Fortran Compiler for 32-bit apps - --fcompiler=lahey Lahey/Fujitsu Fortran 95 Compiler - --fcompiler=mips MIPSpro Fortran Compiler - --fcompiler=nag NAGWare Fortran 95 Compiler - --fcompiler=pg Portland Group Fortran Compiler - --fcompiler=sun Sun|Forte Fortran 95 Compiler - --fcompiler=vast Pacific-Sierra Research Fortran 90 Compiler - List of unimplemented Fortran compilers: - --fcompiler=f Fortran Company/NAG F Compiler - For compiler details, run 'config_fc --verbose' setup command. - - -Q: How to use the F compiler in F2PY? -------------------------------------- - -Read `f2py2e/doc/using_F_compiler.txt`__. It describes why the F -compiler cannot be used in a normal way (i.e. using ``-c`` switch) to -build F2PY generated modules. It also gives a workaround to this -problem. - -__ http://cens.ioc.ee/cgi-bin/viewcvs.cgi/python/f2py2e/doc/using_F_compiler.txt?rev=HEAD&content-type=text/vnd.viewcvs-markup - -Q: How to use F2PY under Windows? ---------------------------------- - -F2PY can be used both within Cygwin__ and MinGW__ environments under -Windows, F2PY can be used also in Windows native terminal. -See the section `Setting up environment`__ for Cygwin and MinGW. - -__ http://cygwin.com/ -__ http://www.mingw.org/ -__ http://cens.ioc.ee/~pearu/numpy/BUILD_WIN32.html#setting-up-environment - -Install numpy_distutils and F2PY. Win32 installers of these packages -are provided in `F2PY Download`__ section. - -__ http://cens.ioc.ee/projects/f2py2e/#download - -Use ``--compiler=`` and ``--fcompiler`` F2PY command line switches to -to specify which C and Fortran compilers F2PY should use, respectively. - -Under MinGW environment, ``mingw32`` is default for a C compiler. - -Supported and Unsupported Features -================================== - -Q: Does F2PY support ``ENTRY`` statements? ------------------------------------------- - -Yes, starting at F2PY version higher than 2.39.235_1706. - -Q: Does F2PY support derived types in F90 code? ------------------------------------------------ - -Not yet. However I do have plans to implement support for F90 TYPE -constructs in future. But note that the task in non-trivial and may -require the next edition of F2PY for which I don't have resources to -work with at the moment. - -Jeffrey Hagelberg from LLNL has made progress on adding -support for derived types to f2py. He writes: - - At this point, I have a version of f2py that supports derived types - for most simple cases. I have multidimensional arrays of derived - types and allocatable arrays of derived types working. I'm just now - starting to work on getting nested derived types to work. I also - haven't tried putting complex number in derived types yet. - -Hopefully he can contribute his changes to f2py soon. - -Q: Does F2PY support pointer data in F90 code? ------------------------------------------------ - -No. I have never needed it and I haven't studied if there are any -obstacles to add pointer data support to F2PY. - -Q: What if Fortran 90 code uses ``<type spec>(kind=KIND(..))``? ---------------------------------------------------------------- - -Currently, F2PY can handle only ``<type spec>(kind=<kindselector>)`` -declarations where ``<kindselector>`` is a numeric integer (e.g. 1, 2, -4,...) but not a function call ``KIND(..)`` or any other -expression. F2PY needs to know what would be the corresponding C type -and a general solution for that would be too complicated to implement. - -However, F2PY provides a hook to overcome this difficulty, namely, -users can define their own <Fortran type> to <C type> maps. For -example, if Fortran 90 code contains:: - - REAL(kind=KIND(0.0D0)) ... - -then create a file ``.f2py_f2cmap`` (into the working directory) -containing a Python dictionary:: - - {'real':{'KIND(0.0D0)':'double'}} - -for instance. - -Or more generally, the file ``.f2py_f2cmap`` must contain a dictionary -with items:: - - <Fortran typespec> : {<selector_expr>:<C type>} - -that defines mapping between Fortran type:: - - <Fortran typespec>([kind=]<selector_expr>) - -and the corresponding ``<C type>``. ``<C type>`` can be one of the -following:: - - char - signed_char - short - int - long_long - float - double - long_double - complex_float - complex_double - complex_long_double - string - -For more information, see ``f2py2e/capi_maps.py``. - -Related software -================ - -Q: How F2PY distinguishes from Pyfort? --------------------------------------- - -F2PY and Pyfort have very similar aims and ideology of how they are -targeted. Both projects started to evolve in the same year 1999 -independently. When we discovered each others projects, a discussion -started to join the projects but that unfortunately failed for -various reasons, e.g. both projects had evolved too far that merging -the tools would have been impractical and giving up the efforts that -the developers of both projects have made was unacceptable to both -parties. And so, nowadays we have two tools for connecting Fortran -with Python and this fact will hardly change in near future. To decide -which one to choose is a matter of taste, I can only recommend to try -out both to make up your choice. - -At the moment F2PY can handle more wrapping tasks than Pyfort, -e.g. with F2PY one can wrap Fortran 77 common blocks, Fortran 90 -module routines, Fortran 90 module data (including allocatable -arrays), one can call Python from Fortran, etc etc. F2PY scans Fortran -codes to create signature (.pyf) files. F2PY is free from most of the -limitations listed in in `the corresponding section of Pyfort -Reference Manual`__. - -__ http://pyfortran.sourceforge.net/pyfort/pyfort_reference.htm#pgfId-296925 - -There is a conceptual difference on how F2PY and Pyfort handle the -issue of different data ordering in Fortran and C multi-dimensional -arrays. Pyfort generated wrapper functions have optional arguments -TRANSPOSE and MIRROR that can be used to control explicitly how the array -arguments and their dimensions are passed to Fortran routine in order -to deal with the C/Fortran data ordering issue. F2PY generated wrapper -functions hide the whole issue from an end-user so that translation -between Fortran and C/Python loops and array element access codes is -one-to-one. How the F2PY generated wrappers deal with the issue is -determined by a person who creates a signature file via using -attributes like ``intent(c)``, ``intent(copy|overwrite)``, -``intent(inout|in,out|inplace)`` etc. - -For example, let's consider a typical usage of both F2PY and Pyfort -when wrapping the following simple Fortran code: - -.. include:: simple.f - :literal: - -The comment lines starting with ``cf2py`` are read by F2PY (so that we -don't need to generate/handwrite an intermediate signature file in -this simple case) while for a Fortran compiler they are just comment -lines. - -And here is a Python version of the Fortran code: - -.. include:: pytest.py - :literal: - -To generate a wrapper for subroutine ``foo`` using F2PY, execute:: - - $ f2py -m f2pytest simple.f -c - -that will generate an extension module ``f2pytest`` into the current -directory. - -To generate a wrapper using Pyfort, create the following file - -.. include:: pyforttest.pyf - :literal: - -and execute:: - - $ pyfort pyforttest - -In Pyfort GUI add ``simple.f`` to the list of Fortran sources and -check that the signature file is in free format. And then copy -``pyforttest.so`` from the build directory to the current directory. - -Now, in Python - -.. include:: simple_session.dat - :literal: - -Q: Can Pyfort .pyf files used with F2PY and vice versa? -------------------------------------------------------- - -After some simple modifications, yes. You should take into account the -following differences in Pyfort and F2PY .pyf files. - -+ F2PY signature file contains ``python module`` and ``interface`` - blocks that are equivalent to Pyfort ``module`` block usage. - -+ F2PY attribute ``intent(inplace)`` is equivalent to Pyfort - ``intent(inout)``. F2PY ``intent(inout)`` is a strict (but safe) - version of ``intent(inplace)``, any mismatch in arguments with - expected type, size, or contiguouness will trigger an exception - while ``intent(inplace)`` (dangerously) modifies arguments - attributes in-place. - -Misc -==== - -Q: How to establish which Fortran compiler F2PY will use? ---------------------------------------------------------- - -This question may be releavant when using F2PY in Makefiles. Here -follows a script demonstrating how to determine which Fortran compiler -and flags F2PY will use:: - - # Using post-0.2.2 numpy_distutils - from numpy_distutils.fcompiler import new_fcompiler - compiler = new_fcompiler() # or new_fcompiler(compiler='intel') - compiler.dump_properties() - - # Using pre-0.2.2 numpy_distutils - import os - from numpy_distutils.command.build_flib import find_fortran_compiler - def main(): - fcompiler = os.environ.get('FC_VENDOR') - fcompiler_exec = os.environ.get('F77') - f90compiler_exec = os.environ.get('F90') - fc = find_fortran_compiler(fcompiler, - fcompiler_exec, - f90compiler_exec, - verbose = 0) - print 'FC=',fc.f77_compiler - print 'FFLAGS=',fc.f77_switches - print 'FOPT=',fc.f77_opt - if __name__ == "__main__": - main() - -Users feedback -============== - -Q: Where to find additional information on using F2PY? ------------------------------------------------------- - -There are several F2PY related tutorials, slides, papers, etc -available: - -+ `Fortran to Python Interface Generator with an Application to - Aerospace Engineering`__ by P. Peterson, J. R. R. A. Martins, and - J. J. Alonso in `In Proceedings of the 9th International Python - Conference`__, Long Beach, California, 2001. - -__ http://www.python9.org/p9-cdrom/07/index.htm -__ http://www.python9.org/ - -+ Section `Adding Fortran90 code`__ in the UG of `The Bolometer Data - Analysis Project`__. - -__ http://www.astro.rub.de/laboca/download/boa_master_doc/7_4Adding_Fortran90_code.html -__ http://www.openboa.de/ - -+ Powerpoint presentation `Python for Scientific Computing`__ by Eric - Jones in `The Ninth International Python Conference`__. - -__ http://www.python9.org/p9-jones.ppt -__ http://www.python9.org/ - -+ Paper `Scripting a Large Fortran Code with Python`__ by Alvaro Caceres - Calleja in `International Workshop on Software Engineering for High - Performance Computing System Applications`__. - -__ http://csdl.ics.hawaii.edu/se-hpcs/pdf/calleja.pdf -__ http://csdl.ics.hawaii.edu/se-hpcs/ - -+ Section `Automatic building of C/Fortran extension for Python`__ by - Simon Lacoste-Julien in `Summer 2002 Report about Hybrid Systems - Modelling`__. - -__ http://moncs.cs.mcgill.ca/people/slacoste/research/report/SummerReport.html#tth_sEc3.4 -__ http://moncs.cs.mcgill.ca/people/slacoste/research/report/SummerReport.html - -+ `Scripting for Computational Science`__ by Hans Petter Langtangen - (see the `Mixed language programming`__ and `NumPy array programming`__ - sections for examples on using F2PY). - -__ http://www.ifi.uio.no/~inf3330/lecsplit/ -__ http://www.ifi.uio.no/~inf3330/lecsplit/slide662.html -__ http://www.ifi.uio.no/~inf3330/lecsplit/slide718.html - -+ Chapters 5 and 9 of `Python Scripting for Computational Science`__ - by H. P. Langtangen for case studies on using F2PY. - -__ http://www.springeronline.com/3-540-43508-5 - -+ Section `Fortran Wrapping`__ in `Continuity`__, a computational tool - for continuum problems in bioengineering and physiology. - -__ http://www.continuity.ucsd.edu/cont6_html/docs_fram.html -__ http://www.continuity.ucsd.edu/ - -+ Presentation `PYFORT and F2PY: 2 ways to bind C and Fortran with Python`__ - by Reiner Vogelsang. - -__ http://www.prism.enes.org/WPs/WP4a/Slides/pyfort/pyfort.html - -+ Lecture slides of `Extending Python: speed it up`__. - -__ http://www.astro.uni-bonn.de/~heith/lecture_pdf/friedrich5.pdf - -+ Wiki topics on `Wrapping Tools`__ and `Wrapping Bemchmarks`__ for Climate - System Center at the University of Chicago. - -__ https://geodoc.uchicago.edu/climatewiki/DiscussWrappingTools -__ https://geodoc.uchicago.edu/climatewiki/WrappingBenchmarks - -+ `Performance Python with Weave`__ by Prabhu Ramachandran. - -__ http://www.numpy.org/documentation/weave/weaveperformance.html - -+ `How To Install py-f2py on Mac OSX`__ - -__ http://py-f2py.darwinports.com/ - -Please, let me know if there are any other sites that document F2PY -usage in one or another way. - -Q: What projects use F2PY? --------------------------- - -+ `SciPy: Scientific tools for Python`__ - -__ http://www.numpy.org/ - -+ `The Bolometer Data Analysis Project`__ - -__ http://www.openboa.de/ - -+ `pywavelet`__ - -__ http://www.met.wau.nl/index.html?http://www.met.wau.nl/medewerkers/moenea/python/pywavelet.html - -+ `PyARTS: an ARTS related Python package`__. - -__ http://www.met.ed.ac.uk/~cory/PyARTS/ - -+ `Python interface to PSPLINE`__, a collection of Spline and - Hermite interpolation tools for 1D, 2D, and 3D datasets on - rectilinear grids. - -__ http://pypspline.sourceforge.net - -+ `Markovian Analysis Package for Python`__. - -__ http://pymc.sourceforge.net - -+ `Modular toolkit for Data Processing (MDP)`__ - -__ http://mdp-toolkit.sourceforge.net/ - - -Please, send me a note if you are using F2PY in your project. - -Q: What people think about F2PY? --------------------------------- - -*F2PY is GOOD*: - -Here are some comments people have posted to f2py mailing list and c.l.py: - -+ Ryan Krauss: I really appreciate f2py. It seems weird to say, but I - am excited about relearning FORTRAN to compliment my python stuff. - -+ Fabien Wahl: f2py is great, and is used extensively over here... - -+ Fernando Perez: Anyway, many many thanks for this amazing tool. - - I haven't used pyfort, but I can definitely vouch for the amazing quality of - f2py. And since f2py is actively used by numpy, it won't go unmaintained. - It's quite impressive, and very easy to use. - -+ Kevin Mueller: First off, thanks to those responsible for F2PY; - its been an integral tool of my research for years now. - -+ David Linke: Best regards and thanks for the great tool! - -+ Perrin Meyer: F2Py is really useful! - -+ Hans Petter Langtangen: First of all, thank you for developing - F2py. This is a very important contribution to the scientific - computing community. We are using F2py a lot and are very happy with - it. - -+ Berthold Höllmann: Thank's alot. It seems it is also working in my - 'real' application :-) - -+ John Hunter: At first I wrapped them with f2py (unbelievably easy!)... - -+ Cameron Laird: Among many other features, Python boasts a mature - f2py, which makes it particularly rewarding to yoke Fortran- and - Python-coded modules into finished applications. - -+ Ryan Gutenkunst: f2py is sweet magic. - -*F2PY is BAD*: - -+ `Is it worth using on a large scale python drivers for Fortran - subroutines, interfaced with f2py?`__ - -__ http://sepwww.stanford.edu/internal/computing/python.html - -Additional comments on F2PY, good or bad, are welcome! - -.. References: -.. _README.txt: index.html -.. _HISTORY.txt: HISTORY.html -.. _HISTORY.txt in CVS: http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt?rev=HEAD&content-type=text/x-cvsweb-markup -.. _TESTING.txt: TESTING.html diff --git a/numpy/f2py/docs/HISTORY.txt b/numpy/f2py/docs/HISTORY.txt deleted file mode 100644 index 72b683eb0..000000000 --- a/numpy/f2py/docs/HISTORY.txt +++ /dev/null @@ -1,1044 +0,0 @@ -.. -*- rest -*- - -========================= - F2PY History -========================= - -:Author: Pearu Peterson <pearu@cens.ioc.ee> -:Web-site: http://cens.ioc.ee/projects/f2py2e/ -:Date: $Date: 2005/09/16 08:36:45 $ -:Revision: $Revision: 1.191 $ - -.. Contents:: - -Release 2.46.243 -===================== - -* common_rules.py - - - Fixed compiler warnings. - -* fortranobject.c - - - Fixed another dims calculation bug. - - Fixed dims calculation bug and added the corresponding check. - - Accept higher dimensional arrays if their effective rank matches. - Effective rank is multiplication of non-unit dimensions. - -* f2py2e.py - - - Added support for numpy.distutils version 0.4.0. - -* Documentation - - - Added example about ``intent(callback,hide)`` usage. Updates. - - Updated FAQ. - -* cb_rules.py - - - Fixed missing need kw error. - - Fixed getting callback non-existing extra arguments. - - External callback functions and extra_args can be set via - ext.module namespace. - - Avoid crash when external callback function is not set. - -* rules.py - - - Enabled ``intent(out)`` for ``intent(aux)`` non-complex scalars. - - Fixed splitting lines in F90 fixed form mode. - - Fixed FORTRANAME typo, relevant when wrapping scalar functions with - ``--no-wrap-functions``. - - Improved failure handling for callback functions. - - Fixed bug in writting F90 wrapper functions when a line length - is exactly 66. - -* cfuncs.py - - - Fixed dependency issue with typedefs. - - Introduced ``-DUNDERSCORE_G77`` that cause extra underscore to be - used for external names that contain an underscore. - -* capi_maps.py - - - Fixed typos. - - Fixed using complex cb functions. - -* crackfortran.py - - - Introduced parent_block key. Get ``use`` statements recursively - from parent blocks. - - Apply parameter values to kindselectors. - - Fixed bug evaluating ``selected_int_kind`` function. - - Ignore Name and Syntax errors when evaluating scalars. - - Treat ``<int>_intType`` as ``<int>`` in get_parameters. - - Added support for F90 line continuation in fix format mode. - - Include optional attribute of external to signature file. - - Add ``entry`` arguments to variable lists. - - Treat \xa0 character as space. - - Fixed bug where __user__ callback subroutine was added to its - argument list. - - In strict 77 mode read only the first 72 columns. - - Fixed parsing ``v(i) = func(r)``. - - Fixed parsing ``integer*4::``. - - Fixed parsing ``1.d-8`` when used as a parameter value. - -Release 2.45.241_1926 -===================== - -* diagnose.py - - - Clean up output. - -* cb_rules.py - - - Fixed ``_cpointer`` usage for subroutines. - - Fortran function ``_cpointer`` can be used for callbacks. - -* func2subr.py - - - Use result name when wrapping functions with subroutines. - -* f2py2e.py - - - Fixed ``--help-link`` switch. - - Fixed ``--[no-]lower`` usage with ``-c`` option. - - Added support for ``.pyf.src`` template files. - -* __init__.py - - - Using ``exec_command`` in ``compile()``. - -* setup.py - - - Clean up. - - Disabled ``need_numpy_distutils`` function. From now on it is assumed - that proper version of ``numpy_distutils`` is already installed. - -* capi_maps.py - - - Added support for wrapping unsigned integers. In a .pyf file - ``integer(-1)``, ``integer(-2)``, ``integer(-4)`` correspond to - ``unsigned char``, ``unsigned short``, ``unsigned`` C types, - respectively. - -* tests/c/return_real.py - - - Added tests to wrap C functions returning float/double. - -* fortranobject.c - - - Added ``_cpointer`` attribute to wrapped objects. - -* rules.py - - - ``_cpointer`` feature for wrapped module functions is not - functional at the moment. - - Introduced ``intent(aux)`` attribute. Useful to save a value - of a parameter to auxiliary C variable. Note that ``intent(aux)`` - implies ``intent(c)``. - - Added ``usercode`` section. When ``usercode`` is used in ``python - module`` block twise then the contents of the second multi-line - block is inserted after the definition of external routines. - - Call-back function arguments can be CObjects. - -* cfuncs.py - - - Allow call-back function arguments to be fortran objects. - - Allow call-back function arguments to be built-in functions. - -* crackfortran.py - - - Fixed detection of a function signature from usage example. - - Cleaned up -h output for intent(callback) variables. - - Repair malformed argument list (missing argument name). - - Warn on the usage of multiple attributes without type specification. - - Evaluate only scalars ``<initexpr>`` (e.g. not of strings). - - Evaluate ``<initexpr>`` using parameters name space. - - Fixed resolving `<name>(<args>)[result(<result>)]` pattern. - - ``usercode`` can be used more than once in the same context. - -Release 2.43.239_1831 -===================== - -* auxfuncs.py - - - Made ``intent(in,inplace)`` to mean ``intent(inplace)``. - -* f2py2e.py - - - Intoduced ``--help-link`` and ``--link-<resource>`` - switches to link generated extension module with system - ``<resource>`` as defined by numpy_distutils/system_info.py. - -* fortranobject.c - - - Patch to make PyArray_CanCastSafely safe on 64-bit machines. - Fixes incorrect results when passing ``array('l')`` to - ``real*8 intent(in,out,overwrite)`` arguments. - -* rules.py - - - Avoid empty continuation lines in Fortran wrappers. - -* cfuncs.py - - - Adding ``\0`` at the end of a space-padded string, fixes tests - on 64-bit Gentoo. - -* crackfortran.py - - - Fixed splitting lines with string parameters. - -Release 2.43.239_1806 -===================== - -* Tests - - - Fixed test site that failed after padding strings with spaces - instead of zeros. - -* Documentation - - - Documented ``intent(inplace)`` attribute. - - Documented ``intent(callback)`` attribute. - - Updated FAQ, added Users Feedback section. - -* cfuncs.py - - - Padding longer (than provided from Python side) strings with spaces - (that is Fortran behavior) instead of nulls (that is C strncpy behavior). - -* f90mod_rules.py - - - Undoing rmbadnames in Python and Fortran layers. - -* common_rules.py - - - Renaming common block items that have names identical to C keywords. - - Fixed wrapping blank common blocks. - -* fortranobject.h - - - Updated numarray (0.9, 1.0, 1.1) support (patch by Todd Miller). - -* fortranobject.c - - - Introduced ``intent(inplace)`` feature. - - Fix numarray reference counts (patch by Todd). - - Updated numarray (0.9, 1.0, 1.1) support (patch by Todd Miller). - - Enabled F2PY_REPORT_ON_ARRAY_COPY for Numarray. - -* capi_maps.py - - - Always normalize .f2py_f2cmap keys to lower case. - -* rules.py - - - Disabled ``index`` macro as it conflicts with the one defined - in string.h. - - Moved ``externroutines`` up to make it visible to ``usercode``. - - Fixed bug in f90 code generation: no empty line continuation is - allowed. - - Fixed undefined symbols failure when ``fortranname`` is used - to rename a wrapped function. - - Support for ``entry`` statement. - -* auxfuncs.py - - - Made is* functions more robust with respect to parameters that - have no typespec specified. - - Using ``size_t`` instead of ``int`` as the type of string - length. Fixes issues on 64-bit platforms. - -* setup.py - - - Fixed bug of installing ``f2py`` script as ``.exe`` file. - -* f2py2e.py - - - ``--compiler=`` and ``--fcompiler=`` can be specified at the same time. - -* crackfortran.py - - - Fixed dependency detection for non-intent(in|inout|inplace) arguments. - They must depend on their dimensions, not vice-versa. - - Don't match ``!!f2py`` as a start of f2py directive. - - Only effective intent attributes will be output to ``-h`` target. - - Introduced ``intent(callback)`` to build interface between Python - functions and Fortran external routines. - - Avoid including external arguments to __user__ modules. - - Initial hooks to evaluate ``kind`` and ``selected_int_kind``. - - Evaluating parameters in {char,kind}selectors and applying rmbadname. - - Evaluating parameters using also module parameters. Fixed the order - of parameter evaluation. - - Fixed silly bug: when block name was not lower cased, it was not - recognized correctly. - - Applying mapping '.false.'->'False', '.true.'->'True' to logical - parameters. TODO: Support for logical expressions is needed. - - Added support for multiple statements in one line (separated with semicolon). - - Impl. get_useparameters function for using parameter values from - other f90 modules. - - Applied Bertholds patch to fix bug in evaluating expressions - like ``1.d0/dvar``. - - Fixed bug in reading string parameters. - - Evaluating parameters in charselector. Code cleanup. - - Using F90 module parameters to resolve kindselectors. - - Made the evaluation of module data init-expression more robust. - - Support for ``entry`` statement. - - Fixed ``determineexprtype`` that in the case of parameters - returned non-dictionary objects. - - Use ``-*- fix -*-`` to specify that a file is in fixed format. - -Release 2.39.235_1693 -===================== - -* fortranobject.{h,c} - - - Support for allocatable string arrays. - -* cfuncs.py - - - Call-back arguments can now be also instances that have ``__call__`` method - as well as instance methods. - -* f2py2e.py - - - Introduced ``--include_paths <path1>:<path2>:..`` command line - option. - - Added ``--compiler=`` support to change the C/C++ compiler from - f2py command line. - -* capi_maps.py - - - Handle ``XDY`` parameter constants. - -* crackfortran.py - - - Handle ``XDY`` parameter constants. - - - Introduced formatpattern to workaround a corner case where reserved - keywords are used in format statement. Other than that, format pattern - has no use. - - - Parameters are now fully evaluated. - -* More splitting of documentation strings. - -* func2subr.py - fixed bug for function names that f77 compiler - would set ``integer`` type. - -Release 2.39.235_1660 -===================== - -* f2py2e.py - - - Fixed bug in using --f90flags=.. - -* f90mod_rules.py - - - Splitted generated documentation strings (to avoid MSVC issue when - string length>2k) - - - Ignore ``private`` module data. - -Release 2.39.235_1644 -===================== - -:Date:24 February 2004 - -* Character arrays: - - - Finished complete support for character arrays and arrays of strings. - - ``character*n a(m)`` is treated like ``character a(m,n)`` with ``intent(c)``. - - Character arrays are now considered as ordinary arrays (not as arrays - of strings which actually didn't work). - -* docs - - - Initial f2py manpage file f2py.1. - - Updated usersguide and other docs when using numpy_distutils 0.2.2 - and up. - -* capi_maps.py - - - Try harder to use .f2py_f2cmap mappings when kind is used. - -* crackfortran.py - - - Included files are first search in the current directory and - then from the source file directory. - - Ignoring dimension and character selector changes. - - Fixed bug in Fortran 90 comments of fixed format. - - Warn when .pyf signatures contain undefined symbols. - - Better detection of source code formats. Using ``-*- fortran -*-`` - or ``-*- f90 -*-`` in the first line of a Fortran source file is - recommended to help f2py detect the format, fixed or free, - respectively, correctly. - -* cfuncs.py - - - Fixed intent(inout) scalars when typecode=='l'. - - Fixed intent(inout) scalars when not using numarray. - - Fixed intent(inout) scalars when using numarray. - -* diagnose.py - - - Updated for numpy_distutils 0.2.2 and up. - - Added numarray support to diagnose. - -* fortranobject.c - - - Fixed nasty bug with intent(in,copy) complex slice arrays. - - Applied Todd's patch to support numarray's byteswapped or - misaligned arrays, requires numarray-0.8 or higher. - -* f2py2e.py - - - Applying new hooks for numpy_distutils 0.2.2 and up, keeping - backward compatibility with depreciation messages. - - Using always os.system on non-posix platforms in f2py2e.compile - function. - -* rules.py - - - Changed the order of buildcallback and usercode junks. - -* setup.cfg - - - Added so that docs/ and tests/ directories are included to RPMs. - -* setup.py - - - Installing f2py.py instead of f2py.bat under NT. - - Introduced ``--with-numpy_distutils`` that is useful when making - f2py tar-ball with numpy_distutils included. - -Release 2.37.233-1545 -===================== - -:Date: 11 September 2003 - -* rules.py - - - Introduced ``interface_usercode`` replacement. When ``usercode`` - statement is used inside the first interface block, its contents - will be inserted at the end of initialization function of a F2PY - generated extension module (feature request: Berthold Höllmann). - - Introduced auxiliary function ``as_column_major_storage`` that - converts input array to an array with column major storage order - (feature request: Hans Petter Langtangen). - -* crackfortran.py - - - Introduced ``pymethoddef`` statement. - -* cfuncs.py - - - Fixed "#ifdef in #define TRYPYARRAYTEMPLATE" bug (patch thanks - to Bernhard Gschaider) - -* auxfuncs.py - - - Introduced ``getpymethod`` function. - - Enabled multi-line blocks in ``callprotoargument`` statement. - -* f90mod_rules.py - - - Undone "Fixed Warning 43 emitted by Intel Fortran compiler" that - causes (curios) segfaults. - -* fortranobject.c - - - Fixed segfaults (that were introduced with recent memory leak - fixes) when using allocatable arrays. - - Introduced F2PY_REPORT_ON_ARRAY_COPY CPP macro int-variable. If defined - then a message is printed to stderr whenever a copy of an array is - made and arrays size is larger than F2PY_REPORT_ON_ARRAY_COPY. - -Release 2.35.229-1505 -===================== - -:Date: 5 August 2003 - -* General - - - Introduced ``usercode`` statement (dropped ``c_code`` hooks). - -* setup.py - - - Updated the CVS location of numpy_distutils. - -* auxfuncs.py - - - Introduced ``isint1array(var)`` for fixing ``integer*1 intent(out)`` - support. - -* tests/f77/callback.py - - Introduced some basic tests. - -* src/fortranobject.{c,h} - - - Fixed memory leaks when getting/setting allocatable arrays. - (Bug report by Bernhard Gschaider) - - - Initial support for numarray (Todd Miller's patch). Use -DNUMARRAY - on the f2py command line to enable numarray support. Note that - there is no character arrays support and these hooks are not - tested with F90 compilers yet. - -* cfuncs.py - - - Fixed reference counting bug that appeared when constructing extra - argument list to callback functions. - - Added ``PyArray_LONG != PyArray_INT`` test. - -* f2py2e.py - - Undocumented ``--f90compiler``. - -* crackfortran.py - - - Introduced ``usercode`` statement. - - Fixed newlines when outputting multi-line blocks. - - Optimized ``getlincoef`` loop and ``analyzevars`` for cases where - len(vars) is large. - - Fixed callback string argument detection. - - Fixed evaluating expressions: only int|float expressions are - evaluated succesfully. - -* docs - - Documented -DF2PY_REPORT_ATEXIT feature. - -* diagnose.py - - Added CPU information and sys.prefix printout. - -* tests/run_all.py - - Added cwd to PYTHONPATH. - -* tests/f??/return_{real,complex}.py - - Pass "infinity" check in SunOS. - -* rules.py - - - Fixed ``integer*1 intent(out)`` support - - Fixed free format continuation of f2py generated F90 files. - -* tests/mixed/ - - Introduced tests for mixing Fortran 77, Fortran 90 fixed and free - format codes in one module. - -* f90mod_rules.py - - - Fixed non-prototype warnings. - - Fixed Warning 43 emitted by Intel Fortran compiler. - - Avoid long lines in Fortran codes to reduce possible problems with - continuations of lines. - -Public Release 2.32.225-1419 -============================ - -:Date: 8 December 2002 - -* docs/usersguide/ - - Complete revision of F2PY Users Guide - -* tests/run_all.py - - - New file. A Python script to run all f2py unit tests. - -* Removed files: buildmakefile.py, buildsetup.py. - -* tests/f77/ - - - Added intent(out) scalar tests. - -* f2py_testing.py - - - Introduced. It contains jiffies, memusage, run, cmdline functions - useful for f2py unit tests site. - -* setup.py - - - Install numpy_distutils only if it is missing or is too old - for f2py. - -* f90modrules.py - - - Fixed wrapping f90 module data. - - Fixed wrapping f90 module subroutines. - - Fixed f90 compiler warnings for wrapped functions by using interface - instead of external stmt for functions. - -* tests/f90/ - - - Introduced return_*.py tests. - -* func2subr.py - - - Added optional signature argument to createfuncwrapper. - - In f2pywrappers routines, declare external, scalar, remaining - arguments in that order. Fixes compiler error 'Invalid declaration' - for:: - - real function foo(a,b) - integer b - real a(b) - end - -* crackfortran.py - - - Removed first-line comment information support. - - Introduced multiline block. Currently usable only for - ``callstatement`` statement. - - Improved array length calculation in getarrlen(..). - - "From sky" program group is created only if ``groupcounter<1``. - See TODO.txt. - - Added support for ``dimension(n:*)``, ``dimension(*:n)``. They are - treated as ``dimesnion(*)`` by f2py. - - Fixed parameter substitution (this fixes TODO item by Patrick - LeGresley, 22 Aug 2001). - -* f2py2e.py - - - Disabled all makefile, setup, manifest file generation hooks. - - Disabled --[no]-external-modroutines option. All F90 module - subroutines will have Fortran/C interface hooks. - - --build-dir can be used with -c option. - - only/skip modes can be used with -c option. - - Fixed and documented `-h stdout` feature. - - Documented extra options. - - Introduced --quiet and --verbose flags. - -* cb_rules.py - - - Fixed debugcapi hooks for intent(c) scalar call-back arguments - (bug report: Pierre Schnizer). - - Fixed intent(c) for scalar call-back arguments. - - Improved failure reports. - -* capi_maps.py - - - Fixed complex(kind=..) to C type mapping bug. The following hold - complex==complex(kind=4)==complex*8, complex(kind=8)==complex*16 - - Using signed_char for integer*1 (bug report: Steve M. Robbins). - - Fixed logical*8 function bug: changed its C correspondence to - long_long. - - Fixed memory leak when returning complex scalar. - -* __init__.py - - - Introduced a new function (for f2py test site, but could be useful - in general) ``compile(source[,modulename,extra_args])`` for - compiling fortran source codes directly from Python. - -* src/fortranobject.c - - - Multi-dimensional common block members and allocatable arrays - are returned as Fortran-contiguous arrays. - - Fixed NULL return to Python without exception. - - Fixed memory leak in getattr(<fortranobj>,'__doc__'). - - <fortranobj>.__doc__ is saved to <fortranobj>.__dict__ (previously - it was generated each time when requested). - - Fixed a nasty typo from the previous item that caused data - corruption and occasional SEGFAULTs. - - array_from_pyobj accepts arbitrary rank arrays if the last dimension - is undefined. E.g. dimension(3,*) accepts a(3,4,5) and the result is - array with dimension(3,20). - - Fixed (void*) casts to make g++ happy (bug report: eric). - - Changed the interface of ARR_IS_NULL macro to avoid "``NULL used in - arithmetics``" warnings from g++. - -* src/fortranobject.h - - - Undone previous item. Defining NO_IMPORT_ARRAY for - src/fortranobject.c (bug report: travis) - - Ensured that PY_ARRAY_UNIQUE_SYMBOL is defined only for - src/fortranobject.c (bug report: eric). - -* rules.py - - - Introduced dummy routine feature. - - F77 and F90 wrapper subroutines (if any) as saved to different - files, <modulename>-f2pywrappers.f and <modulename>-f2pywrappers2.f90, - respectively. Therefore, wrapping F90 requires numpy_distutils >= - 0.2.0_alpha_2.229. - - Fixed compiler warnings about meaningless ``const void (*f2py_func)(..)``. - - Improved error messages for ``*_from_pyobj``. - - Changed __CPLUSPLUS__ macros to __cplusplus (bug report: eric). - - Changed (void*) casts to (f2py_init_func) (bug report: eric). - - Removed unnecessary (void*) cast for f2py_has_column_major_storage - in f2py_module_methods definition (bug report: eric). - - Changed the interface of f2py_has_column_major_storage function: - removed const from the 1st argument. - -* cfuncs.py - - - Introduced -DPREPEND_FORTRAN. - - Fixed bus error on SGI by using PyFloat_AsDouble when ``__sgi`` is defined. - This seems to be `know bug`__ with Python 2.1 and SGI. - - string_from_pyobj accepts only arrays whos elements size==sizeof(char). - - logical scalars (intent(in),function) are normalized to 0 or 1. - - Removed NUMFROMARROBJ macro. - - (char|short)_from_pyobj now use int_from_pyobj. - - (float|long_double)_from_pyobj now use double_from_pyobj. - - complex_(float|long_double)_from_pyobj now use complex_double_from_pyobj. - - Rewrote ``*_from_pyobj`` to be more robust. This fixes segfaults if - getting * from a string. Note that int_from_pyobj differs - from PyNumber_Int in that it accepts also complex arguments - (takes the real part) and sequences (takes the 1st element). - - Removed unnecessary void* casts in NUMFROMARROBJ. - - Fixed casts in ``*_from_pyobj`` functions. - - Replaced CNUMFROMARROBJ with NUMFROMARROBJ. - -.. __: http://sourceforge.net/tracker/index.php?func=detail&aid=435026&group_id=5470&atid=105470 - -* auxfuncs.py - - - Introduced isdummyroutine(). - - Fixed islong_* functions. - - Fixed isintent_in for intent(c) arguments (bug report: Pierre Schnizer). - - Introduced F2PYError and throw_error. Using throw_error, f2py - rejects illegal .pyf file constructs that otherwise would cause - compilation failures or python crashes. - - Fixed islong_long(logical*8)->True. - - Introduced islogical() and islogicalfunction(). - - Fixed prototype string argument (bug report: eric). - -* Updated README.txt and doc strings. Starting to use docutils. - -* Speed up for ``*_from_pyobj`` functions if obj is a sequence. - -* Fixed SegFault (reported by M.Braun) due to invalid ``Py_DECREF`` - in ``GETSCALARFROMPYTUPLE``. - -Older Releases -============== - -:: - - *** Fixed missing includes when wrapping F90 module data. - *** Fixed typos in docs of build_flib options. - *** Implemented prototype calculator if no callstatement or - callprotoargument statements are used. A warning is issued if - callstatement is used without callprotoargument. - *** Fixed transposing issue with array arguments in callback functions. - *** Removed -pyinc command line option. - *** Complete tests for Fortran 77 functions returning scalars. - *** Fixed returning character bug if --no-wrap-functions. - *** Described how to wrap F compiled Fortran F90 module procedures - with F2PY. See doc/using_F_compiler.txt. - *** Fixed the order of build_flib options when using --fcompiler=... - *** Recognize .f95 and .F95 files as Fortran sources with free format. - *** Cleaned up the output of 'f2py -h': removed obsolete items, - added build_flib options section. - *** Added --help-compiler option: it lists available Fortran compilers - as detected by numpy_distutils/command/build_flib.py. This option - is available only with -c option. - - -:Release: 2.13.175-1250 -:Date: 4 April 2002 - -:: - - *** Fixed copying of non-contigious 1-dimensional arrays bug. - (Thanks to Travis O.). - - -:Release: 2.13.175-1242 -:Date: 26 March 2002 - -:: - - *** Fixed ignoring type declarations. - *** Turned F2PY_REPORT_ATEXIT off by default. - *** Made MAX,MIN macros available by default so that they can be - always used in signature files. - *** Disabled F2PY_REPORT_ATEXIT for FreeBSD. - - -:Release: 2.13.175-1233 -:Date: 13 March 2002 - -:: - - *** Fixed Win32 port when using f2py.bat. (Thanks to Erik Wilsher). - *** F2PY_REPORT_ATEXIT is disabled for MACs. - *** Fixed incomplete dependency calculator. - - -:Release: 2.13.175-1222 -:Date: 3 March 2002 - -:: - - *** Plugged a memory leak for intent(out) arrays with overwrite=0. - *** Introduced CDOUBLE_to_CDOUBLE,.. functions for copy_ND_array. - These cast functions probably work incorrectly in Numeric. - - -:Release: 2.13.175-1212 -:Date: 23 February 2002 - -:: - - *** Updated f2py for the latest numpy_distutils. - *** A nasty bug with multi-dimensional Fortran arrays is fixed - (intent(out) arrays had wrong shapes). (Thanks to Eric for - pointing out this bug). - *** F2PY_REPORT_ATEXIT is disabled by default for __WIN32__. - - -:Release: 2.11.174-1161 -:Date: 14 February 2002 - -:: - - *** Updated f2py for the latest numpy_distutils. - *** Fixed raise error when f2py missed -m flag. - *** Script name `f2py' now depends on the name of python executable. - For example, `python2.2 setup.py install' will create a f2py - script with a name `f2py2.2'. - *** Introduced 'callprotoargument' statement so that proper prototypes - can be declared. This is crucial when wrapping C functions as it - will fix segmentation faults when these wrappers use non-pointer - arguments (thanks to R. Clint Whaley for explaining this to me). - Note that in f2py generated wrapper, the prototypes have - the following forms: - extern #rtype# #fortranname#(#callprotoargument#); - or - extern #rtype# F_FUNC(#fortranname#,#FORTRANNAME#)(#callprotoargument#); - *** Cosmetic fixes to F2PY_REPORT_ATEXIT feature. - - -:Release: 2.11.174-1146 -:Date: 3 February 2002 - -:: - - *** Reviewed reference counting in call-back mechanism. Fixed few bugs. - *** Enabled callstatement for complex functions. - *** Fixed bug with initializing capi_overwrite_<varname> - *** Introduced intent(overwrite) that is similar to intent(copy) but - has opposite effect. Renamed copy_<name>=1 to overwrite_<name>=0. - intent(overwrite) will make default overwrite_<name>=1. - *** Introduced intent(in|inout,out,out=<name>) attribute that renames - arguments name when returned. This renaming has effect only in - documentation strings. - *** Introduced 'callstatement' statement to pyf file syntax. With this - one can specify explicitly how wrapped function should be called - from the f2py generated module. WARNING: this is a dangerous feature - and should be used with care. It is introduced to provide a hack - to construct wrappers that may have very different signature - pattern from the wrapped function. Currently 'callstatement' can - be used only inside a subroutine or function block (it should be enough - though) and must be only in one continuous line. The syntax of the - statement is: callstatement <C-expression>; - - -:Release: 2.11.174 -:Date: 18 January 2002 - -:: - - *** Fixed memory-leak for PyFortranObject. - *** Introduced extra keyword argument copy_<varname> for intent(copy) - variables. It defaults to 1 and forces to make a copy for - intent(in) variables when passing on to wrapped functions (in case - they undesirably change the variable in-situ). - *** Introduced has_column_major_storage member function for all f2py - generated extension modules. It is equivalent to Python call - 'transpose(obj).iscontiguous()' but very efficient. - *** Introduced -DF2PY_REPORT_ATEXIT. If this is used when compiling, - a report is printed to stderr as python exits. The report includes - the following timings: - 1) time spent in all wrapped function calls; - 2) time spent in f2py generated interface around the wrapped - functions. This gives a hint whether one should worry - about storing data in proper order (C or Fortran). - 3) time spent in Python functions called by wrapped functions - through call-back interface. - 4) time spent in f2py generated call-back interface. - For now, -DF2PY_REPORT_ATEXIT is enabled by default. Use - -DF2PY_REPORT_ATEXIT_DISABLE to disable it (I am not sure if - Windows has needed tools, let me know). - Also, I appreciate if you could send me the output of 'F2PY - performance report' (with CPU and platform information) so that I - could optimize f2py generated interfaces for future releases. - *** Extension modules can be linked with dmalloc library. Use - -DDMALLOC when compiling. - *** Moved array_from_pyobj to fortranobject.c. - *** Usage of intent(inout) arguments is made more strict -- only - with proper type contiguous arrays are accepted. In general, - you should avoid using intent(inout) attribute as it makes - wrappers of C and Fortran functions asymmetric. I recommend using - intent(in,out) instead. - *** intent(..) has new keywords: copy,cache. - intent(copy,in) - forces a copy of an input argument; this - may be useful for cases where the wrapped function changes - the argument in situ and this may not be desired side effect. - Otherwise, it is safe to not use intent(copy) for the sake - of a better performance. - intent(cache,hide|optional) - just creates a junk of memory. - It does not care about proper storage order. Can be also - intent(in) but then the corresponding argument must be a - contiguous array with a proper elsize. - *** intent(c) can be used also for subroutine names so that - -DNO_APPEND_FORTRAN can be avoided for C functions. - - *** IMPORTANT BREAKING GOOD ... NEWS!!!: - - From now on you don't have to worry about the proper storage order - in multi-dimensional arrays that was earlier a real headache when - wrapping Fortran functions. Now f2py generated modules take care - of the proper conversations when needed. I have carefully designed - and optimized this interface to avoid any unnecessary memory usage - or copying of data. However, it is wise to use input arrays that - has proper storage order: for C arguments it is row-major and for - Fortran arguments it is column-major. But you don't need to worry - about that when developing your programs. The optimization of - initializing the program with proper data for possibly better - memory usage can be safely postponed until the program is working. - - This change also affects the signatures in .pyf files. If you have - created wrappers that take multi-dimensional arrays in arguments, - it is better to let f2py re-generate these files. Or you have to - manually do the following changes: reverse the axes indices in all - 'shape' macros. For example, if you have defined an array A(n,m) - and n=shape(A,1), m=shape(A,0) then you must change the last - statements to n=shape(A,0), m=shape(A,1). - - -:Release: 2.8.172 -:Date: 13 January 2002 - -:: - - *** Fixed -c process. Removed pyf_extensions function and pyf_file class. - *** Reorganized setup.py. It generates f2py or f2py.bat scripts - depending on the OS and the location of the python executable. - *** Started to use update_version from numpy_distutils that makes - f2py startup faster. As a side effect, the version number system - changed. - *** Introduced test-site/test_f2py2e.py script that runs all - tests. - *** Fixed global variables initialization problem in crackfortran - when run_main is called several times. - *** Added 'import Numeric' to C/API init<module> function. - *** Fixed f2py.bat in setup.py. - *** Switched over to numpy_distutils and dropped fortran_support. - *** On Windows create f2py.bat file. - *** Introduced -c option: read fortran or pyf files, construct extension - modules, build, and save them to current directory. - In one word: do-it-all-in-one-call. - *** Introduced pyf_extensions(sources,f2py_opts) function. It simplifies - the extension building process considerably. Only for internal use. - *** Converted tests to use numpy_distutils in order to improve portability: - a,b,c - *** f2py2e.run_main() returns a pyf_file class instance containing - information about f2py generated files. - *** Introduced `--build-dir <dirname>' command line option. - *** Fixed setup.py for bdist_rpm command. - *** Added --numpy-setup command line option. - *** Fixed crackfortran that did not recognized capitalized type - specification with --no-lower flag. - *** `-h stdout' writes signature to stdout. - *** Fixed incorrect message for check() with empty name list. - - -:Release: 2.4.366 -:Date: 17 December 2001 - -:: - - *** Added command line option --[no-]manifest. - *** `make test' should run on Windows, but the results are not truthful. - *** Reorganized f2py2e.py a bit. Introduced run_main(comline_list) function - that can be useful when running f2py from another Python module. - *** Removed command line options -f77,-fix,-f90 as the file format - is determined from the extension of the fortran file - or from its header (first line starting with `!%' and containing keywords - free, fix, or f77). The later overrides the former one. - *** Introduced command line options --[no-]makefile,--[no-]latex-doc. - Users must explicitly use --makefile,--latex-doc if Makefile-<modulename>, - <modulename>module.tex is desired. --setup is default. Use --no-setup - to disable setup_<modulename>.py generation. --overwrite-makefile - will set --makefile. - *** Added `f2py_rout_' to #capiname# in rules.py. - *** intent(...) statement with empty namelist forces intent(...) attribute for - all arguments. - *** Dropped DL_IMPORT and DL_EXPORT in fortranobject.h. - *** Added missing PyFortran_Type.ob_type initialization. - *** Added gcc-3.0 support. - *** Raising non-existing/broken Numeric as a FatalError exception. - *** Fixed Python 2.x specific += construct in fortran_support.py. - *** Fixed copy_ND_array for 1-rank arrays that used to call calloc(0,..) - and caused core dump with a non-gcc compiler (Thanks to Pierre Schnizer - for reporting this bug). - *** Fixed "warning: variable `..' might be clobbered by `longjmp' or `vfork'": - - Reorganized the structure of wrapper functions to get rid of - `goto capi_fail' statements that caused the above warning. - - -:Release: 2.3.343 -:Date: 12 December 2001 - -:: - - *** Issues with the Win32 support (thanks to Eric Jones and Tiffany Kamm): - - Using DL_EXPORT macro for init#modulename#. - - Changed PyObject_HEAD_INIT(&PyType_Type) to PyObject_HEAD_INIT(0). - - Initializing #name#_capi=NULL instead of Py_None in cb hooks. - *** Fixed some 'warning: function declaration isn't a prototype', mainly - in fortranobject.{c,h}. - *** Fixed 'warning: missing braces around initializer'. - *** Fixed reading a line containing only a label. - *** Fixed nonportable 'cp -fv' to shutil.copy in f2py2e.py. - *** Replaced PyEval_CallObject with PyObject_CallObject in cb_rules. - *** Replaced Py_DECREF with Py_XDECREF when freeing hidden arguments. - (Reason: Py_DECREF caused segfault when an error was raised) - *** Impl. support for `include "file"' (in addition to `include 'file'') - *** Fixed bugs (buildsetup.py missing in Makefile, in generated MANIFEST.in) - - -:Release: 2.3.327 -:Date: 4 December 2001 - -:: - - *** Sending out the third public release of f2py. - *** Support for Intel(R) Fortran Compiler (thanks to Patrick LeGresley). - *** Introduced `threadsafe' statement to pyf-files (or to be used with - the 'f2py' directive in fortran codes) to force - Py_BEGIN|END_ALLOW_THREADS block around the Fortran subroutine - calling statement in Python C/API. `threadsafe' statement has - an effect only inside a subroutine block. - *** Introduced `fortranname <name>' statement to be used only within - pyf-files. This is useful when the wrapper (Python C/API) function - has different name from the wrapped (Fortran) function. - *** Introduced `intent(c)' directive and statement. It is useful when - wrapping C functions. Use intent(c) for arguments that are - scalars (not pointers) or arrays (with row-ordering of elements). - - -:Release: 2.3.321 -:Date: 3 December 2001 - -:: - - *** f2py2e can be installed using distutils (run `python setup.py install'). - *** f2py builds setup_<modulename>.py. Use --[no-]setup to control this - feature. setup_<modulename>.py uses fortran_support module (from SciPy), - but for your convenience it is included also with f2py as an additional - package. Note that it has not as many compilers supported as with - using Makefile-<modulename>, but new compilers should be added to - fortran_support module, not to f2py2e package. - *** Fixed some compiler warnings about else statements. - diff --git a/numpy/f2py/docs/OLDNEWS.txt b/numpy/f2py/docs/OLDNEWS.txt deleted file mode 100644 index 401d2dcee..000000000 --- a/numpy/f2py/docs/OLDNEWS.txt +++ /dev/null @@ -1,63 +0,0 @@ - -.. topic:: Old F2PY NEWS - - March 30, 2004 - F2PY bug fix release (version 2.39.235-1693). Two new command line switches: - ``--compiler`` and ``--include_paths``. Support for allocatable string arrays. - Callback arguments may now be arbitrary callable objects. Win32 installers - for F2PY and Scipy_core are provided. - `Differences with the previous release (version 2.37.235-1660)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.98&r2=1.87&f=h - - - March 9, 2004 - F2PY bug fix release (version 2.39.235-1660). - `Differences with the previous release (version 2.37.235-1644)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.87&r2=1.83&f=h - - February 24, 2004 - Latest F2PY release (version 2.39.235-1644). - Support for numpy_distutils 0.2.2 and up (e.g. compiler flags can be - changed via f2py command line options). Implemented support for - character arrays and arrays of strings (e.g. ``character*(*) a(m,..)``). - *Important bug fixes regarding complex arguments, upgrading is - highly recommended*. Documentation updates. - `Differences with the previous release (version 2.37.233-1545)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.83&r2=1.58&f=h - - September 11, 2003 - Latest F2PY release (version 2.37.233-1545). - New statements: ``pymethoddef`` and ``usercode`` in interface blocks. - New function: ``as_column_major_storage``. - New CPP macro: ``F2PY_REPORT_ON_ARRAY_COPY``. - Bug fixes. - `Differences with the previous release (version 2.35.229-1505)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.58&r2=1.49&f=h - - August 2, 2003 - Latest F2PY release (version 2.35.229-1505). - `Differences with the previous release (version 2.32.225-1419)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.49&r2=1.28&f=h - - April 2, 2003 - Initial support for Numarray_ (thanks to Todd Miller). - - December 8, 2002 - Sixth public release of F2PY (version 2.32.225-1419). Comes with - revised `F2PY Users Guide`__, `new testing site`__, lots of fixes - and other improvements, see `HISTORY.txt`_ for details. - - __ usersguide/index.html - __ TESTING.txt_ - -.. References - ========== - -.. _HISTORY.txt: HISTORY.html -.. _Numarray: http://www.stsci.edu/resources/software_hardware/numarray -.. _TESTING.txt: TESTING.html
\ No newline at end of file diff --git a/numpy/f2py/docs/README.txt b/numpy/f2py/docs/README.txt deleted file mode 100644 index cec8a6ec0..000000000 --- a/numpy/f2py/docs/README.txt +++ /dev/null @@ -1,461 +0,0 @@ -.. -*- rest -*- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - F2PY: Fortran to Python interface generator -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:Author: Pearu Peterson <pearu@cens.ioc.ee> -:License: NumPy License -:Web-site: http://cens.ioc.ee/projects/f2py2e/ -:Discussions to: `f2py-users mailing list`_ -:Documentation: `User's Guide`__, FAQ__ -:Platforms: All -:Date: $Date: 2005/01/30 18:54:53 $ - -.. _f2py-users mailing list: http://cens.ioc.ee/mailman/listinfo/f2py-users/ -__ usersguide/index.html -__ FAQ.html - -------------------------------- - -.. topic:: NEWS!!! - - January 5, 2006 - - WARNING -- these notes are out of date! The package structure for NumPy and - SciPy has changed considerably. Much of this information is now incorrect. - - January 30, 2005 - - Latest F2PY release (version 2.45.241_1926). - New features: wrapping unsigned integers, support for ``.pyf.src`` template files, - callback arguments can now be CObjects, fortran objects, built-in functions. - Introduced ``intent(aux)`` attribute. Wrapped objects have ``_cpointer`` - attribute holding C pointer to wrapped functions or variables. - Many bug fixes and improvements, updated documentation. - `Differences with the previous release (version 2.43.239_1831)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.163&r2=1.137&f=h - - October 4, 2004 - F2PY bug fix release (version 2.43.239_1831). - Better support for 64-bit platforms. - Introduced ``--help-link`` and ``--link-<resource>`` options. - Bug fixes. - `Differences with the previous release (version 2.43.239_1806)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.137&r2=1.131&f=h - - September 25, 2004 - Latest F2PY release (version 2.43.239_1806). - Support for ``ENTRY`` statement. New attributes: - ``intent(inplace)``, ``intent(callback)``. Supports Numarray 1.1. - Introduced ``-*- fix -*-`` header content. Improved ``PARAMETER`` support. - Documentation updates. `Differences with the previous release - (version 2.39.235-1693)`__. - - __ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt.diff?r1=1.131&r2=1.98&f=h - - `History of NEWS`__ - - __ OLDNEWS.html - -------------------------------- - -.. Contents:: - -============== - Introduction -============== - -The purpose of the F2PY --*Fortran to Python interface generator*-- -project is to provide connection between Python_ and Fortran -languages. F2PY is a Python extension tool for creating Python C/API -modules from (handwritten or F2PY generated) signature files (or -directly from Fortran sources). The generated extension modules -facilitate: - -* Calling Fortran 77/90/95, Fortran 90/95 module, and C functions from - Python. - -* Accessing Fortran 77 ``COMMON`` blocks and Fortran 90/95 module - data (including allocatable arrays) from Python. - -* Calling Python functions from Fortran or C (call-backs). - -* Automatically handling the difference in the data storage order of - multi-dimensional Fortran and Numerical Python (i.e. C) arrays. - -In addition, F2PY can build the generated extension modules to shared -libraries with one command. F2PY uses the ``numpy_distutils`` module -from SciPy_ that supports number of major Fortran compilers. - -.. - (see `COMPILERS.txt`_ for more information). - -F2PY generated extension modules depend on NumPy_ package that -provides fast multi-dimensional array language facility to Python. - - ---------------- - Main features ---------------- - -Here follows a more detailed list of F2PY features: - -* F2PY scans real Fortran codes to produce the so-called signature - files (.pyf files). The signature files contain all the information - (function names, arguments and their types, etc.) that is needed to - construct Python bindings to Fortran (or C) functions. - - The syntax of signature files is borrowed from the - Fortran 90/95 language specification and has some F2PY specific - extensions. The signature files can be modified to dictate how - Fortran (or C) programs are called from Python: - - + F2PY solves dependencies between arguments (this is relevant for - the order of initializing variables in extension modules). - - + Arguments can be specified to be optional or hidden that - simplifies calling Fortran programs from Python considerably. - - + In principle, one can design any Python signature for a given - Fortran function, e.g. change the order arguments, introduce - auxiliary arguments, hide the arguments, process the arguments - before passing to Fortran, return arguments as output of F2PY - generated functions, etc. - -* F2PY automatically generates __doc__ strings (and optionally LaTeX - documentation) for extension modules. - -* F2PY generated functions accept arbitrary (but sensible) Python - objects as arguments. The F2PY interface automatically takes care of - type-casting and handling of non-contiguous arrays. - -* The following Fortran constructs are recognized by F2PY: - - + All basic Fortran types:: - - integer[ | *1 | *2 | *4 | *8 ], logical[ | *1 | *2 | *4 | *8 ] - integer*([ -1 | -2 | -4 | -8 ]) - character[ | *(*) | *1 | *2 | *3 | ... ] - real[ | *4 | *8 | *16 ], double precision - complex[ | *8 | *16 | *32 ] - - Negative ``integer`` kinds are used to wrap unsigned integers. - - + Multi-dimensional arrays of all basic types with the following - dimension specifications:: - - <dim> | <start>:<end> | * | : - - + Attributes and statements:: - - intent([ in | inout | out | hide | in,out | inout,out | c | - copy | cache | callback | inplace | aux ]) - dimension(<dimspec>) - common, parameter - allocatable - optional, required, external - depend([<names>]) - check([<C-booleanexpr>]) - note(<LaTeX text>) - usercode, callstatement, callprotoargument, threadsafe, fortranname - pymethoddef - entry - -* Because there are only little (and easily handleable) differences - between calling C and Fortran functions from F2PY generated - extension modules, then F2PY is also well suited for wrapping C - libraries to Python. - -* Practice has shown that F2PY generated interfaces (to C or Fortran - functions) are less error prone and even more efficient than - handwritten extension modules. The F2PY generated interfaces are - easy to maintain and any future optimization of F2PY generated - interfaces transparently apply to extension modules by just - regenerating them with the latest version of F2PY. - -* `F2PY Users Guide and Reference Manual`_ - - -=============== - Prerequisites -=============== - -F2PY requires the following software installed: - -* Python_ (versions 1.5.2 or later; 2.1 and up are recommended). - You must have python-dev package installed. -* NumPy_ (versions 13 or later; 20.x, 21.x, 22.x, 23.x are recommended) -* Numarray_ (version 0.9 and up), optional, partial support. -* Scipy_distutils (version 0.2.2 and up are recommended) from SciPy_ - project. Get it from Scipy CVS or download it below. - -Python 1.x users also need distutils_. - -Of course, to build extension modules, you'll need also working C -and/or Fortran compilers installed. - -========== - Download -========== - -You can download the sources for the latest F2PY and numpy_distutils -releases as: - -* `2.x`__/`F2PY-2-latest.tar.gz`__ -* `2.x`__/`numpy_distutils-latest.tar.gz`__ - -Windows users might be interested in Win32 installer for F2PY and -Scipy_distutils (these installers are built using Python 2.3): - -* `2.x`__/`F2PY-2-latest.win32.exe`__ -* `2.x`__/`numpy_distutils-latest.win32.exe`__ - -Older releases are also available in the directories -`rel-0.x`__, `rel-1.x`__, `rel-2.x`__, `rel-3.x`__, `rel-4.x`__, `rel-5.x`__, -if you need them. - -.. __: 2.x/ -.. __: 2.x/F2PY-2-latest.tar.gz -.. __: 2.x/ -.. __: 2.x/numpy_distutils-latest.tar.gz -.. __: 2.x/ -.. __: 2.x/F2PY-2-latest.win32.exe -.. __: 2.x/ -.. __: 2.x/numpy_distutils-latest.win32.exe -.. __: rel-0.x -.. __: rel-1.x -.. __: rel-2.x -.. __: rel-3.x -.. __: rel-4.x -.. __: rel-5.x - -Development version of F2PY from CVS is available as `f2py2e.tar.gz`__. - -__ http://cens.ioc.ee/cgi-bin/viewcvs.cgi/python/f2py2e/f2py2e.tar.gz?tarball=1 - -Debian Sid users can simply install ``python-f2py`` package. - -============== - Installation -============== - -Unpack the source file, change to directrory ``F2PY-?-???/`` and run -(you may need to become a root):: - - python setup.py install - -The F2PY installation installs a Python package ``f2py2e`` to your -Python ``site-packages`` directory and a script ``f2py`` to your -Python executable path. - -See also Installation__ section in `F2PY FAQ`_. - -.. __: FAQ.html#installation - -Similarly, to install ``numpy_distutils``, unpack its tar-ball and run:: - - python setup.py install - -======= - Usage -======= - -To check if F2PY is installed correctly, run -:: - - f2py - -without any arguments. This should print out the usage information of -the ``f2py`` program. - -Next, try out the following three steps: - -1) Create a Fortran file `hello.f`__ that contains:: - - C File hello.f - subroutine foo (a) - integer a - print*, "Hello from Fortran!" - print*, "a=",a - end - -__ hello.f - -2) Run - - :: - - f2py -c -m hello hello.f - - This will build an extension module ``hello.so`` (or ``hello.sl``, - or ``hello.pyd``, etc. depending on your platform) into the current - directory. - -3) Now in Python try:: - - >>> import hello - >>> print hello.__doc__ - >>> print hello.foo.__doc__ - >>> hello.foo(4) - Hello from Fortran! - a= 4 - >>> - -If the above works, then you can try out more thorough -`F2PY unit tests`__ and read the `F2PY Users Guide and Reference Manual`_. - -__ FAQ.html#q-how-to-test-if-f2py-is-working-correctly - -=============== - Documentation -=============== - -The documentation of the F2PY project is collected in ``f2py2e/docs/`` -directory. It contains the following documents: - -`README.txt`_ (in CVS__) - The first thing to read about F2PY -- this document. - -__ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/README.txt?rev=HEAD&content-type=text/x-cvsweb-markup - -`usersguide/index.txt`_, `usersguide/f2py_usersguide.pdf`_ - F2PY Users Guide and Reference Manual. Contains lots of examples. - -`FAQ.txt`_ (in CVS__) - F2PY Frequently Asked Questions. - -__ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/FAQ.txt?rev=HEAD&content-type=text/x-cvsweb-markup - -`TESTING.txt`_ (in CVS__) - About F2PY testing site. What tests are available and how to run them. - -__ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/TESTING.txt?rev=HEAD&content-type=text/x-cvsweb-markup - -`HISTORY.txt`_ (in CVS__) - A list of latest changes in F2PY. This is the most up-to-date - document on F2PY. - -__ http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt?rev=HEAD&content-type=text/x-cvsweb-markup - -`THANKS.txt`_ - Acknowledgments. - -.. - `COMPILERS.txt`_ - Compiler and platform specific notes. - -=============== - Mailing list -=============== - -A mailing list f2py-users@cens.ioc.ee is open for F2PY releated -discussion/questions/etc. - -* `Subscribe..`__ -* `Archives..`__ - -__ http://cens.ioc.ee/mailman/listinfo/f2py-users -__ http://cens.ioc.ee/pipermail/f2py-users - - -===== - CVS -===== - -F2PY is being developed under CVS_. The CVS version of F2PY can be -obtained as follows: - -1) First you need to login (the password is ``guest``):: - - cvs -d :pserver:anonymous@cens.ioc.ee:/home/cvs login - -2) and then do the checkout:: - - cvs -z6 -d :pserver:anonymous@cens.ioc.ee:/home/cvs checkout f2py2e - -3) You can update your local F2PY tree ``f2py2e/`` by executing:: - - cvs -z6 update -P -d - -You can browse the `F2PY CVS`_ repository. - -=============== - Contributions -=============== - -* `A short introduction to F2PY`__ by Pierre Schnizer. - -* `F2PY notes`__ by Fernando Perez. - -* `Debian packages of F2PY`__ by José Fonseca. [OBSOLETE, Debian Sid - ships python-f2py package] - -__ http://fubphpc.tu-graz.ac.at/~pierre/f2py_tutorial.tar.gz -__ http://cens.ioc.ee/pipermail/f2py-users/2003-April/000472.html -__ http://jrfonseca.dyndns.org/debian/ - - -=============== - Related sites -=============== - -* `Numerical Python`_ -- adds a fast array facility to the Python language. -* Pyfort_ -- A Python-Fortran connection tool. -* SciPy_ -- An open source library of scientific tools for Python. -* `Scientific Python`_ -- A collection of Python modules that are - useful for scientific computing. -* `The Fortran Company`_ -- A place to find products, services, and general - information related to the Fortran programming language. -* `American National Standard Programming Language FORTRAN ANSI(R) X3.9-1978`__ -* `J3`_ -- The US Fortran standards committee. -* SWIG_ -- A software development tool that connects programs written - in C and C++ with a variety of high-level programming languages. -* `Mathtools.net`_ -- A technical computing portal for all scientific - and engineering needs. - -.. __: http://www.fortran.com/fortran/F77_std/rjcnf.html - -.. References - ========== - - -.. _F2PY Users Guide and Reference Manual: usersguide/index.html -.. _usersguide/index.txt: usersguide/index.html -.. _usersguide/f2py_usersguide.pdf: usersguide/f2py_usersguide.pdf -.. _README.txt: README.html -.. _COMPILERS.txt: COMPILERS.html -.. _F2PY FAQ: -.. _FAQ.txt: FAQ.html -.. _HISTORY.txt: HISTORY.html -.. _HISTORY.txt from CVS: http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/docs/HISTORY.txt?rev=HEAD&content-type=text/x-cvsweb-markup -.. _THANKS.txt: THANKS.html -.. _TESTING.txt: TESTING.html -.. _F2PY CVS2: http://cens.ioc.ee/cgi-bin/cvsweb/python/f2py2e/ -.. _F2PY CVS: http://cens.ioc.ee/cgi-bin/viewcvs.cgi/python/f2py2e/ - -.. _CVS: http://www.cvshome.org/ -.. _Python: http://www.python.org/ -.. _SciPy: http://www.numpy.org/ -.. _NumPy: http://www.numpy.org/ -.. _Numarray: http://www.stsci.edu/resources/software_hardware/numarray -.. _docutils: http://docutils.sourceforge.net/ -.. _distutils: http://www.python.org/sigs/distutils-sig/ -.. _Numerical Python: http://www.numpy.org/ -.. _Pyfort: http://pyfortran.sourceforge.net/ -.. _Scientific Python: - http://starship.python.net/crew/hinsen/scientific.html -.. _The Fortran Company: http://www.fortran.com/fortran/ -.. _J3: http://www.j3-fortran.org/ -.. _Mathtools.net: http://www.mathtools.net/ -.. _SWIG: http://www.swig.org/ - -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - End: diff --git a/numpy/f2py/docs/TESTING.txt b/numpy/f2py/docs/TESTING.txt deleted file mode 100644 index d90521175..000000000 --- a/numpy/f2py/docs/TESTING.txt +++ /dev/null @@ -1,108 +0,0 @@ - -======================================================= - F2PY unit testing site -======================================================= - -.. Contents:: - -Tests ------ - -* To run all F2PY unit tests in one command:: - - cd tests - python run_all.py [<options>] - - For example:: - - localhost:~/src_cvs/f2py2e/tests$ python2.2 run_all.py 100 --quiet - ********************************************** - Running '/usr/bin/python2.2 f77/return_integer.py 100 --quiet' - run 1000 tests in 1.87 seconds - initial virtual memory size: 3952640 bytes - current virtual memory size: 3952640 bytes - ok - ********************************************** - Running '/usr/bin/python2.2 f77/return_logical.py 100 --quiet' - run 1000 tests in 1.47 seconds - initial virtual memory size: 3952640 bytes - current virtual memory size: 3952640 bytes - ok - ... - - If some tests fail, try to run the failing tests separately (without - the ``--quiet`` option) as described below to get more information - about the failure. - -* Test intent(in), intent(out) scalar arguments, - scalars returned by F77 functions - and F90 module functions:: - - tests/f77/return_integer.py - tests/f77/return_real.py - tests/f77/return_logical.py - tests/f77/return_complex.py - tests/f77/return_character.py - tests/f90/return_integer.py - tests/f90/return_real.py - tests/f90/return_logical.py - tests/f90/return_complex.py - tests/f90/return_character.py - - Change to tests/ directory and run:: - - python f77/return_<type>.py [<options>] - python f90/return_<type>.py [<options>] - - where ``<type>`` is integer, real, logical, complex, or character. - Test scripts options are described below. - - A test is considered succesful if the last printed line is "ok". - - If you get import errors like:: - - ImportError: No module named f77_ext_return_integer - - but ``f77_ext_return_integer.so`` exists in the current directory then - it means that the current directory is not included in to `sys.path` - in your Python installation. As a fix, prepend ``.`` to ``PYTHONPATH`` - environment variable and rerun the tests. For example:: - - PYTHONPATH=. python f77/return_integer.py - -* Test mixing Fortran 77, Fortran 90 fixed and free format codes:: - - tests/mixed/run.py - -* Test basic callback hooks:: - - tests/f77/callback.py - -Options -------- - -You may want to use the following options when running the test -scripts: - -``<integer>`` - Run tests ``<integer>`` times. Useful for detecting memory leaks. Under - Linux tests scripts output virtual memory size state of the process - before and after calling the wrapped functions. - -``--quiet`` - Suppress all messages. On success only "ok" should be displayed. - -``--fcompiler=<Gnu|Intel|...>`` - Use:: - - f2py -c --help-fcompiler - - to find out what compilers are available (or more precisely, which - ones are recognized by ``numpy_distutils``). - -Reporting failures ------------------- - -XXX: (1) make sure that failures are due to f2py and (2) send full -stdout/stderr messages to me. Also add compiler,python,platform -information. diff --git a/numpy/f2py/docs/THANKS.txt b/numpy/f2py/docs/THANKS.txt deleted file mode 100644 index 0a3f0b9d6..000000000 --- a/numpy/f2py/docs/THANKS.txt +++ /dev/null @@ -1,63 +0,0 @@ - -================= - Acknowledgments -================= - -F2PY__ is an open source Python package and command line tool developed and -maintained by Pearu Peterson (me__). - -.. __: http://cens.ioc.ee/projects/f2py2e/ -.. __: http://cens.ioc.ee/~pearu/ - -Many people have contributed to the F2PY project in terms of interest, -encouragement, suggestions, criticism, bug reports, code -contributions, and keeping me busy with developing F2PY. For all that -I thank - - James Amundson, John Barnard, David Beazley, Frank Bertoldi, Roman - Bertle, James Boyle, Moritz Braun, Rolv Erlend Bredesen, John - Chaffer, Fred Clare, Adam Collard, Ben Cornett, Jose L Gomez Dans, - Jaime D. Perea Duarte, Paul F Dubois, Thilo Ernst, Bonilla Fabian, - Martin Gelfand, Eduardo A. Gonzalez, Siegfried Gonzi, Bernhard - Gschaider, Charles Doutriaux, Jeff Hagelberg, Janko Hauser, Thomas - Hauser, Heiko Henkelmann, William Henney, Yueqiang Huang, Asim - Hussain, Berthold Höllmann, Vladimir Janku, Henk Jansen, Curtis - Jensen, Eric Jones, Tiffany Kamm, Andrey Khavryuchenko, Greg - Kochanski, Jochen Küpper, Simon Lacoste-Julien, Tim Lahey, Hans - Petter Langtangen, Jeff Layton, Matthew Lewis, Patrick LeGresley, - Joaquim R R A Martins, Paul Magwene Lionel Maziere, Craig McNeile, - Todd Miller, David C. Morrill, Dirk Muders, Kevin Mueller, Andrew - Mullhaupt, Vijayendra Munikoti, Travis Oliphant, Kevin O'Mara, Arno - Paehler, Fernando Perez, Didrik Pinte, Todd Alan Pitts, Prabhu - Ramachandran, Brad Reisfeld, Steve M. Robbins, Theresa Robinson, - Pedro Rodrigues, Les Schaffer, Christoph Scheurer, Herb Schilling, - Pierre Schnizer, Kevin Smith, Paulo Teotonio Sobrinho, José Rui - Faustino de Sousa, Andrew Swan, Dustin Tang, Charlie Taylor, Paul le - Texier, Michael Tiller, Semen Trygubenko, Ravi C Venkatesan, Peter - Verveer, Nils Wagner, R. Clint Whaley, Erik Wilsher, Martin - Wiechert, Gilles Zerah, SungPil Yoon. - -(This list may not be complete. Please forgive me if I have left you -out and let me know, I'll add your name.) - -Special thanks are due to ... - -Eric Jones - he and Travis O. are responsible for starting the -numpy_distutils project that allowed to move most of the platform and -compiler specific codes out from F2PY. This simplified maintaining the -F2PY project considerably. - -Joaquim R R A Martins - he made possible for me to test F2PY on IRIX64 -platform. He also presented our paper about F2PY in the 9th Python -Conference that I planned to attend but had to cancel in very last -minutes. - -Travis Oliphant - his knowledge and experience on Numerical Python -C/API has been invaluable in early development of the F2PY program. -His major contributions are call-back mechanism and copying N-D arrays -of arbitrary types. - -Todd Miller - he is responsible for Numarray support in F2PY. - -Thanks! - Pearu diff --git a/numpy/f2py/docs/default.css b/numpy/f2py/docs/default.css deleted file mode 100644 index 9289e2826..000000000 --- a/numpy/f2py/docs/default.css +++ /dev/null @@ -1,180 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date: 2002/08/01 20:52:44 $ -:version: $Revision: 1.1 $ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. -*/ - -body { - background: #FFFFFF ; - color: #000000 -} - -a.footnote-reference { - font-size: smaller ; - vertical-align: super } - -a.target { - color: blue } - -a.toc-backref { - text-decoration: none ; - color: black } - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.first { - margin-top: 0 } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.field-argument { - font-style: italic } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: baseline } - -td.docinfo-name { - font-weight: bold ; - text-align: right } - -td.field-name { - font-weight: bold } diff --git a/numpy/f2py/docs/docutils.conf b/numpy/f2py/docs/docutils.conf deleted file mode 100644 index 4e5a8425b..000000000 --- a/numpy/f2py/docs/docutils.conf +++ /dev/null @@ -1,16 +0,0 @@ -[general] - -# These entries affect all processing: -#source-link: 1 -datestamp: %Y-%m-%d %H:%M UTC -generator: 1 - -# These entries affect HTML output: -#stylesheet-path: pearu_style.css -output-encoding: latin-1 - -# These entries affect reStructuredText-style PEPs: -#pep-template: pep-html-template -#pep-stylesheet-path: stylesheets/pep.css -#python-home: http://www.python.org -#no-random: 1 diff --git a/numpy/f2py/docs/hello.f b/numpy/f2py/docs/hello.f deleted file mode 100644 index 3e0dc6d21..000000000 --- a/numpy/f2py/docs/hello.f +++ /dev/null @@ -1,7 +0,0 @@ -C File hello.f - subroutine foo (a) - integer a - print*, "Hello from Fortran!" - print*, "a=",a - end - diff --git a/numpy/f2py/docs/pyforttest.pyf b/numpy/f2py/docs/pyforttest.pyf deleted file mode 100644 index 79a9ae205..000000000 --- a/numpy/f2py/docs/pyforttest.pyf +++ /dev/null @@ -1,5 +0,0 @@ -subroutine foo(a,m,n) -integer m = size(a,1) -integer n = size(a,2) -real, intent(inout) :: a(m,n) -end subroutine foo diff --git a/numpy/f2py/docs/pytest.py b/numpy/f2py/docs/pytest.py deleted file mode 100644 index abd3487df..000000000 --- a/numpy/f2py/docs/pytest.py +++ /dev/null @@ -1,10 +0,0 @@ -#File: pytest.py -import Numeric -def foo(a): - a = Numeric.array(a) - m,n = a.shape - for i in range(m): - for j in range(n): - a[i,j] = a[i,j] + 10*(i+1) + (j+1) - return a -#eof diff --git a/numpy/f2py/docs/simple.f b/numpy/f2py/docs/simple.f deleted file mode 100644 index ba468a509..000000000 --- a/numpy/f2py/docs/simple.f +++ /dev/null @@ -1,13 +0,0 @@ -cFile: simple.f - subroutine foo(a,m,n) - integer m,n,i,j - real a(m,n) -cf2py intent(in,out) a -cf2py intent(hide) m,n - do i=1,m - do j=1,n - a(i,j) = a(i,j) + 10*i+j - enddo - enddo - end -cEOF diff --git a/numpy/f2py/docs/simple_session.dat b/numpy/f2py/docs/simple_session.dat deleted file mode 100644 index 10d9dc962..000000000 --- a/numpy/f2py/docs/simple_session.dat +++ /dev/null @@ -1,51 +0,0 @@ ->>> import pytest ->>> import f2pytest ->>> import pyforttest ->>> print f2pytest.foo.__doc__ -foo - Function signature: - a = foo(a) -Required arguments: - a : input rank-2 array('f') with bounds (m,n) -Return objects: - a : rank-2 array('f') with bounds (m,n) - ->>> print pyforttest.foo.__doc__ -foo(a) - ->>> pytest.foo([[1,2],[3,4]]) -array([[12, 14], - [24, 26]]) ->>> f2pytest.foo([[1,2],[3,4]]) # F2PY can handle arbitrary input sequences -array([[ 12., 14.], - [ 24., 26.]],'f') ->>> pyforttest.foo([[1,2],[3,4]]) -Traceback (most recent call last): - File "<stdin>", line 1, in ? -pyforttest.error: foo, argument A: Argument intent(inout) must be an array. - ->>> import Numeric ->>> a=Numeric.array([[1,2],[3,4]],'f') ->>> f2pytest.foo(a) -array([[ 12., 14.], - [ 24., 26.]],'f') ->>> a # F2PY makes a copy when input array is not Fortran contiguous -array([[ 1., 2.], - [ 3., 4.]],'f') ->>> a=Numeric.transpose(Numeric.array([[1,3],[2,4]],'f')) ->>> a -array([[ 1., 2.], - [ 3., 4.]],'f') ->>> f2pytest.foo(a) -array([[ 12., 14.], - [ 24., 26.]],'f') ->>> a # F2PY passes Fortran contiguous input array directly to Fortran -array([[ 12., 14.], - [ 24., 26.]],'f') -# See intent(copy), intent(overwrite), intent(inplace), intent(inout) -# attributes documentation to enhance the above behavior. - ->>> a=Numeric.array([[1,2],[3,4]],'f') ->>> pyforttest.foo(a) ->>> a # Huh? Pyfort 8.5 gives wrong results.. -array([[ 12., 23.], - [ 15., 26.]],'f') diff --git a/numpy/f2py/docs/usersguide/allocarr.f90 b/numpy/f2py/docs/usersguide/allocarr.f90 deleted file mode 100644 index e0d6c2ec8..000000000 --- a/numpy/f2py/docs/usersguide/allocarr.f90 +++ /dev/null @@ -1,16 +0,0 @@ -module mod - real, allocatable, dimension(:,:) :: b -contains - subroutine foo - integer k - if (allocated(b)) then - print*, "b=[" - do k = 1,size(b,1) - print*, b(k,1:size(b,2)) - enddo - print*, "]" - else - print*, "b is not allocated" - endif - end subroutine foo -end module mod diff --git a/numpy/f2py/docs/usersguide/allocarr_session.dat b/numpy/f2py/docs/usersguide/allocarr_session.dat deleted file mode 100644 index fc91959b7..000000000 --- a/numpy/f2py/docs/usersguide/allocarr_session.dat +++ /dev/null @@ -1,27 +0,0 @@ ->>> import allocarr ->>> print allocarr.mod.__doc__ -b - 'f'-array(-1,-1), not allocated -foo - Function signature: - foo() - ->>> allocarr.mod.foo() - b is not allocated ->>> allocarr.mod.b = [[1,2,3],[4,5,6]] # allocate/initialize b ->>> allocarr.mod.foo() - b=[ - 1.000000 2.000000 3.000000 - 4.000000 5.000000 6.000000 - ] ->>> allocarr.mod.b # b is Fortran-contiguous -array([[ 1., 2., 3.], - [ 4., 5., 6.]],'f') ->>> allocarr.mod.b = [[1,2,3],[4,5,6],[7,8,9]] # reallocate/initialize b ->>> allocarr.mod.foo() - b=[ - 1.000000 2.000000 3.000000 - 4.000000 5.000000 6.000000 - 7.000000 8.000000 9.000000 - ] ->>> allocarr.mod.b = None # deallocate array ->>> allocarr.mod.foo() - b is not allocated diff --git a/numpy/f2py/docs/usersguide/array.f b/numpy/f2py/docs/usersguide/array.f deleted file mode 100644 index ef20c9c20..000000000 --- a/numpy/f2py/docs/usersguide/array.f +++ /dev/null @@ -1,17 +0,0 @@ -C FILE: ARRAY.F - SUBROUTINE FOO(A,N,M) -C -C INCREMENT THE FIRST ROW AND DECREMENT THE FIRST COLUMN OF A -C - INTEGER N,M,I,J - REAL*8 A(N,M) -Cf2py intent(in,out,copy) a -Cf2py integer intent(hide),depend(a) :: n=shape(a,0), m=shape(a,1) - DO J=1,M - A(1,J) = A(1,J) + 1D0 - ENDDO - DO I=1,N - A(I,1) = A(I,1) - 1D0 - ENDDO - END -C END OF FILE ARRAY.F diff --git a/numpy/f2py/docs/usersguide/array_session.dat b/numpy/f2py/docs/usersguide/array_session.dat deleted file mode 100644 index f64933482..000000000 --- a/numpy/f2py/docs/usersguide/array_session.dat +++ /dev/null @@ -1,65 +0,0 @@ ->>> import arr ->>> from Numeric import array ->>> print arr.foo.__doc__ -foo - Function signature: - a = foo(a,[overwrite_a]) -Required arguments: - a : input rank-2 array('d') with bounds (n,m) -Optional arguments: - overwrite_a := 0 input int -Return objects: - a : rank-2 array('d') with bounds (n,m) - ->>> a=arr.foo([[1,2,3], -... [4,5,6]]) -copied an array using PyArray_CopyFromObject: size=6, elsize=8 ->>> print a -[[ 1. 3. 4.] - [ 3. 5. 6.]] ->>> a.iscontiguous(), arr.has_column_major_storage(a) -(0, 1) ->>> b=arr.foo(a) # even if a is proper-contiguous -... # and has proper type, a copy is made -... # forced by intent(copy) attribute -... # to preserve its original contents -... -copied an array using copy_ND_array: size=6, elsize=8 ->>> print a -[[ 1. 3. 4.] - [ 3. 5. 6.]] ->>> print b -[[ 1. 4. 5.] - [ 2. 5. 6.]] ->>> b=arr.foo(a,overwrite_a=1) # a is passed directly to Fortran -... # routine and its contents is discarded -... ->>> print a -[[ 1. 4. 5.] - [ 2. 5. 6.]] ->>> print b -[[ 1. 4. 5.] - [ 2. 5. 6.]] ->>> a is b # a and b are acctually the same objects -1 ->>> print arr.foo([1,2,3]) # different rank arrays are allowed -copied an array using PyArray_CopyFromObject: size=3, elsize=8 -[ 1. 1. 2.] ->>> print arr.foo([[[1],[2],[3]]]) -copied an array using PyArray_CopyFromObject: size=3, elsize=8 -[ [[ 1.] - [ 3.] - [ 4.]]] ->>> ->>> # Creating arrays with column major data storage order: -... ->>> s = arr.as_column_major_storage(array([[1,2,3],[4,5,6]])) -copied an array using copy_ND_array: size=6, elsize=4 ->>> arr.has_column_major_storage(s) -1 ->>> print s -[[1 2 3] - [4 5 6]] ->>> s2 = arr.as_column_major_storage(s) ->>> s2 is s # an array with column major storage order - # is returned immediately -1
\ No newline at end of file diff --git a/numpy/f2py/docs/usersguide/calculate.f b/numpy/f2py/docs/usersguide/calculate.f deleted file mode 100644 index 1cda1c8dd..000000000 --- a/numpy/f2py/docs/usersguide/calculate.f +++ /dev/null @@ -1,14 +0,0 @@ - subroutine calculate(x,n) -cf2py intent(callback) func - external func -c The following lines define the signature of func for F2PY: -cf2py real*8 y -cf2py y = func(y) -c -cf2py intent(in,out,copy) x - integer n,i - real*8 x(n) - do i=1,n - x(i) = func(x(i)) - end do - end diff --git a/numpy/f2py/docs/usersguide/calculate_session.dat b/numpy/f2py/docs/usersguide/calculate_session.dat deleted file mode 100644 index 2fe64f522..000000000 --- a/numpy/f2py/docs/usersguide/calculate_session.dat +++ /dev/null @@ -1,6 +0,0 @@ ->>> import foo ->>> foo.calculate(range(5), lambda x: x*x) -array([ 0., 1., 4., 9., 16.]) ->>> import math ->>> foo.calculate(range(5), math.exp) -array([ 1. , 2.71828175, 7.38905621, 20.08553696, 54.59814835]) diff --git a/numpy/f2py/docs/usersguide/callback.f b/numpy/f2py/docs/usersguide/callback.f deleted file mode 100644 index 6e9bfb920..000000000 --- a/numpy/f2py/docs/usersguide/callback.f +++ /dev/null @@ -1,12 +0,0 @@ -C FILE: CALLBACK.F - SUBROUTINE FOO(FUN,R) - EXTERNAL FUN - INTEGER I - REAL*8 R -Cf2py intent(out) r - R = 0D0 - DO I=-5,5 - R = R + FUN(I) - ENDDO - END -C END OF FILE CALLBACK.F diff --git a/numpy/f2py/docs/usersguide/callback2.pyf b/numpy/f2py/docs/usersguide/callback2.pyf deleted file mode 100644 index 3d77eed24..000000000 --- a/numpy/f2py/docs/usersguide/callback2.pyf +++ /dev/null @@ -1,19 +0,0 @@ -! -*- f90 -*- -python module __user__routines - interface - function fun(i) result (r) - integer :: i - real*8 :: r - end function fun - end interface -end python module __user__routines - -python module callback2 - interface - subroutine foo(f,r) - use __user__routines, f=>fun - external f - real*8 intent(out) :: r - end subroutine foo - end interface -end python module callback2 diff --git a/numpy/f2py/docs/usersguide/callback_session.dat b/numpy/f2py/docs/usersguide/callback_session.dat deleted file mode 100644 index cd2f26084..000000000 --- a/numpy/f2py/docs/usersguide/callback_session.dat +++ /dev/null @@ -1,23 +0,0 @@ ->>> import callback ->>> print callback.foo.__doc__ -foo - Function signature: - r = foo(fun,[fun_extra_args]) -Required arguments: - fun : call-back function -Optional arguments: - fun_extra_args := () input tuple -Return objects: - r : float -Call-back functions: - def fun(i): return r - Required arguments: - i : input int - Return objects: - r : float - ->>> def f(i): return i*i -... ->>> print callback.foo(f) -110.0 ->>> print callback.foo(lambda i:1) -11.0 diff --git a/numpy/f2py/docs/usersguide/common.f b/numpy/f2py/docs/usersguide/common.f deleted file mode 100644 index b098ab20c..000000000 --- a/numpy/f2py/docs/usersguide/common.f +++ /dev/null @@ -1,13 +0,0 @@ -C FILE: COMMON.F - SUBROUTINE FOO - INTEGER I,X - REAL A - COMMON /DATA/ I,X(4),A(2,3) - PRINT*, "I=",I - PRINT*, "X=[",X,"]" - PRINT*, "A=[" - PRINT*, "[",A(1,1),",",A(1,2),",",A(1,3),"]" - PRINT*, "[",A(2,1),",",A(2,2),",",A(2,3),"]" - PRINT*, "]" - END -C END OF COMMON.F diff --git a/numpy/f2py/docs/usersguide/common_session.dat b/numpy/f2py/docs/usersguide/common_session.dat deleted file mode 100644 index 846fdaa07..000000000 --- a/numpy/f2py/docs/usersguide/common_session.dat +++ /dev/null @@ -1,27 +0,0 @@ ->>> import common ->>> print common.data.__doc__ -i - 'i'-scalar -x - 'i'-array(4) -a - 'f'-array(2,3) - ->>> common.data.i = 5 ->>> common.data.x[1] = 2 ->>> common.data.a = [[1,2,3],[4,5,6]] ->>> common.foo() - I= 5 - X=[ 0 2 0 0] - A=[ - [ 1., 2., 3.] - [ 4., 5., 6.] - ] ->>> common.data.a[1] = 45 ->>> common.foo() - I= 5 - X=[ 0 2 0 0] - A=[ - [ 1., 2., 3.] - [ 45., 45., 45.] - ] ->>> common.data.a # a is Fortran-contiguous -array([[ 1., 2., 3.], - [ 45., 45., 45.]],'f') diff --git a/numpy/f2py/docs/usersguide/compile_session.dat b/numpy/f2py/docs/usersguide/compile_session.dat deleted file mode 100644 index 0d8408198..000000000 --- a/numpy/f2py/docs/usersguide/compile_session.dat +++ /dev/null @@ -1,11 +0,0 @@ ->>> import f2py2e ->>> fsource = ''' -... subroutine foo -... print*, "Hello world!" -... end -... ''' ->>> f2py2e.compile(fsource,modulename='hello',verbose=0) -0 ->>> import hello ->>> hello.foo() - Hello world! diff --git a/numpy/f2py/docs/usersguide/default.css b/numpy/f2py/docs/usersguide/default.css deleted file mode 100644 index bb7226161..000000000 --- a/numpy/f2py/docs/usersguide/default.css +++ /dev/null @@ -1,180 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date: 2002/12/07 23:59:33 $ -:version: $Revision: 1.2 $ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. -*/ - -body { - background: #FFFFFF ; - color: #000000 -} - -a.footnote-reference { - font-size: smaller ; - vertical-align: super } - -a.target { - color: blue } - -a.toc-backref { - text-decoration: none ; - color: black } - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.first { - margin-top: 0 } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #ee9e9e } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.field-argument { - font-style: italic } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: baseline } - -td.docinfo-name { - font-weight: bold ; - text-align: right } - -td.field-name { - font-weight: bold } diff --git a/numpy/f2py/docs/usersguide/docutils.conf b/numpy/f2py/docs/usersguide/docutils.conf deleted file mode 100644 index b772fd137..000000000 --- a/numpy/f2py/docs/usersguide/docutils.conf +++ /dev/null @@ -1,16 +0,0 @@ -[general] - -# These entries affect all processing: -#source-link: 1 -datestamp: %Y-%m-%d %H:%M UTC -generator: 1 - -# These entries affect HTML output: -#stylesheet-path: f2py_style.css -output-encoding: latin-1 - -# These entries affect reStructuredText-style PEPs: -#pep-template: pep-html-template -#pep-stylesheet-path: stylesheets/pep.css -#python-home: http://www.python.org -#no-random: 1 diff --git a/numpy/f2py/docs/usersguide/extcallback.f b/numpy/f2py/docs/usersguide/extcallback.f deleted file mode 100644 index 9a800628e..000000000 --- a/numpy/f2py/docs/usersguide/extcallback.f +++ /dev/null @@ -1,14 +0,0 @@ - subroutine f1() - print *, "in f1, calling f2 twice.." - call f2() - call f2() - return - end - - subroutine f2() -cf2py intent(callback, hide) fpy - external fpy - print *, "in f2, calling f2py.." - call fpy() - return - end diff --git a/numpy/f2py/docs/usersguide/extcallback_session.dat b/numpy/f2py/docs/usersguide/extcallback_session.dat deleted file mode 100644 index c22935ea0..000000000 --- a/numpy/f2py/docs/usersguide/extcallback_session.dat +++ /dev/null @@ -1,19 +0,0 @@ ->>> import pfromf ->>> pfromf.f2() -Traceback (most recent call last): - File "<stdin>", line 1, in ? -pfromf.error: Callback fpy not defined (as an argument or module pfromf attribute). - ->>> def f(): print "python f" -... ->>> pfromf.fpy = f ->>> pfromf.f2() - in f2, calling f2py.. -python f ->>> pfromf.f1() - in f1, calling f2 twice.. - in f2, calling f2py.. -python f - in f2, calling f2py.. -python f ->>>
\ No newline at end of file diff --git a/numpy/f2py/docs/usersguide/fib1.f b/numpy/f2py/docs/usersguide/fib1.f deleted file mode 100644 index cfbb1eea0..000000000 --- a/numpy/f2py/docs/usersguide/fib1.f +++ /dev/null @@ -1,18 +0,0 @@ -C FILE: FIB1.F - SUBROUTINE FIB(A,N) -C -C CALCULATE FIRST N FIBONACCI NUMBERS -C - INTEGER N - REAL*8 A(N) - DO I=1,N - IF (I.EQ.1) THEN - A(I) = 0.0D0 - ELSEIF (I.EQ.2) THEN - A(I) = 1.0D0 - ELSE - A(I) = A(I-1) + A(I-2) - ENDIF - ENDDO - END -C END FILE FIB1.F diff --git a/numpy/f2py/docs/usersguide/fib1.pyf b/numpy/f2py/docs/usersguide/fib1.pyf deleted file mode 100644 index 3d6cc0a54..000000000 --- a/numpy/f2py/docs/usersguide/fib1.pyf +++ /dev/null @@ -1,12 +0,0 @@ -! -*- f90 -*- -python module fib2 ! in - interface ! in :fib2 - subroutine fib(a,n) ! in :fib2:fib1.f - real*8 dimension(n) :: a - integer optional,check(len(a)>=n),depend(a) :: n=len(a) - end subroutine fib - end interface -end python module fib2 - -! This file was auto-generated with f2py (version:2.28.198-1366). -! See http://cens.ioc.ee/projects/f2py2e/ diff --git a/numpy/f2py/docs/usersguide/fib2.pyf b/numpy/f2py/docs/usersguide/fib2.pyf deleted file mode 100644 index 4a5ae29f1..000000000 --- a/numpy/f2py/docs/usersguide/fib2.pyf +++ /dev/null @@ -1,9 +0,0 @@ -! -*- f90 -*- -python module fib2 - interface - subroutine fib(a,n) - real*8 dimension(n),intent(out),depend(n) :: a - integer intent(in) :: n - end subroutine fib - end interface -end python module fib2 diff --git a/numpy/f2py/docs/usersguide/fib3.f b/numpy/f2py/docs/usersguide/fib3.f deleted file mode 100644 index 08b050cd2..000000000 --- a/numpy/f2py/docs/usersguide/fib3.f +++ /dev/null @@ -1,21 +0,0 @@ -C FILE: FIB3.F - SUBROUTINE FIB(A,N) -C -C CALCULATE FIRST N FIBONACCI NUMBERS -C - INTEGER N - REAL*8 A(N) -Cf2py intent(in) n -Cf2py intent(out) a -Cf2py depend(n) a - DO I=1,N - IF (I.EQ.1) THEN - A(I) = 0.0D0 - ELSEIF (I.EQ.2) THEN - A(I) = 1.0D0 - ELSE - A(I) = A(I-1) + A(I-2) - ENDIF - ENDDO - END -C END FILE FIB3.F diff --git a/numpy/f2py/docs/usersguide/ftype.f b/numpy/f2py/docs/usersguide/ftype.f deleted file mode 100644 index cabbb9e2d..000000000 --- a/numpy/f2py/docs/usersguide/ftype.f +++ /dev/null @@ -1,9 +0,0 @@ -C FILE: FTYPE.F - SUBROUTINE FOO(N) - INTEGER N -Cf2py integer optional,intent(in) :: n = 13 - REAL A,X - COMMON /DATA/ A,X(3) - PRINT*, "IN FOO: N=",N," A=",A," X=[",X(1),X(2),X(3),"]" - END -C END OF FTYPE.F diff --git a/numpy/f2py/docs/usersguide/ftype_session.dat b/numpy/f2py/docs/usersguide/ftype_session.dat deleted file mode 100644 index 01f9febaf..000000000 --- a/numpy/f2py/docs/usersguide/ftype_session.dat +++ /dev/null @@ -1,21 +0,0 @@ ->>> import ftype ->>> print ftype.__doc__ -This module 'ftype' is auto-generated with f2py (version:2.28.198-1366). -Functions: - foo(n=13) -COMMON blocks: - /data/ a,x(3) -. ->>> type(ftype.foo),type(ftype.data) -(<type 'fortran'>, <type 'fortran'>) ->>> ftype.foo() - IN FOO: N= 13 A= 0. X=[ 0. 0. 0.] ->>> ftype.data.a = 3 ->>> ftype.data.x = [1,2,3] ->>> ftype.foo() - IN FOO: N= 13 A= 3. X=[ 1. 2. 3.] ->>> ftype.data.x[1] = 45 ->>> ftype.foo(24) - IN FOO: N= 24 A= 3. X=[ 1. 45. 3.] ->>> ftype.data.x -array([ 1., 45., 3.],'f') diff --git a/numpy/f2py/docs/usersguide/index.txt b/numpy/f2py/docs/usersguide/index.txt deleted file mode 100644 index 5a8d12c68..000000000 --- a/numpy/f2py/docs/usersguide/index.txt +++ /dev/null @@ -1,1772 +0,0 @@ -.. -*- rest -*- - -////////////////////////////////////////////////////////////////////// - F2PY Users Guide and Reference Manual -////////////////////////////////////////////////////////////////////// - -:Author: Pearu Peterson -:Contact: pearu@cens.ioc.ee -:Web site: http://cens.ioc.ee/projects/f2py2e/ -:Date: $Date: 2005/04/02 10:03:26 $ -:Revision: $Revision: 1.27 $ - - -.. section-numbering:: - -.. Contents:: - - -================ - Introduction -================ - -The purpose of the F2PY_ --*Fortran to Python interface generator*-- -project is to provide a connection between Python and Fortran -languages. F2PY is a Python_ package (with a command line tool -``f2py`` and a module ``f2py2e``) that facilitates creating/building -Python C/API extension modules that make it possible - -* to call Fortran 77/90/95 external subroutines and Fortran 90/95 - module subroutines as well as C functions; -* to access Fortran 77 ``COMMON`` blocks and Fortran 90/95 module data, - including allocatable arrays - -from Python. See F2PY_ web site for more information and installation -instructions. - -====================================== - Three ways to wrap - getting started -====================================== - -Wrapping Fortran or C functions to Python using F2PY consists of the -following steps: - -* Creating the so-called signature file that contains descriptions of - wrappers to Fortran or C functions, also called as signatures of the - functions. In the case of Fortran routines, F2PY can create initial - signature file by scanning Fortran source codes and - catching all relevant information needed to create wrapper - functions. - -* Optionally, F2PY created signature files can be edited to optimize - wrappers functions, make them "smarter" and more "Pythonic". - -* F2PY reads a signature file and writes a Python C/API module containing - Fortran/C/Python bindings. - -* F2PY compiles all sources and builds an extension module containing - the wrappers. In building extension modules, F2PY uses - ``numpy_distutils`` that supports a number of Fortran 77/90/95 - compilers, including Gnu, Intel, - Sun Fortre, SGI MIPSpro, Absoft, NAG, Compaq etc. compilers. - -Depending on a particular situation, these steps can be carried out -either by just in one command or step-by-step, some steps can be -ommited or combined with others. - -Below I'll describe three typical approaches of using F2PY. -The following `example Fortran 77 code`__ will be used for -illustration: - -.. include:: fib1.f - :literal: - -__ fib1.f - -The quick way -============== - -The quickest way to wrap the Fortran subroutine ``FIB`` to Python is -to run - -:: - - f2py -c fib1.f -m fib1 - -This command builds (see ``-c`` flag, execute ``f2py`` without -arguments to see the explanation of command line options) an extension -module ``fib1.so`` (see ``-m`` flag) to the current directory. Now, in -Python the Fortran subroutine ``FIB`` is accessible via ``fib1.fib``:: - - >>> import Numeric - >>> import fib1 - >>> print fib1.fib.__doc__ - fib - Function signature: - fib(a,[n]) - Required arguments: - a : input rank-1 array('d') with bounds (n) - Optional arguments: - n := len(a) input int - - >>> a=Numeric.zeros(8,'d') - >>> fib1.fib(a) - >>> print a - [ 0. 1. 1. 2. 3. 5. 8. 13.] - -.. topic:: Comments - - * Note that F2PY found that the second argument ``n`` is the - dimension of the first array argument ``a``. Since by default all - arguments are input-only arguments, F2PY concludes that ``n`` can - be optional with the default value ``len(a)``. - - * One can use different values for optional ``n``:: - - >>> a1=Numeric.zeros(8,'d') - >>> fib1.fib(a1,6) - >>> print a1 - [ 0. 1. 1. 2. 3. 5. 0. 0.] - - but an exception is raised when it is incompatible with the input - array ``a``:: - - >>> fib1.fib(a,10) - fib:n=10 - Traceback (most recent call last): - File "<stdin>", line 1, in ? - fib.error: (len(a)>=n) failed for 1st keyword n - >>> - - This demonstrates one of the useful features in F2PY, that it, - F2PY implements basic compatibility checks between related - arguments in order to avoid any unexpected crashes. - - * When a Numeric array, that is Fortran contiguous and has a typecode - corresponding to presumed Fortran type, is used as an input array - argument, then its C pointer is directly passed to Fortran. - - Otherwise F2PY makes a contiguous copy (with a proper typecode) of - the input array and passes C pointer of the copy to Fortran - subroutine. As a result, any possible changes to the (copy of) - input array have no effect to the original argument, as - demonstrated below:: - - >>> a=Numeric.ones(8,'i') - >>> fib1.fib(a) - >>> print a - [1 1 1 1 1 1 1 1] - - Clearly, this is not an expected behaviour. The fact that the - above example worked with ``typecode='d'`` is considered - accidental. - - F2PY provides ``intent(inplace)`` attribute that would modify - the attributes of an input array so that any changes made by - Fortran routine will be effective also in input argument. For example, - if one specifies ``intent(inplace) a`` (see below, how), then - the example above would read: - - >>> a=Numeric.ones(8,'i') - >>> fib1.fib(a) - >>> print a - [ 0. 1. 1. 2. 3. 5. 8. 13.] - - However, the recommended way to get changes made by Fortran - subroutine back to python is to use ``intent(out)`` attribute. It - is more efficient and a cleaner solution. - - * The usage of ``fib1.fib`` in Python is very similar to using - ``FIB`` in Fortran. However, using *in situ* output arguments in - Python indicates a poor style as there is no safety mechanism - in Python with respect to wrong argument types. When using Fortran - or C, compilers naturally discover any type mismatches during - compile time but in Python the types must be checked in - runtime. So, using *in situ* output arguments in Python may cause - difficult to find bugs, not to mention that the codes will be less - readable when all required type checks are implemented. - - Though the demonstrated way of wrapping Fortran routines to Python - is very straightforward, it has several drawbacks (see the comments - above). These drawbacks are due to the fact that there is no way - that F2PY can determine what is the acctual intention of one or the - other argument, is it input or output argument, or both, or - something else. So, F2PY conservatively assumes that all arguments - are input arguments by default. - - However, there are ways (see below) how to "teach" F2PY about the - true intentions (among other things) of function arguments; and then - F2PY is able to generate more Pythonic (more explicit, easier to - use, and less error prone) wrappers to Fortran functions. - -The smart way -============== - -Let's apply the steps of wrapping Fortran functions to Python one by -one. - -* First, we create a signature file from ``fib1.f`` by running - - :: - - f2py fib1.f -m fib2 -h fib1.pyf - - The signature file is saved to ``fib1.pyf`` (see ``-h`` flag) and - its contents is shown below. - - .. include:: fib1.pyf - :literal: - -* Next, we'll teach F2PY that the argument ``n`` is a input argument - (use ``intent(in)`` attribute) and that the result, i.e. the - contents of ``a`` after calling Fortran function ``FIB``, should be - returned to Python (use ``intent(out)`` attribute). In addition, an - array ``a`` should be created dynamically using the size given by - the input argument ``n`` (use ``depend(n)`` attribute to indicate - dependence relation). - - The content of a modified version of ``fib1.pyf`` (saved as - ``fib2.pyf``) is as follows: - - .. include:: fib2.pyf - :literal: - -* And finally, we build the extension module by running - - :: - - f2py -c fib2.pyf fib1.f - -In Python:: - - >>> import fib2 - >>> print fib2.fib.__doc__ - fib - Function signature: - a = fib(n) - Required arguments: - n : input int - Return objects: - a : rank-1 array('d') with bounds (n) - - >>> print fib2.fib(8) - [ 0. 1. 1. 2. 3. 5. 8. 13.] - -.. topic:: Comments - - * Clearly, the signature of ``fib2.fib`` now corresponds to the - intention of Fortran subroutine ``FIB`` more closely: given the - number ``n``, ``fib2.fib`` returns the first ``n`` Fibonacci numbers - as a Numeric array. Also, the new Python signature ``fib2.fib`` - rules out any surprises that we experienced with ``fib1.fib``. - - * Note that by default using single ``intent(out)`` also implies - ``intent(hide)``. Argument that has ``intent(hide)`` attribute - specified, will not be listed in the argument list of a wrapper - function. - -The quick and smart way -======================== - -The "smart way" of wrapping Fortran functions, as explained above, is -suitable for wrapping (e.g. third party) Fortran codes for which -modifications to their source codes are not desirable nor even -possible. - -However, if editing Fortran codes is acceptable, then the generation -of an intermediate signature file can be skipped in most -cases. Namely, F2PY specific attributes can be inserted directly to -Fortran source codes using the so-called F2PY directive. A F2PY -directive defines special comment lines (starting with ``Cf2py``, for -example) which are ignored by Fortran compilers but F2PY interprets -them as normal lines. - -Here is shown a `modified version of the example Fortran code`__, saved -as ``fib3.f``: - -.. include:: fib3.f - :literal: - -__ fib3.f - -Building the extension module can be now carried out in one command:: - - f2py -c -m fib3 fib3.f - -Notice that the resulting wrapper to ``FIB`` is as "smart" as in -previous case:: - - >>> import fib3 - >>> print fib3.fib.__doc__ - fib - Function signature: - a = fib(n) - Required arguments: - n : input int - Return objects: - a : rank-1 array('d') with bounds (n) - - >>> print fib3.fib(8) - [ 0. 1. 1. 2. 3. 5. 8. 13.] - - -================== - Signature file -================== - -The syntax specification for signature files (.pyf files) is borrowed -from the Fortran 90/95 language specification. Almost all Fortran -90/95 standard constructs are understood, both in free and fixed -format (recall that Fortran 77 is a subset of Fortran 90/95). F2PY -introduces also some extensions to Fortran 90/95 language -specification that help designing Fortran to Python interface, make it -more "Pythonic". - -Signature files may contain arbitrary Fortran code (so that Fortran -codes can be considered as signature files). F2PY silently ignores -Fortran constructs that are irrelevant for creating the interface. -However, this includes also syntax errors. So, be careful not making -ones;-). - -In general, the contents of signature files is case-sensitive. When -scanning Fortran codes and writing a signature file, F2PY lowers all -cases automatically except in multi-line blocks or when ``--no-lower`` -option is used. - -The syntax of signature files is overvied below. - -Python module block -===================== - -A signature file may contain one (recommended) or more ``python -module`` blocks. ``python module`` block describes the contents of -a Python/C extension module ``<modulename>module.c`` that F2PY -generates. - -Exception: if ``<modulename>`` contains a substring ``__user__``, then -the corresponding ``python module`` block describes the signatures of -so-called call-back functions (see `Call-back arguments`_). - -A ``python module`` block has the following structure:: - - python module <modulename> - [<usercode statement>]... - [ - interface - <usercode statement> - <Fortran block data signatures> - <Fortran/C routine signatures> - end [interface] - ]... - [ - interface - module <F90 modulename> - [<F90 module data type declarations>] - [<F90 module routine signatures>] - end [module [<F90 modulename>]] - end [interface] - ]... - end [python module [<modulename>]] - -Here brackets ``[]`` indicate a optional part, dots ``...`` indicate -one or more of a previous part. So, ``[]...`` reads zero or more of a -previous part. - - -Fortran/C routine signatures -============================= - -The signature of a Fortran routine has the following structure:: - - [<typespec>] function | subroutine <routine name> \ - [ ( [<arguments>] ) ] [ result ( <entityname> ) ] - [<argument/variable type declarations>] - [<argument/variable attribute statements>] - [<use statements>] - [<common block statements>] - [<other statements>] - end [ function | subroutine [<routine name>] ] - -From a Fortran routine signature F2PY generates a Python/C extension -function that has the following signature:: - - def <routine name>(<required arguments>[,<optional arguments>]): - ... - return <return variables> - -The signature of a Fortran block data has the following structure:: - - block data [ <block data name> ] - [<variable type declarations>] - [<variable attribute statements>] - [<use statements>] - [<common block statements>] - [<include statements>] - end [ block data [<block data name>] ] - -Type declarations -------------------- - - The definition of the ``<argument/variable type declaration>`` part - is - - :: - - <typespec> [ [<attrspec>] :: ] <entitydecl> - - where - - :: - - <typespec> := byte | character [<charselector>] - | complex [<kindselector>] | real [<kindselector>] - | double complex | double precision - | integer [<kindselector>] | logical [<kindselector>] - - <charselector> := * <charlen> - | ( [len=] <len> [ , [kind=] <kind>] ) - | ( kind= <kind> [ , len= <len> ] ) - <kindselector> := * <intlen> | ( [kind=] <kind> ) - - <entitydecl> := <name> [ [ * <charlen> ] [ ( <arrayspec> ) ] - | [ ( <arrayspec> ) ] * <charlen> ] - | [ / <init_expr> / | = <init_expr> ] \ - [ , <entitydecl> ] - - and - - + ``<attrspec>`` is a comma separated list of attributes_; - - + ``<arrayspec>`` is a comma separated list of dimension bounds; - - + ``<init_expr>`` is a `C expression`__. - - + ``<intlen>`` may be negative integer for ``integer`` type - specifications. In such cases ``integer*<negintlen>`` represents - unsigned C integers. - -__ `C expressions`_ - - If an argument has no ``<argument type declaration>``, its type is - determined by applying ``implicit`` rules to its name. - - -Statements ------------- - -Attribute statements: - - The ``<argument/variable attribute statement>`` is - ``<argument/variable type declaration>`` without ``<typespec>``. - In addition, in an attribute statement one cannot use other - attributes, also ``<entitydecl>`` can be only a list of names. - -Use statements: - - The definition of the ``<use statement>`` part is - - :: - - use <modulename> [ , <rename_list> | , ONLY : <only_list> ] - - where - - :: - - <rename_list> := <local_name> => <use_name> [ , <rename_list> ] - - Currently F2PY uses ``use`` statement only for linking call-back - modules and ``external`` arguments (call-back functions), see - `Call-back arguments`_. - -Common block statements: - - The definition of the ``<common block statement>`` part is - - :: - - common / <common name> / <shortentitydecl> - - where - - :: - - <shortentitydecl> := <name> [ ( <arrayspec> ) ] [ , <shortentitydecl> ] - - One ``python module`` block should not contain two or more - ``common`` blocks with the same name. Otherwise, the latter ones are - ignored. The types of variables in ``<shortentitydecl>`` are defined - using ``<argument type declarations>``. Note that the corresponding - ``<argument type declarations>`` may contain array specifications; - then you don't need to specify these in ``<shortentitydecl>``. - -Other statements: - - The ``<other statement>`` part refers to any other Fortran language - constructs that are not described above. F2PY ignores most of them - except - - + ``call`` statements and function calls of ``external`` arguments - (`more details`__?); - -__ external_ - - + ``include`` statements - - :: - - include '<filename>' - include "<filename>" - - If a file ``<filename>`` does not exist, the ``include`` - statement is ignored. Otherwise, the file ``<filename>`` is - included to a signature file. ``include`` statements can be used - in any part of a signature file, also outside the Fortran/C - routine signature blocks. - - + ``implicit`` statements - - :: - - implicit none - implicit <list of implicit maps> - - where - - :: - - <implicit map> := <typespec> ( <list of letters or range of letters> ) - - Implicit rules are used to deterimine the type specification of - a variable (from the first-letter of its name) if the variable - is not defined using ``<variable type declaration>``. Default - implicit rule is given by - - :: - - implicit real (a-h,o-z,$_), integer (i-m) - - + ``entry`` statements - - :: - - entry <entry name> [([<arguments>])] - - F2PY generates wrappers to all entry names using the signature - of the routine block. - - Tip: ``entry`` statement can be used to describe the signature - of an arbitrary routine allowing F2PY to generate a number of - wrappers from only one routine block signature. There are few - restrictions while doing this: ``fortranname`` cannot be used, - ``callstatement`` and ``callprotoargument`` can be used only if - they are valid for all entry routines, etc. - - In addition, F2PY introduces the following statements: - - + ``threadsafe`` - Use ``Py_BEGIN_ALLOW_THREADS .. Py_END_ALLOW_THREADS`` block - around the call to Fortran/C function. - - + ``callstatement <C-expr|multi-line block>`` - Replace F2PY generated call statement to Fortran/C function with - ``<C-expr|multi-line block>``. The wrapped Fortran/C function - is available as ``(*f2py_func)``. To raise an exception, set - ``f2py_success = 0`` in ``<C-expr|multi-line block>``. - - + ``callprotoargument <C-typespecs>`` - When ``callstatement`` statement is used then F2PY may not - generate proper prototypes for Fortran/C functions (because - ``<C-expr>`` may contain any function calls and F2PY has no way - to determine what should be the proper prototype). With this - statement you can explicitely specify the arguments of the - corresponding prototype:: - - extern <return type> FUNC_F(<routine name>,<ROUTINE NAME>)(<callprotoargument>); - - + ``fortranname [<acctual Fortran/C routine name>]`` - You can use arbitrary ``<routine name>`` for a given Fortran/C - function. Then you have to specify - ``<acctual Fortran/C routine name>`` with this statement. - - If ``fortranname`` statement is used without - ``<acctual Fortran/C routine name>`` then a dummy wrapper is - generated. - - + ``usercode <multi-line block>`` - When used inside ``python module`` block, then given C code - will be inserted to generated C/API source just before - wrapper function definitions. Here you can define arbitrary - C functions to be used in initialization of optional arguments, - for example. If ``usercode`` is used twise inside ``python - module`` block then the second multi-line block is inserted - after the definition of external routines. - - When used inside ``<routine singature>``, then given C code will - be inserted to the corresponding wrapper function just after - declaring variables but before any C statements. So, ``usercode`` - follow-up can contain both declarations and C statements. - - When used inside the first ``interface`` block, then given C - code will be inserted at the end of the initialization - function of the extension module. Here you can modify extension - modules dictionary. For example, for defining additional - variables etc. - - + ``pymethoddef <multi-line block>`` - Multiline block will be inserted to the definition of - module methods ``PyMethodDef``-array. It must be a - comma-separated list of C arrays (see `Extending and Embedding`__ - Python documentation for details). - ``pymethoddef`` statement can be used only inside - ``python module`` block. - - __ http://www.python.org/doc/current/ext/ext.html - -Attributes ------------- - -The following attributes are used by F2PY: - -``optional`` - The corresponding argument is moved to the end of ``<optional - arguments>`` list. A default value for an optional argument can be - specified ``<init_expr>``, see ``entitydecl`` definition. Note that - the default value must be given as a valid C expression. - - Note that whenever ``<init_expr>`` is used, ``optional`` attribute - is set automatically by F2PY. - - For an optional array argument, all its dimensions must be bounded. - -``required`` - The corresponding argument is considered as a required one. This is - default. You need to specify ``required`` only if there is a need to - disable automatic ``optional`` setting when ``<init_expr>`` is used. - - If Python ``None`` object is used as an required argument, the - argument is treated as optional. That is, in the case of array - argument, the memory is allocated. And if ``<init_expr>`` is given, - the corresponding initialization is carried out. - -``dimension(<arrayspec>)`` - The corresponding variable is considered as an array with given - dimensions in ``<arrayspec>``. - -``intent(<intentspec>)`` - This specifies the "intention" of the corresponding - argument. ``<intentspec>`` is a comma separated list of the - following keys: - - + ``in`` - The argument is considered as an input-only argument. It means - that the value of the argument is passed to Fortran/C function and - that function is expected not to change the value of an argument. - - + ``inout`` - The argument is considered as an input/output or *in situ* - output argument. ``intent(inout)`` arguments can be only - "contiguous" Numeric arrays with proper type and size. Here - "contiguous" can be either in Fortran or C sense. The latter one - coincides with the contiguous concept used in Numeric and is - effective only if ``intent(c)`` is used. Fortran-contiguousness - is assumed by default. - - Using ``intent(inout)`` is generally not recommended, use - ``intent(in,out)`` instead. See also ``intent(inplace)`` attribute. - - + ``inplace`` - The argument is considered as an input/output or *in situ* - output argument. ``intent(inplace)`` arguments must be - Numeric arrays with proper size. If the type of an array is - not "proper" or the array is non-contiguous then the array - will be changed in-place to fix the type and make it contiguous. - - Using ``intent(inplace)`` is generally not recommended either. - For example, when slices have been taken from an - ``intent(inplace)`` argument then after in-place changes, - slices data pointers may point to unallocated memory area. - - + ``out`` - The argument is considered as an return variable. It is appended - to the ``<returned variables>`` list. Using ``intent(out)`` - sets ``intent(hide)`` automatically, unless also - ``intent(in)`` or ``intent(inout)`` were used. - - By default, returned multidimensional arrays are - Fortran-contiguous. If ``intent(c)`` is used, then returned - multi-dimensional arrays are C-contiguous. - - + ``hide`` - The argument is removed from the list of required or optional - arguments. Typically ``intent(hide)`` is used with ``intent(out)`` - or when ``<init_expr>`` completely determines the value of the - argument like in the following example:: - - integer intent(hide),depend(a) :: n = len(a) - real intent(in),dimension(n) :: a - - + ``c`` - The argument is treated as a C scalar or C array argument. In - the case of a scalar argument, its value is passed to C function - as a C scalar argument (recall that Fortran scalar arguments are - actually C pointer arguments). In the case of an array - argument, the wrapper function is assumed to treat - multi-dimensional arrays as C-contiguous arrays. - - There is no need to use ``intent(c)`` for one-dimensional - arrays, no matter if the wrapped function is either a Fortran or - a C function. This is because the concepts of Fortran- and - C-contiguousness overlap in one-dimensional cases. - - If ``intent(c)`` is used as an statement but without entity - declaration list, then F2PY adds ``intent(c)`` attibute to all - arguments. - - Also, when wrapping C functions, one must use ``intent(c)`` - attribute for ``<routine name>`` in order to disable Fortran - specific ``F_FUNC(..,..)`` macros. - - + ``cache`` - The argument is treated as a junk of memory. No Fortran nor C - contiguousness checks are carried out. Using ``intent(cache)`` - makes sense only for array arguments, also in connection with - ``intent(hide)`` or ``optional`` attributes. - - + ``copy`` - Ensure that the original contents of ``intent(in)`` argument is - preserved. Typically used in connection with ``intent(in,out)`` - attribute. F2PY creates an optional argument - ``overwrite_<argument name>`` with the default value ``0``. - - + ``overwrite`` - The original contents of the ``intent(in)`` argument may be - altered by the Fortran/C function. F2PY creates an optional - argument ``overwrite_<argument name>`` with the default value - ``1``. - - + ``out=<new name>`` - Replace the return name with ``<new name>`` in the ``__doc__`` - string of a wrapper function. - - + ``callback`` - Construct an external function suitable for calling Python function - from Fortran. ``intent(callback)`` must be specified before the - corresponding ``external`` statement. If 'argument' is not in - argument list then it will be added to Python wrapper but only - initializing external function. - - Use ``intent(callback)`` in situations where a Fortran/C code - assumes that a user implements a function with given prototype - and links it to an executable. Don't use ``intent(callback)`` - if function appears in the argument list of a Fortran routine. - - With ``intent(hide)`` or ``optional`` attributes specified and - using a wrapper function without specifying the callback argument - in argument list then call-back function is looked in the - namespace of F2PY generated extension module where it can be - set as a module attribute by a user. - - + ``aux`` - Define auxiliary C variable in F2PY generated wrapper function. - Useful to save parameter values so that they can be accessed - in initialization expression of other variables. Note that - ``intent(aux)`` silently implies ``intent(c)``. - - The following rules apply: - - + If no ``intent(in | inout | out | hide)`` is specified, - ``intent(in)`` is assumed. - + ``intent(in,inout)`` is ``intent(in)``. - + ``intent(in,hide)`` or ``intent(inout,hide)`` is - ``intent(hide)``. - + ``intent(out)`` is ``intent(out,hide)`` unless ``intent(in)`` or - ``intent(inout)`` is specified. - + If ``intent(copy)`` or ``intent(overwrite)`` is used, then an - additional optional argument is introduced with a name - ``overwrite_<argument name>`` and a default value 0 or 1, respectively. - + ``intent(inout,inplace)`` is ``intent(inplace)``. - + ``intent(in,inplace)`` is ``intent(inplace)``. - + ``intent(hide)`` disables ``optional`` and ``required``. - -``check([<C-booleanexpr>])`` - Perform consistency check of arguments by evaluating - ``<C-booleanexpr>``; if ``<C-booleanexpr>`` returns 0, an exception - is raised. - - If ``check(..)`` is not used then F2PY generates few standard checks - (e.g. in a case of an array argument, check for the proper shape - and size) automatically. Use ``check()`` to disable checks generated - by F2PY. - -``depend([<names>])`` - This declares that the corresponding argument depends on the values - of variables in the list ``<names>``. For example, ``<init_expr>`` - may use the values of other arguments. Using information given by - ``depend(..)`` attributes, F2PY ensures that arguments are - initialized in a proper order. If ``depend(..)`` attribute is not - used then F2PY determines dependence relations automatically. Use - ``depend()`` to disable dependence relations generated by F2PY. - - When you edit dependence relations that were initially generated by - F2PY, be careful not to break the dependence relations of other - relevant variables. Another thing to watch out is cyclic - dependencies. F2PY is able to detect cyclic dependencies - when constructing wrappers and it complains if any are found. - -``allocatable`` - The corresponding variable is Fortran 90 allocatable array defined - as Fortran 90 module data. - -.. _external: - -``external`` - The corresponding argument is a function provided by user. The - signature of this so-called call-back function can be defined - - - in ``__user__`` module block, - - or by demonstrative (or real, if the signature file is a real Fortran - code) call in the ``<other statements>`` block. - - For example, F2PY generates from - - :: - - external cb_sub, cb_fun - integer n - real a(n),r - call cb_sub(a,n) - r = cb_fun(4) - - the following call-back signatures:: - - subroutine cb_sub(a,n) - real dimension(n) :: a - integer optional,check(len(a)>=n),depend(a) :: n=len(a) - end subroutine cb_sub - function cb_fun(e_4_e) result (r) - integer :: e_4_e - real :: r - end function cb_fun - - The corresponding user-provided Python function are then:: - - def cb_sub(a,[n]): - ... - return - def cb_fun(e_4_e): - ... - return r - - See also ``intent(callback)`` attribute. - -``parameter`` - The corresponding variable is a parameter and it must have a fixed - value. F2PY replaces all parameter occurrences by their - corresponding values. - -Extensions -============ - -F2PY directives ------------------ - -The so-called F2PY directives allow using F2PY signature file -constructs also in Fortran 77/90 source codes. With this feature you -can skip (almost) completely intermediate signature file generations -and apply F2PY directly to Fortran source codes. - -F2PY directive has the following form:: - - <comment char>f2py ... - -where allowed comment characters for fixed and free format Fortran -codes are ``cC*!#`` and ``!``, respectively. Everything that follows -``<comment char>f2py`` is ignored by a compiler but read by F2PY as a -normal Fortran (non-comment) line: - - When F2PY finds a line with F2PY directive, the directive is first - replaced by 5 spaces and then the line is reread. - -For fixed format Fortran codes, ``<comment char>`` must be at the -first column of a file, of course. For free format Fortran codes, -F2PY directives can appear anywhere in a file. - -C expressions --------------- - -C expressions are used in the following parts of signature files: - -* ``<init_expr>`` of variable initialization; -* ``<C-booleanexpr>`` of the ``check`` attribute; -* ``<arrayspec> of the ``dimension`` attribute; -* ``callstatement`` statement, here also a C multi-line block can be used. - -A C expression may contain: - -* standard C constructs; -* functions from ``math.h`` and ``Python.h``; -* variables from the argument list, presumably initialized before - according to given dependence relations; -* the following CPP macros: - - ``rank(<name>)`` - Returns the rank of an array ``<name>``. - ``shape(<name>,<n>)`` - Returns the ``<n>``-th dimension of an array ``<name>``. - ``len(<name>)`` - Returns the lenght of an array ``<name>``. - ``size(<name>)`` - Returns the size of an array ``<name>``. - ``slen(<name>)`` - Returns the length of a string ``<name>``. - -For initializing an array ``<array name>``, F2PY generates a loop over -all indices and dimensions that executes the following -pseudo-statement:: - - <array name>(_i[0],_i[1],...) = <init_expr>; - -where ``_i[<i>]`` refers to the ``<i>``-th index value and that runs -from ``0`` to ``shape(<array name>,<i>)-1``. - -For example, a function ``myrange(n)`` generated from the following -signature - -:: - - subroutine myrange(a,n) - fortranname ! myrange is a dummy wrapper - integer intent(in) :: n - real*8 intent(c,out),dimension(n),depend(n) :: a = _i[0] - end subroutine myrange - -is equivalent to ``Numeric.arange(n,typecode='d')``. - -.. topic:: Warning! - - F2PY may lower cases also in C expressions when scanning Fortran codes - (see ``--[no]-lower`` option). - -Multi-line blocks ------------------- - -A multi-line block starts with ``'''`` (triple single-quotes) and ends -with ``'''`` in some *strictly* subsequent line. Multi-line blocks can -be used only within .pyf files. The contents of a multi-line block can -be arbitrary (except that it cannot contain ``'''``) and no -transformations (e.g. lowering cases) are applied to it. - -Currently, multi-line blocks can be used in the following constructs: - -+ as a C expression of the ``callstatement`` statement; - -+ as a C type specification of the ``callprotoargument`` statement; - -+ as a C code block of the ``usercode`` statement; - -+ as a list of C arrays of the ``pymethoddef`` statement; - -+ as documentation string. - -================================== -Using F2PY bindings in Python -================================== - -All wrappers (to Fortran/C routines or to common blocks or to Fortran -90 module data) generated by F2PY are exposed to Python as ``fortran`` -type objects. Routine wrappers are callable ``fortran`` type objects -while wrappers to Fortran data have attributes referring to data -objects. - -All ``fortran`` type object have attribute ``_cpointer`` that contains -CObject referring to the C pointer of the corresponding Fortran/C -function or variable in C level. Such CObjects can be used as an -callback argument of F2PY generated functions to bypass Python C/API -layer of calling Python functions from Fortran or C when the -computational part of such functions is implemented in C or Fortran -and wrapped with F2PY (or any other tool capable of providing CObject -of a function). - -.. topic:: Example - - Consider a `Fortran 77 file`__ ``ftype.f``: - - .. include:: ftype.f - :literal: - - and build a wrapper using:: - - f2py -c ftype.f -m ftype - - __ ftype.f - - In Python: - - .. include:: ftype_session.dat - :literal: - - -Scalar arguments -================= - -In general, a scalar argument of a F2PY generated wrapper function can -be ordinary Python scalar (integer, float, complex number) as well as -an arbitrary sequence object (list, tuple, array, string) of -scalars. In the latter case, the first element of the sequence object -is passed to Fortran routine as a scalar argument. - -Note that when type-casting is required and there is possible loss of -information (e.g. when type-casting float to integer or complex to -float), F2PY does not raise any exception. In complex to real -type-casting only the real part of a complex number is used. - -``intent(inout)`` scalar arguments are assumed to be array objects in -order to *in situ* changes to be effective. It is recommended to use -arrays with proper type but also other types work. - -.. topic:: Example - - Consider the following `Fortran 77 code`__: - - .. include:: scalar.f - :literal: - - and wrap it using ``f2py -c -m scalar scalar.f``. - - __ scalar.f - - In Python: - - .. include:: scalar_session.dat - :literal: - - -String arguments -================= - -F2PY generated wrapper functions accept (almost) any Python object as -a string argument, ``str`` is applied for non-string objects. -Exceptions are Numeric arrays that must have type code ``'c'`` or -``'1'`` when used as string arguments. - -A string can have arbitrary length when using it as a string argument -to F2PY generated wrapper function. If the length is greater than -expected, the string is truncated. If the length is smaller that -expected, additional memory is allocated and filled with ``\0``. - -Because Python strings are immutable, an ``intent(inout)`` argument -expects an array version of a string in order to *in situ* changes to -be effective. - -.. topic:: Example - - Consider the following `Fortran 77 code`__: - - .. include:: string.f - :literal: - - and wrap it using ``f2py -c -m mystring string.f``. - - __ string.f - - Python session: - - .. include:: string_session.dat - :literal: - - -Array arguments -================ - -In general, array arguments of F2PY generated wrapper functions accept -arbitrary sequences that can be transformed to Numeric array objects. -An exception is ``intent(inout)`` array arguments that always must be -proper-contiguous and have proper type, otherwise an exception is -raised. Another exception is ``intent(inplace)`` array arguments that -attributes will be changed in-situ if the argument has different type -than expected (see ``intent(inplace)`` attribute for more -information). - -In general, if a Numeric array is proper-contiguous and has a proper -type then it is directly passed to wrapped Fortran/C function. -Otherwise, an element-wise copy of an input array is made and the -copy, being proper-contiguous and with proper type, is used as an -array argument. - -There are two types of proper-contiguous Numeric arrays: - -* Fortran-contiguous arrays when data is stored column-wise, - i.e. indexing of data as stored in memory starts from the lowest - dimension; -* C-contiguous or simply contiguous arrays when data is stored - row-wise, i.e. indexing of data as stored in memory starts from the - highest dimension. - -For one-dimensional arrays these notions coincide. - -For example, an 2x2 array ``A`` is Fortran-contiguous if its elements -are stored in memory in the following order:: - - A[0,0] A[1,0] A[0,1] A[1,1] - -and C-contiguous if the order is as follows:: - - A[0,0] A[0,1] A[1,0] A[1,1] - -To test whether an array is C-contiguous, use ``.iscontiguous()`` -method of Numeric arrays. To test for Fortran-contiguousness, all -F2PY generated extension modules provide a function -``has_column_major_storage(<array>)``. This function is equivalent to -``Numeric.transpose(<array>).iscontiguous()`` but more efficient. - -Usually there is no need to worry about how the arrays are stored in -memory and whether the wrapped functions, being either Fortran or C -functions, assume one or another storage order. F2PY automatically -ensures that wrapped functions get arguments with proper storage -order; the corresponding algorithm is designed to make copies of -arrays only when absolutely necessary. However, when dealing with very -large multi-dimensional input arrays with sizes close to the size of -the physical memory in your computer, then a care must be taken to use -always proper-contiguous and proper type arguments. - -To transform input arrays to column major storage order before passing -them to Fortran routines, use a function -``as_column_major_storage(<array>)`` that is provided by all F2PY -generated extension modules. - -.. topic:: Example - - Consider `Fortran 77 code`__: - - .. include:: array.f - :literal: - - and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``. - - __ array.f - - In Python: - - .. include:: array_session.dat - :literal: - -Call-back arguments -==================== - -F2PY supports calling Python functions from Fortran or C codes. - - -.. topic:: Example - - Consider the following `Fortran 77 code`__ - - .. include:: callback.f - :literal: - - and wrap it using ``f2py -c -m callback callback.f``. - - __ callback.f - - In Python: - - .. include:: callback_session.dat - :literal: - -In the above example F2PY was able to guess accurately the signature -of a call-back function. However, sometimes F2PY cannot establish the -signature as one would wish and then the signature of a call-back -function must be modified in the signature file manually. Namely, -signature files may contain special modules (the names of such modules -contain a substring ``__user__``) that collect various signatures of -call-back functions. Callback arguments in routine signatures have -attribute ``external`` (see also ``intent(callback)`` attribute). To -relate a callback argument and its signature in ``__user__`` module -block, use ``use`` statement as illustrated below. The same signature -of a callback argument can be referred in different routine -signatures. - -.. topic:: Example - - We use the same `Fortran 77 code`__ as in previous example but now - we'll pretend that F2PY was not able to guess the signatures of - call-back arguments correctly. First, we create an initial signature - file ``callback2.pyf`` using F2PY:: - - f2py -m callback2 -h callback2.pyf callback.f - - Then modify it as follows - - .. include:: callback2.pyf - :literal: - - Finally, build the extension module using:: - - f2py -c callback2.pyf callback.f - - An example Python session would be identical to the previous example - except that argument names would differ. - - __ callback.f - -Sometimes a Fortran package may require that users provide routines -that the package will use. F2PY can construct an interface to such -routines so that Python functions could be called from Fortran. - -.. topic:: Example - - Consider the following `Fortran 77 subroutine`__ that takes an array - and applies a function ``func`` to its elements. - - .. include:: calculate.f - :literal: - - __ calculate.f - - It is expected that function ``func`` has been defined - externally. In order to use a Python function as ``func``, it must - have an attribute ``intent(callback)`` (it must be specified before - the ``external`` statement). - - Finally, build an extension module using:: - - f2py -c -m foo calculate.f - - In Python: - - .. include:: calculate_session.dat - :literal: - -The function is included as an argument to the python function call to -the FORTRAN subroutine eventhough it was NOT in the FORTRAN subroutine argument -list. The "external" refers to the C function generated by f2py, not the python -function itself. The python function must be supplied to the C function. - -The callback function may also be explicitly set in the module. -Then it is not necessary to pass the function in the argument list to -the FORTRAN function. This may be desired if the FORTRAN function calling -the python callback function is itself called by another FORTRAN function. - -.. topic:: Example - - Consider the following `Fortran 77 subroutine`__. - - .. include:: extcallback.f - :literal: - - __ extcallback.f - - and wrap it using ``f2py -c -m pfromf extcallback.f``. - - In Python: - - .. include:: extcallback_session.dat - :literal: - -Resolving arguments to call-back functions ------------------------------------------- - -F2PY generated interface is very flexible with respect to call-back -arguments. For each call-back argument an additional optional -argument ``<name>_extra_args`` is introduced by F2PY. This argument -can be used to pass extra arguments to user provided call-back -arguments. - -If a F2PY generated wrapper function expects the following call-back -argument:: - - def fun(a_1,...,a_n): - ... - return x_1,...,x_k - -but the following Python function - -:: - - def gun(b_1,...,b_m): - ... - return y_1,...,y_l - -is provided by an user, and in addition, - -:: - - fun_extra_args = (e_1,...,e_p) - -is used, then the following rules are applied when a Fortran or C -function calls the call-back argument ``gun``: - -* If ``p==0`` then ``gun(a_1,...,a_q)`` is called, here - ``q=min(m,n)``. -* If ``n+p<=m`` then ``gun(a_1,...,a_n,e_1,...,e_p)`` is called. -* If ``p<=m<n+p`` then ``gun(a_1,...,a_q,e_1,...,e_p)`` is called, here - ``q=m-p``. -* If ``p>m`` then ``gun(e_1,...,e_m)`` is called. -* If ``n+p`` is less than the number of required arguments to ``gun`` - then an exception is raised. - -The function ``gun`` may return any number of objects as a tuple. Then -following rules are applied: - -* If ``k<l``, then ``y_{k+1},...,y_l`` are ignored. -* If ``k>l``, then only ``x_1,...,x_l`` are set. - - - -Common blocks -============== - -F2PY generates wrappers to ``common`` blocks defined in a routine -signature block. Common blocks are visible by all Fortran codes linked -with the current extension module, but not to other extension modules -(this restriction is due to how Python imports shared libraries). In -Python, the F2PY wrappers to ``common`` blocks are ``fortran`` type -objects that have (dynamic) attributes related to data members of -common blocks. When accessed, these attributes return as Numeric array -objects (multi-dimensional arrays are Fortran-contiguous) that -directly link to data members in common blocks. Data members can be -changed by direct assignment or by in-place changes to the -corresponding array objects. - -.. topic:: Example - - Consider the following `Fortran 77 code`__ - - .. include:: common.f - :literal: - - and wrap it using ``f2py -c -m common common.f``. - - __ common.f - - In Python: - - .. include:: common_session.dat - :literal: - -Fortran 90 module data -======================= - -The F2PY interface to Fortran 90 module data is similar to Fortran 77 -common blocks. - -.. topic:: Example - - Consider the following `Fortran 90 code`__ - - .. include:: moddata.f90 - :literal: - - and wrap it using ``f2py -c -m moddata moddata.f90``. - - __ moddata.f90 - - In Python: - - .. include:: moddata_session.dat - :literal: - -Allocatable arrays -------------------- - -F2PY has basic support for Fortran 90 module allocatable arrays. - -.. topic:: Example - - Consider the following `Fortran 90 code`__ - - .. include:: allocarr.f90 - :literal: - - and wrap it using ``f2py -c -m allocarr allocarr.f90``. - - __ allocarr.f90 - - In Python: - - .. include:: allocarr_session.dat - :literal: - - -=========== -Using F2PY -=========== - -F2PY can be used either as a command line tool ``f2py`` or as a Python -module ``f2py2e``. - -Command ``f2py`` -================= - -When used as a command line tool, ``f2py`` has three major modes, -distinguished by the usage of ``-c`` and ``-h`` switches: - -1. To scan Fortran sources and generate a signature file, use - - :: - - f2py -h <filename.pyf> <options> <fortran files> \ - [[ only: <fortran functions> : ] \ - [ skip: <fortran functions> : ]]... \ - [<fortran files> ...] - - Note that a Fortran source file can contain many routines, and not - necessarily all routines are needed to be used from Python. So, you - can either specify which routines should be wrapped (in ``only: .. :`` - part) or which routines F2PY should ignored (in ``skip: .. :`` part). - - If ``<filename.pyf>`` is specified as ``stdout`` then signatures - are send to standard output instead of a file. - - Among other options (see below), the following options can be used - in this mode: - - ``--overwrite-signature`` - Overwrite existing signature file. - -2. To construct an extension module, use - - :: - - f2py <options> <fortran files> \ - [[ only: <fortran functions> : ] \ - [ skip: <fortran functions> : ]]... \ - [<fortran files> ...] - - The constructed extension module is saved as - ``<modulename>module.c`` to the current directory. - - Here ``<fortran files>`` may also contain signature files. - Among other options (see below), the following options can be used - in this mode: - - ``--debug-capi`` - Add debugging hooks to the extension module. When using this - extension module, various information about the wrapper is printed - to standard output, for example, the values of variables, the - steps taken, etc. - - ``-include'<includefile>'`` - Add a CPP ``#include`` statement to the extension module source. - ``<includefile>`` should be given in one of the following forms:: - - "filename.ext" - <filename.ext> - - The include statement is inserted just before the wrapper - functions. This feature enables using arbitrary C functions - (defined in ``<includefile>``) in F2PY generated wrappers. - - This option is deprecated. Use ``usercode`` statement to specify - C codelets directly in signature filess - - - ``--[no-]wrap-functions`` - - Create Fortran subroutine wrappers to Fortran functions. - ``--wrap-functions`` is default because it ensures maximum - portability and compiler independence. - - ``--include-paths <path1>:<path2>:..`` - Search include files from given directories. - - ``--help-link [<list of resources names>]`` - List system resources found by ``numpy_distutils/system_info.py``. - For example, try ``f2py --help-link lapack_opt``. - -3. To build an extension module, use - - :: - - f2py -c <options> <fortran files> \ - [[ only: <fortran functions> : ] \ - [ skip: <fortran functions> : ]]... \ - [ <fortran/c source files> ] [ <.o, .a, .so files> ] - - If ``<fortran files>`` contains a signature file, then a source for - an extension module is constructed, all Fortran and C sources are - compiled, and finally all object and library files are linked to the - extension module ``<modulename>.so`` which is saved into the current - directory. - - If ``<fortran files>`` does not contain a signature file, then an - extension module is constructed by scanning all Fortran source codes - for routine signatures. - - Among other options (see below) and options described in previous - mode, the following options can be used in this mode: - - ``--help-fcompiler`` - List available Fortran compilers. - ``--help-compiler`` [depreciated] - List available Fortran compilers. - ``--fcompiler=<Vendor>`` - Specify Fortran compiler type by vendor. - ``--f77exec=<path>`` - Specify the path to F77 compiler - ``--fcompiler-exec=<path>`` [depreciated] - Specify the path to F77 compiler - ``--f90exec=<path>`` - Specify the path to F90 compiler - ``--f90compiler-exec=<path>`` [depreciated] - Specify the path to F90 compiler - - ``--f77flags=<string>`` - Specify F77 compiler flags - ``--f90flags=<string>`` - Specify F90 compiler flags - ``--opt=<string>`` - Specify optimization flags - ``--arch=<string>`` - Specify architecture specific optimization flags - ``--noopt`` - Compile without optimization - ``--noarch`` - Compile without arch-dependent optimization - ``--debug`` - Compile with debugging information - - ``-l<libname>`` - Use the library ``<libname>`` when linking. - ``-D<macro>[=<defn=1>]`` - Define macro ``<macro>`` as ``<defn>``. - ``-U<macro>`` - Define macro ``<macro>`` - ``-I<dir>`` - Append directory ``<dir>`` to the list of directories searched for - include files. - ``-L<dir>`` - Add directory ``<dir>`` to the list of directories to be searched - for ``-l``. - - ``link-<resource>`` - - Link extension module with <resource> as defined by - ``numpy_distutils/system_info.py``. E.g. to link with optimized - LAPACK libraries (vecLib on MacOSX, ATLAS elsewhere), use - ``--link-lapack_opt``. See also ``--help-link`` switch. - - When building an extension module, a combination of the following - macros may be required for non-gcc Fortran compilers:: - - -DPREPEND_FORTRAN - -DNO_APPEND_FORTRAN - -DUPPERCASE_FORTRAN - - To test the performance of F2PY generated interfaces, use - ``-DF2PY_REPORT_ATEXIT``. Then a report of various timings is - printed out at the exit of Python. This feature may not work on - all platforms, currently only Linux platform is supported. - - To see whether F2PY generated interface performs copies of array - arguments, use ``-DF2PY_REPORT_ON_ARRAY_COPY=<int>``. When the size - of an array argument is larger than ``<int>``, a message about - the coping is sent to ``stderr``. - -Other options: - -``-m <modulename>`` - Name of an extension module. Default is ``untitled``. Don't use this option - if a signature file (*.pyf) is used. -``--[no-]lower`` - Do [not] lower the cases in ``<fortran files>``. By default, - ``--lower`` is assumed with ``-h`` switch, and ``--no-lower`` - without the ``-h`` switch. -``--build-dir <dirname>`` - All F2PY generated files are created in ``<dirname>``. Default is - ``tempfile.mktemp()``. -``--quiet`` - Run quietly. -``--verbose`` - Run with extra verbosity. -``-v`` - Print f2py version ID and exit. - -Execute ``f2py`` without any options to get an up-to-date list of -available options. - -Python module ``f2py2e`` -========================= - -.. topic:: Warning - - The current Python interface to ``f2py2e`` module is not mature and - may change in future depending on users needs. - -The following functions are provided by the ``f2py2e`` module: - -``run_main(<list>)`` - Equivalent to running:: - - f2py <args> - - where ``<args>=string.join(<list>,' ')``, but in Python. Unless - ``-h`` is used, this function returns a dictionary containing - information on generated modules and their dependencies on source - files. For example, the command ``f2py -m scalar scalar.f`` can be - executed from Python as follows - - .. include:: run_main_session.dat - :literal: - - You cannot build extension modules with this function, that is, - using ``-c`` is not allowed. Use ``compile`` command instead, see - below. - -``compile(source, modulename='untitled', extra_args='', verbose=1, source_fn=None)`` - - Build extension module from Fortran 77 source string ``source``. - Return 0 if successful. - Note that this function actually calls ``f2py -c ..`` from shell to - ensure safety of the current Python process. - For example, - - .. include:: compile_session.dat - :literal: - -========================== -Using ``numpy_distutils`` -========================== - -``numpy_distutils`` is part of the SciPy_ project and aims to extend -standard Python ``distutils`` to deal with Fortran sources and F2PY -signature files, e.g. compile Fortran sources, call F2PY to construct -extension modules, etc. - -.. topic:: Example - - Consider the following `setup file`__: - - .. include:: setup_example.py - :literal: - - Running - - :: - - python setup_example.py build - - will build two extension modules ``scalar`` and ``fib2`` to the - build directory. - - __ setup_example.py - -``numpy_distutils`` extends ``distutils`` with the following features: - -* ``Extension`` class argument ``sources`` may contain Fortran source - files. In addition, the list ``sources`` may contain at most one - F2PY signature file, and then the name of an Extension module must - match with the ``<modulename>`` used in signature file. It is - assumed that an F2PY signature file contains exactly one ``python - module`` block. - - If ``sources`` does not contain a signature files, then F2PY is used - to scan Fortran source files for routine signatures to construct the - wrappers to Fortran codes. - - Additional options to F2PY process can be given using ``Extension`` - class argument ``f2py_options``. - -``numpy_distutils`` 0.2.2 and up -================================ - -* The following new ``distutils`` commands are defined: - - ``build_src`` - to construct Fortran wrapper extension modules, among many other things. - ``config_fc`` - to change Fortran compiler options - - as well as ``build_ext`` and ``build_clib`` commands are enhanced - to support Fortran sources. - - Run - - :: - - python <setup.py file> config_fc build_src build_ext --help - - to see available options for these commands. - -* When building Python packages containing Fortran sources, then one - can choose different Fortran compilers by using ``build_ext`` - command option ``--fcompiler=<Vendor>``. Here ``<Vendor>`` can be one of the - following names:: - - absoft sun mips intel intelv intele intelev nag compaq compaqv gnu vast pg hpux - - See ``numpy_distutils/fcompiler.py`` for up-to-date list of - supported compilers or run - - :: - - f2py -c --help-fcompiler - -``numpy_distutils`` pre 0.2.2 -============================= - -* The following new ``distutils`` commands are defined: - - ``build_flib`` - to build f77/f90 libraries used by Python extensions; - ``run_f2py`` - to construct Fortran wrapper extension modules. - - Run - - :: - - python <setup.py file> build_flib run_f2py --help - - to see available options for these commands. - -* When building Python packages containing Fortran sources, then one - can choose different Fortran compilers either by using ``build_flib`` - command option ``--fcompiler=<Vendor>`` or by defining environment - variable ``FC_VENDOR=<Vendor>``. Here ``<Vendor>`` can be one of the - following names:: - - Absoft Sun SGI Intel Itanium NAG Compaq Digital Gnu VAST PG - - See ``numpy_distutils/command/build_flib.py`` for up-to-date list of - supported compilers. - -====================== - Extended F2PY usages -====================== - -Adding self-written functions to F2PY generated modules -======================================================= - -Self-written Python C/API functions can be defined inside -signature files using ``usercode`` and ``pymethoddef`` statements -(they must be used inside the ``python module`` block). For -example, the following signature file ``spam.pyf`` - -.. include:: spam.pyf - :literal: - -wraps the C library function ``system()``:: - - f2py -c spam.pyf - -In Python: - -.. include:: spam_session.dat - :literal: - -Modifying the dictionary of a F2PY generated module -=================================================== - -The following example illustrates how to add an user-defined -variables to a F2PY generated extension module. Given the following -signature file - -.. include:: var.pyf - :literal: - -compile it as ``f2py -c var.pyf``. - -Notice that the second ``usercode`` statement must be defined inside -an ``interface`` block and where the module dictionary is available through -the variable ``d`` (see ``f2py var.pyf``-generated ``varmodule.c`` for -additional details). - -In Python: - -.. include:: var_session.dat - :literal: - -.. References - ========== -.. _F2PY: http://cens.ioc.ee/projects/f2py2e/ -.. _Python: http://www.python.org/ -.. _NumPy: http://www.numpy.org/ -.. _SciPy: http://www.numpy.org/ diff --git a/numpy/f2py/docs/usersguide/moddata.f90 b/numpy/f2py/docs/usersguide/moddata.f90 deleted file mode 100644 index 0e98f0467..000000000 --- a/numpy/f2py/docs/usersguide/moddata.f90 +++ /dev/null @@ -1,18 +0,0 @@ -module mod - integer i - integer :: x(4) - real, dimension(2,3) :: a - real, allocatable, dimension(:,:) :: b -contains - subroutine foo - integer k - print*, "i=",i - print*, "x=[",x,"]" - print*, "a=[" - print*, "[",a(1,1),",",a(1,2),",",a(1,3),"]" - print*, "[",a(2,1),",",a(2,2),",",a(2,3),"]" - print*, "]" - print*, "Setting a(1,2)=a(1,2)+3" - a(1,2) = a(1,2)+3 - end subroutine foo -end module mod diff --git a/numpy/f2py/docs/usersguide/moddata_session.dat b/numpy/f2py/docs/usersguide/moddata_session.dat deleted file mode 100644 index 1ec212f8b..000000000 --- a/numpy/f2py/docs/usersguide/moddata_session.dat +++ /dev/null @@ -1,23 +0,0 @@ ->>> import moddata ->>> print moddata.mod.__doc__ -i - 'i'-scalar -x - 'i'-array(4) -a - 'f'-array(2,3) -foo - Function signature: - foo() - - ->>> moddata.mod.i = 5 ->>> moddata.mod.x[:2] = [1,2] ->>> moddata.mod.a = [[1,2,3],[4,5,6]] ->>> moddata.mod.foo() - i= 5 - x=[ 1 2 0 0 ] - a=[ - [ 1.000000 , 2.000000 , 3.000000 ] - [ 4.000000 , 5.000000 , 6.000000 ] - ] - Setting a(1,2)=a(1,2)+3 ->>> moddata.mod.a # a is Fortran-contiguous -array([[ 1., 5., 3.], - [ 4., 5., 6.]],'f') diff --git a/numpy/f2py/docs/usersguide/run_main_session.dat b/numpy/f2py/docs/usersguide/run_main_session.dat deleted file mode 100644 index 29ecc3dfe..000000000 --- a/numpy/f2py/docs/usersguide/run_main_session.dat +++ /dev/null @@ -1,14 +0,0 @@ ->>> import f2py2e ->>> r=f2py2e.run_main(['-m','scalar','docs/usersguide/scalar.f']) -Reading fortran codes... - Reading file 'docs/usersguide/scalar.f' -Post-processing... - Block: scalar - Block: FOO -Building modules... - Building module "scalar"... - Wrote C/API module "scalar" to file "./scalarmodule.c" ->>> print r -{'scalar': {'h': ['/home/users/pearu/src_cvs/f2py2e/src/fortranobject.h'], - 'csrc': ['./scalarmodule.c', - '/home/users/pearu/src_cvs/f2py2e/src/fortranobject.c']}} diff --git a/numpy/f2py/docs/usersguide/scalar.f b/numpy/f2py/docs/usersguide/scalar.f deleted file mode 100644 index c22f639ed..000000000 --- a/numpy/f2py/docs/usersguide/scalar.f +++ /dev/null @@ -1,12 +0,0 @@ -C FILE: SCALAR.F - SUBROUTINE FOO(A,B) - REAL*8 A, B -Cf2py intent(in) a -Cf2py intent(inout) b - PRINT*, " A=",A," B=",B - PRINT*, "INCREMENT A AND B" - A = A + 1D0 - B = B + 1D0 - PRINT*, "NEW A=",A," B=",B - END -C END OF FILE SCALAR.F diff --git a/numpy/f2py/docs/usersguide/scalar_session.dat b/numpy/f2py/docs/usersguide/scalar_session.dat deleted file mode 100644 index 4fe8c03b1..000000000 --- a/numpy/f2py/docs/usersguide/scalar_session.dat +++ /dev/null @@ -1,21 +0,0 @@ ->>> import scalar ->>> print scalar.foo.__doc__ -foo - Function signature: - foo(a,b) -Required arguments: - a : input float - b : in/output rank-0 array(float,'d') - ->>> scalar.foo(2,3) - A= 2. B= 3. - INCREMENT A AND B - NEW A= 3. B= 4. ->>> import Numeric ->>> a=Numeric.array(2) # these are integer rank-0 arrays ->>> b=Numeric.array(3) ->>> scalar.foo(a,b) - A= 2. B= 3. - INCREMENT A AND B - NEW A= 3. B= 4. ->>> print a,b # note that only b is changed in situ -2 4
\ No newline at end of file diff --git a/numpy/f2py/docs/usersguide/setup_example.py b/numpy/f2py/docs/usersguide/setup_example.py deleted file mode 100644 index e5f5e8441..000000000 --- a/numpy/f2py/docs/usersguide/setup_example.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -# File: setup_example.py - -from numpy_distutils.core import Extension - -ext1 = Extension(name = 'scalar', - sources = ['scalar.f']) -ext2 = Extension(name = 'fib2', - sources = ['fib2.pyf','fib1.f']) - -if __name__ == "__main__": - from numpy_distutils.core import setup - setup(name = 'f2py_example', - description = "F2PY Users Guide examples", - author = "Pearu Peterson", - author_email = "pearu@cens.ioc.ee", - ext_modules = [ext1,ext2] - ) -# End of setup_example.py diff --git a/numpy/f2py/docs/usersguide/spam.pyf b/numpy/f2py/docs/usersguide/spam.pyf deleted file mode 100644 index 21ea18b77..000000000 --- a/numpy/f2py/docs/usersguide/spam.pyf +++ /dev/null @@ -1,19 +0,0 @@ -! -*- f90 -*- -python module spam - usercode ''' - static char doc_spam_system[] = "Execute a shell command."; - static PyObject *spam_system(PyObject *self, PyObject *args) - { - char *command; - int sts; - - if (!PyArg_ParseTuple(args, "s", &command)) - return NULL; - sts = system(command); - return Py_BuildValue("i", sts); - } - ''' - pymethoddef ''' - {"system", spam_system, METH_VARARGS, doc_spam_system}, - ''' -end python module spam diff --git a/numpy/f2py/docs/usersguide/spam_session.dat b/numpy/f2py/docs/usersguide/spam_session.dat deleted file mode 100644 index 7f99d13f9..000000000 --- a/numpy/f2py/docs/usersguide/spam_session.dat +++ /dev/null @@ -1,5 +0,0 @@ ->>> import spam ->>> status = spam.system('whoami') -pearu ->> status = spam.system('blah') -sh: line 1: blah: command not found
\ No newline at end of file diff --git a/numpy/f2py/docs/usersguide/string.f b/numpy/f2py/docs/usersguide/string.f deleted file mode 100644 index 9246f02e7..000000000 --- a/numpy/f2py/docs/usersguide/string.f +++ /dev/null @@ -1,21 +0,0 @@ -C FILE: STRING.F - SUBROUTINE FOO(A,B,C,D) - CHARACTER*5 A, B - CHARACTER*(*) C,D -Cf2py intent(in) a,c -Cf2py intent(inout) b,d - PRINT*, "A=",A - PRINT*, "B=",B - PRINT*, "C=",C - PRINT*, "D=",D - PRINT*, "CHANGE A,B,C,D" - A(1:1) = 'A' - B(1:1) = 'B' - C(1:1) = 'C' - D(1:1) = 'D' - PRINT*, "A=",A - PRINT*, "B=",B - PRINT*, "C=",C - PRINT*, "D=",D - END -C END OF FILE STRING.F diff --git a/numpy/f2py/docs/usersguide/string_session.dat b/numpy/f2py/docs/usersguide/string_session.dat deleted file mode 100644 index 64ebcb3f4..000000000 --- a/numpy/f2py/docs/usersguide/string_session.dat +++ /dev/null @@ -1,27 +0,0 @@ ->>> import mystring ->>> print mystring.foo.__doc__ -foo - Function signature: - foo(a,b,c,d) -Required arguments: - a : input string(len=5) - b : in/output rank-0 array(string(len=5),'c') - c : input string(len=-1) - d : in/output rank-0 array(string(len=-1),'c') - ->>> import Numeric ->>> a=Numeric.array('123') ->>> b=Numeric.array('123') ->>> c=Numeric.array('123') ->>> d=Numeric.array('123') ->>> mystring.foo(a,b,c,d) - A=123 - B=123 - C=123 - D=123 - CHANGE A,B,C,D - A=A23 - B=B23 - C=C23 - D=D23 ->>> a.tostring(),b.tostring(),c.tostring(),d.tostring() -('123', 'B23', '123', 'D23')
\ No newline at end of file diff --git a/numpy/f2py/docs/usersguide/var.pyf b/numpy/f2py/docs/usersguide/var.pyf deleted file mode 100644 index 8275ff3af..000000000 --- a/numpy/f2py/docs/usersguide/var.pyf +++ /dev/null @@ -1,11 +0,0 @@ -! -*- f90 -*- -python module var - usercode ''' - int BAR = 5; - ''' - interface - usercode ''' - PyDict_SetItemString(d,"BAR",PyInt_FromLong(BAR)); - ''' - end interface -end python module diff --git a/numpy/f2py/docs/usersguide/var_session.dat b/numpy/f2py/docs/usersguide/var_session.dat deleted file mode 100644 index fb0f798bf..000000000 --- a/numpy/f2py/docs/usersguide/var_session.dat +++ /dev/null @@ -1,3 +0,0 @@ ->>> import var ->>> var.BAR -5
\ No newline at end of file diff --git a/numpy/f2py/f2py.1 b/numpy/f2py/f2py.1 deleted file mode 100644 index b8769a0cc..000000000 --- a/numpy/f2py/f2py.1 +++ /dev/null @@ -1,209 +0,0 @@ -.TH "F2PY" 1 -.SH NAME -f2py \- Fortran to Python interface generator -.SH SYNOPSIS -(1) To construct extension module sources: - -.B f2py -[<options>] <fortran files> [[[only:]||[skip:]] <fortran functions> ] [: <fortran files> ...] - -(2) To compile fortran files and build extension modules: - -.B f2py --c [<options>, <config_fc options>, <extra options>] <fortran files> - -(3) To generate signature files: - -.B f2py --h <filename.pyf> ...< same options as in (1) > -.SH DESCRIPTION -This program generates a Python C/API file (<modulename>module.c) -that contains wrappers for given Fortran or C functions so that they -can be called from Python. -With the -c option the corresponding -extension modules are built. -.SH OPTIONS -.TP -.B \-h <filename> -Write signatures of the fortran routines to file <filename> and -exit. You can then edit <filename> and use it instead of <fortran -files>. If <filename>==stdout then the signatures are printed to -stdout. -.TP -.B <fortran functions> -Names of fortran routines for which Python C/API functions will be -generated. Default is all that are found in <fortran files>. -.TP -.B skip: -Ignore fortran functions that follow until `:'. -.TP -.B only: -Use only fortran functions that follow until `:'. -.TP -.B : -Get back to <fortran files> mode. -.TP -.B \-m <modulename> -Name of the module; f2py generates a Python/C API file -<modulename>module.c or extension module <modulename>. Default is -\'untitled\'. -.TP -.B \-\-[no\-]lower -Do [not] lower the cases in <fortran files>. By default, --lower is -assumed with -h key, and --no-lower without -h key. -.TP -.B \-\-build\-dir <dirname> -All f2py generated files are created in <dirname>. Default is tempfile.mktemp(). -.TP -.B \-\-overwrite\-signature -Overwrite existing signature file. -.TP -.B \-\-[no\-]latex\-doc -Create (or not) <modulename>module.tex. Default is --no-latex-doc. -.TP -.B \-\-short\-latex -Create 'incomplete' LaTeX document (without commands \\documentclass, -\\tableofcontents, and \\begin{document}, \\end{document}). -.TP -.B \-\-[no\-]rest\-doc -Create (or not) <modulename>module.rst. Default is --no-rest-doc. -.TP -.B \-\-debug\-capi -Create C/API code that reports the state of the wrappers during -runtime. Useful for debugging. -.TP -.B \-include\'<includefile>\' -Add CPP #include statement to the C/API code. <includefile> should be -in the format of either `"filename.ext"' or `<filename.ext>'. As a -result <includefile> will be included just before wrapper functions -part in the C/API code. The option is depreciated, use `usercode` -statement in signature files instead. -.TP -.B \-\-[no\-]wrap\-functions -Create Fortran subroutine wrappers to Fortran 77 -functions. --wrap-functions is default because it ensures maximum -portability/compiler independence. -.TP -.B \-\-help\-link [..] -List system resources found by system_info.py. [..] may contain -a list of resources names. See also --link-<resource> switch below. -.TP -.B \-\-quiet -Run quietly. -.TP -.B \-\-verbose -Run with extra verbosity. -.TP -.B \-v -Print f2py version ID and exit. -.TP -.B \-\-include_paths path1:path2:... -Search include files (that f2py will scan) from the given directories. -.SH "CONFIG_FC OPTIONS" -The following options are effective only when -c switch is used. -.TP -.B \-\-help-compiler -List available Fortran compilers [DEPRECIATED]. -.TP -.B \-\-fcompiler=<name> -Specify Fortran compiler type by vendor. -.TP -.B \-\-compiler=<name> -Specify C compiler type (as defined by distutils) -.TP -.B \-\-fcompiler-exec=<path> -Specify the path to F77 compiler [DEPRECIATED]. -.TP -.B \-\-f90compiler\-exec=<path> -Specify the path to F90 compiler [DEPRECIATED]. -.TP -.B \-\-help\-fcompiler -List available Fortran compilers and exit. -.TP -.B \-\-f77exec=<path> -Specify the path to F77 compiler. -.TP -.B \-\-f90exec=<path> -Specify the path to F90 compiler. -.TP -.B \-\-f77flags="..." -Specify F77 compiler flags. -.TP -.B \-\-f90flags="..." -Specify F90 compiler flags. -.TP -.B \-\-opt="..." -Specify optimization flags. -.TP -.B \-\-arch="..." -Specify architecture specific optimization flags. -.TP -.B \-\-noopt -Compile without optimization. -.TP -.B \-\-noarch -Compile without arch-dependent optimization. -.TP -.B \-\-debug -Compile with debugging information. -.SH "EXTRA OPTIONS" -The following options are effective only when -c switch is used. -.TP -.B \-\-link-<resource> -Link extension module with <resource> as defined by -numpy_distutils/system_info.py. E.g. to link with optimized LAPACK -libraries (vecLib on MacOSX, ATLAS elsewhere), use ---link-lapack_opt. See also --help-link switch. - -.TP -.B -L/path/to/lib/ -l<libname> -.TP -.B -D<define> -U<name> -I/path/to/include/ -.TP -.B <filename>.o <filename>.so <filename>.a - -.TP -.B -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN -DUNDERSCORE_G77 -Macros that might be required with non-gcc Fortran compilers. - -.TP -.B -DF2PY_REPORT_ATEXIT -To print out a performance report of F2PY interface when python -exits. Available for Linux. - -.TP -.B -DF2PY_REPORT_ON_ARRAY_COPY=<int> -To send a message to stderr whenever F2PY interface makes a copy of an -array. Integer <int> sets the threshold for array sizes when a message -should be shown. - -.SH REQUIREMENTS -Python 1.5.2 or higher (2.x is supported). - -Numerical Python 13 or higher (20.x,21.x,22.x,23.x are supported). - -Optional Numarray 0.9 or higher partially supported. - -numpy_distutils from Scipy (can be downloaded from F2PY homepage) -.SH "SEE ALSO" -python(1) -.SH BUGS -For instructions on reporting bugs, see - - http://cens.ioc.ee/projects/f2py2e/FAQ.html -.SH AUTHOR -Pearu Peterson <pearu@cens.ioc.ee> -.SH "INTERNET RESOURCES" -Main website: http://cens.ioc.ee/projects/f2py2e/ - -User's Guide: http://cens.ioc.ee/projects/f2py2e/usersguide/ - -Mailing list: http://cens.ioc.ee/mailman/listinfo/f2py-users/ - -Scipy website: http://www.numpy.org -.SH COPYRIGHT -Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Pearu Peterson -.SH LICENSE -NumPy License -.SH VERSION -2.45.241 diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py deleted file mode 100755 index 85102e281..000000000 --- a/numpy/f2py/f2py2e.py +++ /dev/null @@ -1,554 +0,0 @@ -#!/usr/bin/env python -""" - -f2py2e - Fortran to Python C/API generator. 2nd Edition. - See __usage__ below. - -Copyright 1999--2005 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@cens.ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/05/06 08:31:19 $ -Pearu Peterson -""" -__version__ = "$Revision: 1.90 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import sys,os,string,pprint,shutil,types,re -errmess=sys.stderr.write -#outmess=sys.stdout.write -show=pprint.pprint - -import crackfortran -import rules -import cb_rules -import common_rules -import auxfuncs -import cfuncs -import capi_maps -import func2subr -import f90mod_rules - -outmess = auxfuncs.outmess - -try: - from numpy import __version__ as numpy_version -except ImportError: - numpy_version = 'N/A' - -__usage__ = """\ -Usage: - -1) To construct extension module sources: - - f2py [<options>] <fortran files> [[[only:]||[skip:]] \\ - <fortran functions> ] \\ - [: <fortran files> ...] - -2) To compile fortran files and build extension modules: - - f2py -c [<options>, <build_flib options>, <extra options>] <fortran files> - -3) To generate signature files: - - f2py -h <filename.pyf> ...< same options as in (1) > - -Description: This program generates a Python C/API file (<modulename>module.c) - that contains wrappers for given fortran functions so that they - can be called from Python. With the -c option the corresponding - extension modules are built. - -Options: - - -h <filename> Write signatures of the fortran routines to file <filename> - and exit. You can then edit <filename> and use it instead - of <fortran files>. If <filename>==stdout then the - signatures are printed to stdout. - <fortran functions> Names of fortran routines for which Python C/API - functions will be generated. Default is all that are found - in <fortran files>. - <fortran files> Paths to fortran/signature files that will be scanned for - <fortran functions> in order to determine their signatures. - skip: Ignore fortran functions that follow until `:'. - only: Use only fortran functions that follow until `:'. - : Get back to <fortran files> mode. - - -m <modulename> Name of the module; f2py generates a Python/C API - file <modulename>module.c or extension module <modulename>. - Default is 'untitled'. - - --[no-]lower Do [not] lower the cases in <fortran files>. By default, - --lower is assumed with -h key, and --no-lower without -h key. - - --build-dir <dirname> All f2py generated files are created in <dirname>. - Default is tempfile.mktemp(). - - --overwrite-signature Overwrite existing signature file. - - --[no-]latex-doc Create (or not) <modulename>module.tex. - Default is --no-latex-doc. - --short-latex Create 'incomplete' LaTeX document (without commands - \\documentclass, \\tableofcontents, and \\begin{document}, - \\end{document}). - - --[no-]rest-doc Create (or not) <modulename>module.rst. - Default is --no-rest-doc. - - --debug-capi Create C/API code that reports the state of the wrappers - during runtime. Useful for debugging. - - --[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77 - functions. --wrap-functions is default because it ensures - maximum portability/compiler independence. - - --include_paths <path1>:<path2>:... Search include files from the given - directories. - - --help-link [..] List system resources found by system_info.py. See also - --link-<resource> switch below. [..] is optional list - of resources names. E.g. try 'f2py --help-link lapack_opt'. - - --quiet Run quietly. - --verbose Run with extra verbosity. - -v Print f2py version ID and exit. - - -numpy.distutils options (only effective with -c): - - --fcompiler= Specify Fortran compiler type by vendor - --compiler= Specify C compiler type (as defined by distutils) - - --help-fcompiler List available Fortran compilers and exit - --f77exec= Specify the path to F77 compiler - --f90exec= Specify the path to F90 compiler - --f77flags= Specify F77 compiler flags - --f90flags= Specify F90 compiler flags - --opt= Specify optimization flags - --arch= Specify architecture specific optimization flags - --noopt Compile without optimization - --noarch Compile without arch-dependent optimization - --debug Compile with debugging information - -Extra options (only effective with -c): - - --link-<resource> Link extension module with <resource> as defined - by numpy.distutils/system_info.py. E.g. to link - with optimized LAPACK libraries (vecLib on MacOSX, - ATLAS elsewhere), use --link-lapack_opt. - See also --help-link switch. - - -L/path/to/lib/ -l<libname> - -D<define> -U<name> - -I/path/to/include/ - <filename>.o <filename>.so <filename>.a - - Using the following macros may be required with non-gcc Fortran - compilers: - -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN - -DUNDERSCORE_G77 - - When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY - interface is printed out at exit (platforms: Linux). - - When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is - sent to stderr whenever F2PY interface makes a copy of an - array. Integer <int> sets the threshold for array sizes when - a message should be shown. - -Version: %s -numpy Version: %s -Requires: Python 2.3 or higher. -License: NumPy license (see LICENSE.txt in the NumPy source code) -Copyright 1999 - 2005 Pearu Peterson all rights reserved. -http://cens.ioc.ee/projects/f2py2e/"""%(f2py_version, numpy_version) - - -def scaninputline(inputline): - files,funcs,skipfuncs,onlyfuncs,debug=[],[],[],[],[] - f,f2,f3,f4,f5,f6,f7=1,0,0,0,0,0,0 - verbose = 1 - dolc=-1 - dolatexdoc = 0 - dorestdoc = 0 - wrapfuncs = 1 - buildpath = '.' - include_paths = [] - signsfile,modulename=None,None - options = {'buildpath':buildpath} - for l in inputline: - if l=='': pass - elif l=='only:': f=0 - elif l=='skip:': f=-1 - elif l==':': f=1;f4=0 - elif l[:8]=='--debug-': debug.append(l[8:]) - elif l=='--lower': dolc=1 - elif l=='--build-dir': f6=1 - elif l=='--no-lower': dolc=0 - elif l=='--quiet': verbose = 0 - elif l=='--verbose': verbose += 1 - elif l=='--latex-doc': dolatexdoc=1 - elif l=='--no-latex-doc': dolatexdoc=0 - elif l=='--rest-doc': dorestdoc=1 - elif l=='--no-rest-doc': dorestdoc=0 - elif l=='--wrap-functions': wrapfuncs=1 - elif l=='--no-wrap-functions': wrapfuncs=0 - elif l=='--short-latex': options['shortlatex']=1 - elif l=='--overwrite-signature': options['h-overwrite']=1 - elif l=='-h': f2=1 - elif l=='-m': f3=1 - elif l[:2]=='-v': - print f2py_version - sys.exit() - elif l=='--show-compilers': - f5=1 - elif l[:8]=='-include': - cfuncs.outneeds['userincludes'].append(l[9:-1]) - cfuncs.userincludes[l[9:-1]]='#include '+l[8:] - elif l[:15]=='--include_paths': - f7=1 - elif l[0]=='-': - errmess('Unknown option %s\n'%`l`) - sys.exit() - elif f2: f2=0;signsfile=l - elif f3: f3=0;modulename=l - elif f6: f6=0;buildpath=l - elif f7: f7=0;include_paths.extend(l.split(os.pathsep)) - elif f==1: - try: - open(l).close() - files.append(l) - except IOError,detail: - errmess('IOError: %s. Skipping file "%s".\n'%(str(detail),l)) - elif f==-1: skipfuncs.append(l) - elif f==0: onlyfuncs.append(l) - if not f5 and not files and not modulename: - print __usage__ - sys.exit() - if not os.path.isdir(buildpath): - if not verbose: - outmess('Creating build directory %s'%(buildpath)) - os.mkdir(buildpath) - if signsfile: - signsfile = os.path.join(buildpath,signsfile) - if signsfile and os.path.isfile(signsfile) and not options.has_key('h-overwrite'): - errmess('Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n'%(signsfile)) - sys.exit() - - options['debug']=debug - options['verbose']=verbose - if dolc==-1 and not signsfile: options['do-lower']=0 - else: options['do-lower']=dolc - if modulename: options['module']=modulename - if signsfile: options['signsfile']=signsfile - if onlyfuncs: options['onlyfuncs']=onlyfuncs - if skipfuncs: options['skipfuncs']=skipfuncs - options['dolatexdoc'] = dolatexdoc - options['dorestdoc'] = dorestdoc - options['wrapfuncs'] = wrapfuncs - options['buildpath']=buildpath - options['include_paths']=include_paths - return files,options - -def callcrackfortran(files,options): - rules.options=options - funcs=[] - crackfortran.debug=options['debug'] - crackfortran.verbose=options['verbose'] - if options.has_key('module'): - crackfortran.f77modulename=options['module'] - if options.has_key('skipfuncs'): - crackfortran.skipfuncs=options['skipfuncs'] - if options.has_key('onlyfuncs'): - crackfortran.onlyfuncs=options['onlyfuncs'] - crackfortran.include_paths[:]=options['include_paths'] - crackfortran.dolowercase=options['do-lower'] - postlist=crackfortran.crackfortran(files) - if options.has_key('signsfile'): - outmess('Saving signatures to file "%s"\n'%(options['signsfile'])) - pyf=crackfortran.crack2fortran(postlist) - if options['signsfile'][-6:]=='stdout': - sys.stdout.write(pyf) - else: - f=open(options['signsfile'],'w') - f.write(pyf) - f.close() - return postlist - -def buildmodules(list): - cfuncs.buildcfuncs() - outmess('Building modules...\n') - modules,mnames,isusedby=[],[],{} - for i in range(len(list)): - if string.find(list[i]['name'],'__user__')>=0: - cb_rules.buildcallbacks(list[i]) - else: - if list[i].has_key('use'): - for u in list[i]['use'].keys(): - if not isusedby.has_key(u): isusedby[u]=[] - isusedby[u].append(list[i]['name']) - modules.append(list[i]) - mnames.append(list[i]['name']) - ret = {} - for i in range(len(mnames)): - if isusedby.has_key(mnames[i]): - outmess('\tSkipping module "%s" which is used by %s.\n'%(mnames[i],string.join(map(lambda s:'"%s"'%s,isusedby[mnames[i]]),','))) - else: - um=[] - if modules[i].has_key('use'): - for u in modules[i]['use'].keys(): - if isusedby.has_key(u) and u in mnames: - um.append(modules[mnames.index(u)]) - else: - outmess('\tModule "%s" uses nonexisting "%s" which will be ignored.\n'%(mnames[i],u)) - ret[mnames[i]] = {} - dict_append(ret[mnames[i]],rules.buildmodule(modules[i],um)) - return ret - -def dict_append(d_out,d_in): - for (k,v) in d_in.items(): - if not d_out.has_key(k): - d_out[k] = [] - if type(v) is types.ListType: - d_out[k] = d_out[k] + v - else: - d_out[k].append(v) - -def run_main(comline_list): - """Run f2py as if string.join(comline_list,' ') is used as a command line. - In case of using -h flag, return None. - """ - reload(crackfortran) - f2pydir=os.path.dirname(os.path.abspath(cfuncs.__file__)) - fobjhsrc = os.path.join(f2pydir,'src','fortranobject.h') - fobjcsrc = os.path.join(f2pydir,'src','fortranobject.c') - files,options=scaninputline(comline_list) - auxfuncs.options=options - postlist=callcrackfortran(files,options) - isusedby={} - for i in range(len(postlist)): - if postlist[i].has_key('use'): - for u in postlist[i]['use'].keys(): - if not isusedby.has_key(u): isusedby[u]=[] - isusedby[u].append(postlist[i]['name']) - for i in range(len(postlist)): - if postlist[i]['block']=='python module' and string.find(postlist[i]['name'],'__user__')<0: - if isusedby.has_key(postlist[i]['name']): - #if not quiet: - outmess('Skipping Makefile build for module "%s" which is used by %s\n'%(postlist[i]['name'],string.join(map(lambda s:'"%s"'%s,isusedby[postlist[i]['name']]),','))) - if options.has_key('signsfile'): - if options['verbose']>1: - outmess('Stopping. Edit the signature file and then run f2py on the signature file: ') - outmess('%s %s\n'%(os.path.basename(sys.argv[0]),options['signsfile'])) - return - for i in range(len(postlist)): - if postlist[i]['block']!='python module': - if not options.has_key('python module'): - errmess('Tip: If your original code is Fortran 77 then you must use -m option.\n') - raise TypeError,'All blocks must be module blocks but got %s'%(`postlist[i]['block']`) - auxfuncs.debugoptions=options['debug'] - f90mod_rules.options=options - auxfuncs.wrapfuncs=options['wrapfuncs'] - - ret=buildmodules(postlist) - - for mn in ret.keys(): - dict_append(ret[mn],{'csrc':fobjcsrc,'h':fobjhsrc}) - return ret - -def filter_files(prefix,suffix,files,remove_prefix=None): - """ - Filter files by prefix and suffix. - """ - filtered,rest = [],[] - match = re.compile(prefix+r'.*'+suffix+r'\Z').match - if remove_prefix: - ind = len(prefix) - else: - ind = 0 - for file in map(string.strip,files): - if match(file): filtered.append(file[ind:]) - else: rest.append(file) - return filtered,rest - -def get_prefix(module): - p = os.path.dirname(os.path.dirname(module.__file__)) - return p - -def run_compile(): - """ - Do it all in one call! - """ - import tempfile,os,shutil - - i = sys.argv.index('-c') - del sys.argv[i] - - remove_build_dir = 0 - try: i = sys.argv.index('--build-dir') - except ValueError: i=None - if i is not None: - build_dir = sys.argv[i+1] - del sys.argv[i+1] - del sys.argv[i] - else: - remove_build_dir = 1 - build_dir = os.path.join(tempfile.mktemp()) - - sysinfo_flags = filter(re.compile(r'[-][-]link[-]').match,sys.argv[1:]) - sys.argv = filter(lambda a,flags=sysinfo_flags:a not in flags,sys.argv) - if sysinfo_flags: - sysinfo_flags = [f[7:] for f in sysinfo_flags] - - f2py_flags = filter(re.compile(r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include').match,sys.argv[1:]) - sys.argv = filter(lambda a,flags=f2py_flags:a not in flags,sys.argv) - f2py_flags2 = [] - fl = 0 - for a in sys.argv[1:]: - if a in ['only:','skip:']: - fl = 1 - elif a==':': - fl = 0 - if fl or a==':': - f2py_flags2.append(a) - if f2py_flags2 and f2py_flags2[-1]!=':': - f2py_flags2.append(':') - f2py_flags.extend(f2py_flags2) - - sys.argv = filter(lambda a,flags=f2py_flags2:a not in flags,sys.argv) - - flib_flags = filter(re.compile(r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)').match,sys.argv[1:]) - sys.argv = filter(lambda a,flags=flib_flags:a not in flags,sys.argv) - fc_flags = filter(re.compile(r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))').match,sys.argv[1:]) - sys.argv = filter(lambda a,flags=fc_flags:a not in flags,sys.argv) - - if 1: - del_list = [] - for s in flib_flags: - v = '--fcompiler=' - if s[:len(v)]==v: - from numpy.distutils import fcompiler - allowed_keys = fcompiler.fcompiler_class.keys() - nv = ov = s[len(v):].lower() - if ov not in allowed_keys: - vmap = {} # XXX - try: - nv = vmap[ov] - except KeyError: - if ov not in vmap.values(): - print 'Unknown vendor: "%s"' % (s[len(v):]) - nv = ov - i = flib_flags.index(s) - flib_flags[i] = '--fcompiler=' + nv - continue - for s in del_list: - i = flib_flags.index(s) - del flib_flags[i] - assert len(flib_flags)<=2,`flib_flags` - setup_flags = filter(re.compile(r'[-][-](verbose)').match,sys.argv[1:]) - sys.argv = filter(lambda a,flags=setup_flags:a not in flags,sys.argv) - if '--quiet' in f2py_flags: - setup_flags.append('--quiet') - - modulename = 'untitled' - sources = sys.argv[1:] - if '-m' in sys.argv: - i = sys.argv.index('-m') - modulename = sys.argv[i+1] - del sys.argv[i+1],sys.argv[i] - sources = sys.argv[1:] - else: - from numpy.distutils.command.build_src import get_f2py_modulename - pyf_files,sources = filter_files('','[.]pyf([.]src|)',sources) - sources = pyf_files + sources - for f in pyf_files: - modulename = get_f2py_modulename(f) - if modulename: - break - - extra_objects, sources = filter_files('','[.](o|a|so)',sources) - include_dirs, sources = filter_files('-I','',sources,remove_prefix=1) - library_dirs, sources = filter_files('-L','',sources,remove_prefix=1) - libraries, sources = filter_files('-l','',sources,remove_prefix=1) - undef_macros, sources = filter_files('-U','',sources,remove_prefix=1) - define_macros, sources = filter_files('-D','',sources,remove_prefix=1) - using_numarray = 0 - using_numeric = 0 - for i in range(len(define_macros)): - name_value = string.split(define_macros[i],'=',1) - if len(name_value)==1: - name_value.append(None) - if len(name_value)==2: - define_macros[i] = tuple(name_value) - else: - print 'Invalid use of -D:',name_value - - from numpy.distutils.system_info import get_info - - num_include_dir = None - num_info = {} - #import numpy - #n = 'numpy' - #p = get_prefix(numpy) - #from numpy.distutils.misc_util import get_numpy_include_dirs - #num_info = {'include_dirs': get_numpy_include_dirs()} - - if num_info: - include_dirs.extend(num_info.get('include_dirs',[])) - - from numpy.distutils.core import setup,Extension - ext_args = {'name':modulename,'sources':sources, - 'include_dirs': include_dirs, - 'library_dirs': library_dirs, - 'libraries': libraries, - 'define_macros': define_macros, - 'undef_macros': undef_macros, - 'extra_objects': extra_objects, - 'f2py_options': f2py_flags, - } - - if sysinfo_flags: - from numpy.distutils.misc_util import dict_append - for n in sysinfo_flags: - i = get_info(n) - if not i: - outmess('No %s resources found in system'\ - ' (try `f2py --help-link`)\n' % (`n`)) - dict_append(ext_args,**i) - - ext = Extension(**ext_args) - sys.argv = [sys.argv[0]] + setup_flags - sys.argv.extend(['build', - '--build-temp',build_dir, - '--build-base',build_dir, - '--build-platlib','.']) - if fc_flags: - sys.argv.extend(['config_fc']+fc_flags) - if flib_flags: - sys.argv.extend(['build_ext']+flib_flags) - - setup(ext_modules = [ext]) - - if remove_build_dir and os.path.exists(build_dir): - outmess('Removing build directory %s\n'%(build_dir)) - shutil.rmtree(build_dir) - -def main(): - if '--help-link' in sys.argv[1:]: - sys.argv.remove('--help-link') - from numpy.distutils.system_info import show_all - show_all() - return - if '-c' in sys.argv[1:]: - run_compile() - else: - run_main(sys.argv[1:]) - -#if __name__ == "__main__": -# main() - - -# EOF diff --git a/numpy/f2py/f2py_testing.py b/numpy/f2py/f2py_testing.py deleted file mode 100644 index f94712105..000000000 --- a/numpy/f2py/f2py_testing.py +++ /dev/null @@ -1,74 +0,0 @@ - -import os,sys,re,time - -def cmdline(): - m=re.compile(r'\A\d+\Z') - args = [] - repeat = 1 - for a in sys.argv[1:]: - if m.match(a): - repeat = eval(a) - else: - args.append(a) - f2py_opts = ' '.join(args) - return repeat,f2py_opts - -if sys.platform[:5]=='linux': - def jiffies(_proc_pid_stat = '/proc/%s/stat'%(os.getpid()), - _load_time=time.time()): - """ Return number of jiffies (1/100ths of a second) that this - process has been scheduled in user mode. See man 5 proc. """ - try: - f=open(_proc_pid_stat,'r') - l = f.readline().split(' ') - f.close() - return int(l[13]) - except: - return int(100*(time.time()-_load_time)) - - def memusage(_proc_pid_stat = '/proc/%s/stat'%(os.getpid())): - """ Return virtual memory size in bytes of the running python. - """ - try: - f=open(_proc_pid_stat,'r') - l = f.readline().split(' ') - f.close() - return int(l[22]) - except: - return -else: - def jiffies(_load_time=time.time()): - """ Return number of jiffies (1/100ths of a second) that this - process has been scheduled in user mode. [Emulation with time.time]. """ - return int(100*(time.time()-_load_time)) - - def memusage(): - pass - -def run(runtest,test_functions,repeat=1): - l = [(t,repr(t.__doc__.split('\n')[1].strip())) for t in test_functions] - #l = [(t,'') for t in test_functions] - start_memusage = memusage() - diff_memusage = None - start_jiffies = jiffies() - i = 0 - while i<repeat: - i += 1 - for t,fname in l: - runtest(t) - if start_memusage is None: continue - if diff_memusage is None: - diff_memusage = memusage() - start_memusage - else: - diff_memusage2 = memusage() - start_memusage - if diff_memusage2!=diff_memusage: - print 'memory usage change at step %i:' % i,\ - diff_memusage2-diff_memusage,\ - fname - diff_memusage = diff_memusage2 - current_memusage = memusage() - print 'run',repeat*len(test_functions),'tests',\ - 'in %.2f seconds' % ((jiffies()-start_jiffies)/100.0) - if start_memusage: - print 'initial virtual memory size:',start_memusage,'bytes' - print 'current virtual memory size:',current_memusage,'bytes' diff --git a/numpy/f2py/f90mod_rules.py b/numpy/f2py/f90mod_rules.py deleted file mode 100644 index aaedde1b2..000000000 --- a/numpy/f2py/f90mod_rules.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/env python -""" - -Build F90 module support for f2py2e. - -Copyright 2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/02/03 19:30:23 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.27 $"[10:-1] - -f2py_version='See `f2py -v`' - -import pprint -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -import capi_maps -import cfuncs -import rules -import func2subr -from crackfortran import undo_rmbadname, undo_rmbadname1 - -options={} - -def findf90modules(m): - if ismodule(m): return [m] - if not hasbody(m): return [] - ret = [] - for b in m['body']: - if ismodule(b): ret.append(b) - else: ret=ret+findf90modules(b) - return ret - -fgetdims1 = """\ - external f2pysetdata - logical ns - integer s(*),r,i,j - ns = .FALSE. - if (allocated(d)) then - do i=1,r - if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then - ns = .TRUE. - end if - end do - if (ns) then - deallocate(d) - end if - end if - if ((.not.allocated(d)).and.(s(1).ge.1)) then""" - -fgetdims2="""\ - end if - if (allocated(d)) then - do i=1,r - s(i) = size(d,i) - end do - end if - flag = 1 - call f2pysetdata(d,allocated(d))""" - -fgetdims2_sa="""\ - end if - if (allocated(d)) then - do i=1,r - s(i) = size(d,i) - end do - !s(r) must be equal to len(d(1)) - end if - flag = 2 - call f2pysetdata(d,allocated(d))""" - - -def buildhooks(pymod): - global fgetdims1,fgetdims2 - ret = {'f90modhooks':[],'initf90modhooks':[],'body':[], - 'need':['F_FUNC','arrayobject.h'], - 'separatorsfor':{'includes0':'\n','includes':'\n'}, - 'docs':['"Fortran 90/95 modules:\\n"'], - 'latexdoc':[]} - fhooks=[''] - def fadd(line,s=fhooks): s[0] = '%s\n %s'%(s[0],line) - doc = [''] - def dadd(line,s=doc): s[0] = '%s\n%s'%(s[0],line) - for m in findf90modules(pymod): - sargs,fargs,efargs,modobjs,notvars,onlyvars=[],[],[],[],[m['name']],[] - sargsp = [] - ifargs = [] - mfargs = [] - if hasbody(m): - for b in m['body']: notvars.append(b['name']) - for n in m['vars'].keys(): - var = m['vars'][n] - if (n not in notvars) and (not l_or(isintent_hide,isprivate)(var)): - onlyvars.append(n) - mfargs.append(n) - outmess('\t\tConstructing F90 module support for "%s"...\n'%(m['name'])) - if onlyvars: - outmess('\t\t Variables: %s\n'%(string.join(onlyvars))) - chooks=[''] - def cadd(line,s=chooks): s[0] = '%s\n%s'%(s[0],line) - ihooks=[''] - def iadd(line,s=ihooks): s[0] = '%s\n%s'%(s[0],line) - - vrd=capi_maps.modsign2map(m) - cadd('static FortranDataDef f2py_%s_def[] = {'%(m['name'])) - dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n'%(m['name'])) - if hasnote(m): - note = m['note'] - if type(note) is type([]): note=string.join(note,'\n') - dadd(note) - if onlyvars: - dadd('\\begin{description}') - for n in onlyvars: - var = m['vars'][n] - modobjs.append(n) - ct = capi_maps.getctype(var) - at = capi_maps.c2capi_map[ct] - dm = capi_maps.getarrdims(n,var) - dms = string.strip(string.replace(dm['dims'],'*','-1')) - dms = string.strip(string.replace(dms,':','-1')) - if not dms: dms='-1' - use_fgetdims2 = fgetdims2 - if isstringarray(var): - if var.has_key('charselector') and var['charselector'].has_key('len'): - cadd('\t{"%s",%s,{{%s,%s}},%s},'\ - %(undo_rmbadname1(n),dm['rank'],dms,var['charselector']['len'],at)) - use_fgetdims2 = fgetdims2_sa - else: - cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n),dm['rank'],dms,at)) - else: - cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n),dm['rank'],dms,at)) - dadd('\\item[]{{}\\verb@%s@{}}'%(capi_maps.getarrdocsign(n,var))) - if hasnote(var): - note = var['note'] - if type(note) is type([]): note=string.join(note,'\n') - dadd('--- %s'%(note)) - if isallocatable(var): - fargs.append('f2py_%s_getdims_%s'%(m['name'],n)) - efargs.append(fargs[-1]) - sargs.append('void (*%s)(int*,int*,void(*)(char*,int*),int*)'%(n)) - sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)') - iadd('\tf2py_%s_def[i_f2py++].func = %s;'%(m['name'],n)) - fadd('subroutine %s(r,s,f2pysetdata,flag)'%(fargs[-1])) - fadd('use %s, only: d => %s\n'%(m['name'],undo_rmbadname1(n))) - fadd('integer flag\n') - fhooks[0]=fhooks[0]+fgetdims1 - dms = eval('range(1,%s+1)'%(dm['rank'])) - fadd(' allocate(d(%s))\n'%(string.join(map(lambda i:'s(%s)'%i,dms),','))) - fhooks[0]=fhooks[0]+use_fgetdims2 - fadd('end subroutine %s'%(fargs[-1])) - else: - fargs.append(n) - sargs.append('char *%s'%(n)) - sargsp.append('char*') - iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'],n)) - if onlyvars: - dadd('\\end{description}') - if hasbody(m): - for b in m['body']: - if not isroutine(b): - print 'Skipping',b['block'],b['name'] - continue - modobjs.append('%s()'%(b['name'])) - b['modulename'] = m['name'] - api,wrap=rules.buildapi(b) - if isfunction(b): - fhooks[0]=fhooks[0]+wrap - fargs.append('f2pywrap_%s_%s'%(m['name'],b['name'])) - #efargs.append(fargs[-1]) - ifargs.append(func2subr.createfuncwrapper(b,signature=1)) - else: - fargs.append(b['name']) - mfargs.append(fargs[-1]) - #if options.has_key('--external-modroutines') and options['--external-modroutines']: - # outmess('\t\t\tapplying --external-modroutines for %s\n'%(b['name'])) - # efargs.append(fargs[-1]) - api['externroutines']=[] - ar=applyrules(api,vrd) - ar['docs']=[] - ar['docshort']=[] - ret=dictappend(ret,ar) - cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},'%(b['name'],m['name'],b['name'],m['name'],b['name'])) - sargs.append('char *%s'%(b['name'])) - sargsp.append('char *') - iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'],b['name'])) - cadd('\t{NULL}\n};\n') - iadd('}') - ihooks[0]='static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s'%(m['name'],string.join(sargs,','),ihooks[0]) - if '_' in m['name']: - F_FUNC='F_FUNC_US' - else: - F_FUNC='F_FUNC' - iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'\ - %(F_FUNC,m['name'],string.upper(m['name']),string.join(sargsp,','))) - iadd('static void f2py_init_%s(void) {'%(m['name'])) - iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'\ - %(F_FUNC,m['name'],string.upper(m['name']),m['name'])) - iadd('}\n') - ret['f90modhooks']=ret['f90modhooks']+chooks+ihooks - ret['initf90modhooks']=['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));'%(m['name'],m['name'],m['name'])]+ret['initf90modhooks'] - fadd('') - fadd('subroutine f2pyinit%s(f2pysetupfunc)'%(m['name'])) - #fadd('use %s'%(m['name'])) - if mfargs: - for a in undo_rmbadname(mfargs): - fadd('use %s, only : %s'%(m['name'],a)) - if ifargs: - fadd(string.join(['interface']+ifargs)) - fadd('end interface') - fadd('external f2pysetupfunc') - if efargs: - for a in undo_rmbadname(efargs): - fadd('external %s'%(a)) - fadd('call f2pysetupfunc(%s)'%(string.join(undo_rmbadname(fargs),','))) - fadd('end subroutine f2pyinit%s\n'%(m['name'])) - - dadd(string.replace(string.join(ret['latexdoc'],'\n'),r'\subsection{',r'\subsubsection{')) - - ret['latexdoc']=[] - ret['docs'].append('"\t%s --- %s"'%(m['name'], - string.join(undo_rmbadname(modobjs),','))) - - ret['routine_defs']='' - ret['doc']=[] - ret['docshort']=[] - ret['latexdoc']=doc[0] - if len(ret['docs'])<=1: ret['docs']='' - return ret,fhooks[0] diff --git a/numpy/f2py/func2subr.py b/numpy/f2py/func2subr.py deleted file mode 100644 index 4cec37032..000000000 --- a/numpy/f2py/func2subr.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python -""" - -Rules for building C/API module with f2py2e. - -Copyright 1999,2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2004/11/26 11:13:06 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.16 $"[10:-1] - -f2py_version='See `f2py -v`' - -import pprint,copy -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -def var2fixfortran(vars,a,fa=None,f90mode=None): - if fa is None: - fa = a - if not vars.has_key(a): - show(vars) - outmess('var2fixfortran: No definition for argument "%s".\n'%a) - return '' - if not vars[a].has_key('typespec'): - show(vars[a]) - outmess('var2fixfortran: No typespec for argument "%s".\n'%a) - return '' - vardef=vars[a]['typespec'] - if vardef=='type' and vars[a].has_key('typename'): - vardef='%s(%s)'%(vardef,vars[a]['typename']) - selector={} - lk = '' - if vars[a].has_key('kindselector'): - selector=vars[a]['kindselector'] - lk = 'kind' - elif vars[a].has_key('charselector'): - selector=vars[a]['charselector'] - lk = 'len' - if selector.has_key('*'): - if f90mode: - if selector['*'] in ['*',':','(*)']: - vardef='%s(len=*)'%(vardef) - else: - vardef='%s(%s=%s)'%(vardef,lk,selector['*']) - else: - if selector['*'] in ['*',':']: - vardef='%s*(%s)'%(vardef,selector['*']) - else: - vardef='%s*%s'%(vardef,selector['*']) - else: - if selector.has_key('len'): - vardef='%s(len=%s'%(vardef,selector['len']) - if selector.has_key('kind'): - vardef='%s,kind=%s)'%(vardef,selector['kind']) - else: - vardef='%s)'%(vardef) - elif selector.has_key('kind'): - vardef='%s(kind=%s)'%(vardef,selector['kind']) - - vardef='%s %s'%(vardef,fa) - if vars[a].has_key('dimension'): - vardef='%s(%s)'%(vardef,string.join(vars[a]['dimension'],',')) - return vardef - -def createfuncwrapper(rout,signature=0): - assert isfunction(rout) - ret = [''] - def add(line,ret=ret): - ret[0] = '%s\n %s'%(ret[0],line) - name = rout['name'] - fortranname = getfortranname(rout) - f90mode = ismoduleroutine(rout) - newname = '%sf2pywrap'%(name) - vars = rout['vars'] - if not vars.has_key(newname): - vars[newname] = vars[name] - args = [newname]+rout['args'][1:] - else: - args = [newname]+rout['args'] - - l = var2fixfortran(vars,name,newname,f90mode) - return_char_star = 0 - if l[:13]=='character*(*)': - return_char_star = 1 - if f90mode: l = 'character(len=10)'+l[13:] - else: l = 'character*10'+l[13:] - charselect = vars[name]['charselector'] - if charselect.get('*','')=='(*)': - charselect['*'] = '10' - if f90mode: - sargs = string.join(args,', ') - add('subroutine f2pywrap_%s_%s (%s)'%(rout['modulename'],name,sargs)) - if not signature: - add('use %s, only : %s'%(rout['modulename'],fortranname)) - else: - add('subroutine f2pywrap%s (%s)'%(name,string.join(args,', '))) - add('external %s'%(fortranname)) - #if not return_char_star: - l = l + ', '+fortranname - args = args[1:] - dumped_args = [] - for a in args: - if isexternal(vars[a]): - add('external %s'%(a)) - dumped_args.append(a) - for a in args: - if a in dumped_args: continue - if isscalar(vars[a]): - add(var2fixfortran(vars,a,f90mode=f90mode)) - dumped_args.append(a) - for a in args: - if a in dumped_args: continue - add(var2fixfortran(vars,a,f90mode=f90mode)) - - add(l) - - if not signature: - if islogicalfunction(rout): - add('%s = .not.(.not.%s(%s))'%(newname,fortranname,string.join(args,', '))) - else: - add('%s = %s(%s)'%(newname,fortranname,string.join(args,', '))) - if f90mode: - add('end subroutine f2pywrap_%s_%s'%(rout['modulename'],name)) - else: - add('end') - #print '**'*10 - #print ret[0] - #print '**'*10 - return ret[0] - -def assubr(rout): - if not isfunction_wrap(rout): return rout,'' - fortranname = getfortranname(rout) - name = rout['name'] - outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n'%(name,fortranname)) - rout = copy.copy(rout) - fname = name - rname = fname - if rout.has_key('result'): - rname = rout['result'] - rout['vars'][fname]=rout['vars'][rname] - fvar = rout['vars'][fname] - if not isintent_out(fvar): - if not fvar.has_key('intent'): fvar['intent']=[] - fvar['intent'].append('out') - flag=1 - for i in fvar['intent']: - if i.startswith('out='): - flag = 0 - break - if flag: - fvar['intent'].append('out=%s' % (rname)) - - rout['args'] = [fname] + rout['args'] - return rout,createfuncwrapper(rout) diff --git a/numpy/f2py/info.py b/numpy/f2py/info.py deleted file mode 100644 index 8beaba228..000000000 --- a/numpy/f2py/info.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Fortran to Python Interface Generator. - -""" - -postpone_import = True diff --git a/numpy/f2py/lib/__init__.py b/numpy/f2py/lib/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/numpy/f2py/lib/__init__.py +++ /dev/null diff --git a/numpy/f2py/lib/base_classes.py b/numpy/f2py/lib/base_classes.py deleted file mode 100644 index ee19caaae..000000000 --- a/numpy/f2py/lib/base_classes.py +++ /dev/null @@ -1,577 +0,0 @@ - -__all__ = ['Statement','BeginStatement','EndStatement'] - -import re -import sys -import copy -from readfortran import Line -from numpy.distutils.misc_util import yellow_text, red_text -from utils import split_comma, specs_split_comma, is_int_literal_constant - -class AttributeHolder: - # copied from symbolic.base module - """ - Defines a object with predefined attributes. Only those attributes - are allowed that are specified as keyword arguments of a constructor. - When an argument is callable then the corresponding attribute will - be read-only and set by the value the callable object returns. - """ - def __init__(self, **kws): - self._attributes = {} - self._readonly = [] - for k,v in kws.items(): - self._attributes[k] = v - if callable(v): - self._readonly.append(k) - return - - def __getattr__(self, name): - if name not in self._attributes: - raise AttributeError,'%s instance has no attribute %r, '\ - 'expected attributes: %s' \ - % (self.__class__.__name__,name, - ','.join(self._attributes.keys())) - value = self._attributes[name] - if callable(value): - value = value() - self._attributes[name] = value - return value - - def __setattr__(self, name, value): - if name in ['_attributes','_readonly']: - self.__dict__[name] = value - return - if name in self._readonly: - raise AttributeError,'%s instance attribute %r is readonly' \ - % (self.__class__.__name__, name) - if name not in self._attributes: - raise AttributeError,'%s instance has no attribute %r, '\ - 'expected attributes: %s' \ - % (self.__class__.__name__,name,','.join(self._attributes.keys())) - self._attributes[name] = value - - def __repr__(self): - l = [] - for k in self._attributes.keys(): - v = getattr(self,k) - l.append('%s=%r' % (k,v)) - return '%s(%s)' % (self.__class__.__name__,', '.join(l)) - - def todict(self): - d = {} - for k in self._attributes.keys(): - v = getattr(self, k) - d[k] = v - return d - -def get_base_classes(cls): - bases = () - for c in cls.__bases__: - bases += get_base_classes(c) - return bases + cls.__bases__ + (cls,) - -class Variable: - """ - Variable instance has attributes: - name - typedecl - dimension - attributes - intent - parent - Statement instances defining the variable - """ - def __init__(self, parent, name): - self.parent = parent - self.parents = [parent] - self.name = name - self.typedecl = None - self.dimension = None - self.bounds = None - self.length = None - self.attributes = [] - self.intent = None - self.bind = [] - self.check = [] - self.init = None - return - - def add_parent(self, parent): - if id(parent) not in map(id, self.parents): - self.parents.append(parent) - self.parent = parent - return - - def set_type(self, typedecl): - if self.typedecl is not None: - if not self.typedecl==typedecl: - self.parent.warning(\ - 'variable %r already has type %s,'\ - ' resetting to %s' \ - % (self.name, self.typedecl.tostr(),typedecl.tostr())) - self.typedecl = typedecl - return - - def set_init(self, expr): - if self.init is not None: - if not self.init==expr: - self.parent.warning(\ - 'variable %r already has initialization %r, '\ - ' resetting to %r' % (self.name, self.expr, expr)) - self.init = expr - return - - def set_dimension(self, dims): - if self.dimension is not None: - if not self.dimension==dims: - self.parent.warning(\ - 'variable %r already has dimension %r, '\ - ' resetting to %r' % (self.name, self.dimension, dims)) - self.dimension = dims - return - - def set_bounds(self, bounds): - if self.bounds is not None: - if not self.bounds==bounds: - self.parent.warning(\ - 'variable %r already has bounds %r, '\ - ' resetting to %r' % (self.name, self.bounds, bounds)) - self.bounds = bounds - return - - def set_length(self, length): - if self.length is not None: - if not self.length==length: - self.parent.warning(\ - 'variable %r already has length %r, '\ - ' resetting to %r' % (self.name, self.length, length)) - self.length = length - return - - known_intent_specs = ['IN','OUT','INOUT','CACHE','HIDE', 'COPY', - 'OVERWRITE', 'CALLBACK', 'AUX', 'C', 'INPLACE', - 'OUT='] - - def set_intent(self, intent): - if self.intent is None: - self.intent = [] - for i in intent: - if i not in self.intent: - if i not in self.known_intent_specs: - self.parent.warning('unknown intent-spec %r for %r'\ - % (i, self.name)) - self.intent.append(i) - return - - known_attributes = ['PUBLIC', 'PRIVATE', 'ALLOCATABLE', 'ASYNCHRONOUS', - 'EXTERNAL', 'INTRINSIC', 'OPTIONAL', 'PARAMETER', - 'POINTER', 'PROTECTED', 'SAVE', 'TARGET', 'VALUE', - 'VOLATILE', 'REQUIRED'] - - def is_private(self): - if 'PUBLIC' in self.attributes: return False - if 'PRIVATE' in self.attributes: return True - parent_attrs = self.parent.parent.a.attributes - if 'PUBLIC' in parent_attrs: return False - if 'PRIVATE' in parent_attrs: return True - return - def is_public(self): return not self.is_private() - - def is_allocatable(self): return 'ALLOCATABLE' in self.attributes - def is_external(self): return 'EXTERNAL' in self.attributes - def is_intrinsic(self): return 'INTRINSIC' in self.attributes - def is_parameter(self): return 'PARAMETER' in self.attributes - def is_optional(self): return 'OPTIONAL' in self.attributes - def is_required(self): return 'REQUIRED' in self.attributes - - def update(self, *attrs): - attributes = self.attributes - if len(attrs)==1 and isinstance(attrs[0],(tuple,list)): - attrs = attrs[0] - for attr in attrs: - lattr = attr.lower() - uattr = attr.upper() - if lattr.startswith('dimension'): - assert self.dimension is None, `self.dimension,attr` - l = attr[9:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.set_dimension(split_comma(l[1:-1].strip(), self.parent.item)) - continue - if lattr.startswith('intent'): - l = attr[6:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.set_intent(specs_split_comma(l[1:-1].strip(), - self.parent.item, upper=True)) - continue - if lattr.startswith('bind'): - l = attr[4:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.bind = specs_split_comma(l[1:-1].strip(), self.parent.item, - upper = True) - continue - if lattr.startswith('check'): - l = attr[5:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.check.extend(split_comma(l[1:-1].strip()), self.parent.item) - continue - if uattr not in attributes: - if uattr not in self.known_attributes: - self.parent.warning('unknown attribute %r' % (attr)) - attributes.append(uattr) - return - - def __str__(self): - s = '' - if self.typedecl is not None: - s += self.typedecl.tostr() + ' ' - a = self.attributes[:] - if self.dimension is not None: - a.append('DIMENSION(%s)' % (', '.join(self.dimension))) - if self.intent is not None: - a.append('INTENT(%s)' % (', '.join(self.intent))) - if self.bind: - a.append('BIND(%s)' % (', '.join(self.bind))) - if self.check: - a.append('CHECK(%s)' % (', '.join(self.check))) - if a: - s += ', '.join(a) + ' :: ' - s += self.name - if self.bounds: - s += '(%s)' % (', '.join(self.bounds)) - if self.length: - if is_int_literal_constant(self.length): - s += '*%s' % (self.length) - else: - s += '*(%s)' % (self.length) - if self.init: - s += ' = ' + self.init - return s - -class ProgramBlock: - pass - -class Statement: - """ - Statement instance has attributes: - parent - Parent BeginStatement or FortranParser instance - item - Line instance containing the statement line - isvalid - boolean, when False, the Statement instance will be ignored - """ - modes = ['free90','fix90','fix77','pyf'] - - def __init__(self, parent, item): - self.parent = parent - if item is not None: - self.reader = item.reader - else: - self.reader = parent.reader - self.top = getattr(parent,'top',None) - if isinstance(parent, ProgramBlock): - self.programblock = parent - elif isinstance(self, ProgramBlock): - self.programblock = self - elif hasattr(parent,'programblock'): - self.programblock = parent.programblock - - self.item = item - - # when a statement instance is constructed by error, set isvalid to False - self.isvalid = True - # when a statement should be ignored, set ignore to True - self.ignore = False - - # attribute a will hold analyze information. - a_dict = {} - for cls in get_base_classes(self.__class__): - if hasattr(cls,'a'): - a_dict.update(copy.deepcopy(cls.a.todict())) - self.a = AttributeHolder(**a_dict) - if hasattr(self.__class__,'a'): - assert self.a is not self.__class__.a - - self.process_item() - - return - - def get_indent_tab(self,colon=None,deindent=False): - if self.reader.isfix: - tab = ' '*6 - else: - tab = '' - p = self.parent - while isinstance(p, Statement): - tab += ' ' - p = p.parent - if deindent: - tab = tab[:-2] - if self.item is None: - return tab - s = self.item.label - if colon is None: - if self.reader.isfix: - colon = '' - else: - colon = ':' - if s: - c = '' - if self.reader.isfix: - c = ' ' - tab = tab[len(c+s)+len(colon):] - if not tab: tab = ' ' - tab = c + s + colon + tab - return tab - - def format_message(self, kind, message): - message = self.reader.format_message(kind, message, - self.item.span[0], self.item.span[1]) - return message - - def show_message(self, message, stream=sys.stderr): - print >> stream, message - stream.flush() - return - - def error(self, message): - message = self.format_message('ERROR', red_text(message)) - self.show_message(message) - return - - def warning(self, message): - message = self.format_message('WARNING', yellow_text(message)) - self.show_message(message) - return - - def info(self, message): - message = self.format_message('INFO', message) - self.show_message(message) - return - - def analyze(self): - self.warning('nothing analyzed') - return - - def get_variable(self, name): - variables = self.parent.a.variables - if not variables.has_key(name): - variables[name] = var = Variable(self, name) - else: - var = variables[name] - var.add_parent(self) - return var - -class BeginStatement(Statement): - """ <blocktype> <name> - - BeginStatement instances have additional attributes: - name - blocktype - - Block instance has attributes: - content - list of Line or Statement instances - name - name of the block, unnamed blocks are named - with the line label - parent - Block or FortranParser instance - item - Line instance containing the block start statement - get_item, put_item - methods to retrive/submit Line instaces - from/to Fortran reader. - isvalid - boolean, when False, the Block instance will be ignored. - - stmt_cls, end_stmt_cls - - """ - def __init__(self, parent, item=None): - - self.content = [] - self.get_item = parent.get_item # get line function - self.put_item = parent.put_item # put line function - if not hasattr(self, 'blocktype'): - self.blocktype = self.__class__.__name__.lower() - if not hasattr(self, 'name'): - # process_item may change this - self.name = '__'+self.blocktype.upper()+'__' - - Statement.__init__(self, parent, item) - return - - def tostr(self): - return self.blocktype.upper() + ' '+ self.name - - def __str__(self): - l=[self.get_indent_tab(colon=':') + self.tostr()] - for c in self.content: - l.append(str(c)) - return '\n'.join(l) - - def process_item(self): - """ Process the line - """ - item = self.item - if item is None: return - self.fill() - return - - def fill(self, end_flag = False): - """ - Fills blocks content until the end of block statement. - """ - - mode = self.reader.mode - classes = self.get_classes() - self.classes = [cls for cls in classes if mode in cls.modes] - self.pyf_classes = [cls for cls in classes if 'pyf' in cls.modes] - - item = self.get_item() - while item is not None: - if isinstance(item, Line): - if self.process_subitem(item): - end_flag = True - break - item = self.get_item() - - if not end_flag: - self.warning('failed to find the end of block') - return - - def process_subitem(self, item): - """ - Check is item is blocks start statement, if it is, read the block. - - Return True to stop adding items to given block. - """ - line = item.get_line() - - # First check for the end of block - cls = self.end_stmt_cls - if cls.match(line): - stmt = cls(self, item) - if stmt.isvalid: - self.content.append(stmt) - return True - - if item.is_f2py_directive: - classes = self.pyf_classes - else: - classes = self.classes - - # Look for statement match - for cls in classes: - if cls.match(line): - stmt = cls(self, item) - if stmt.isvalid: - if not stmt.ignore: - self.content.append(stmt) - return False - # item may be cloned that changes the items line: - line = item.get_line() - - # Check if f77 code contains inline comments or other f90 - # constructs that got undetected by get_source_info. - if item.reader.isfix77: - i = line.find('!') - if i != -1: - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block'\ - ' maybe due to inline comment.'\ - ' Trying to remove the comment.'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - # .. but at the expense of loosing the comment. - self.show_message(message) - newitem = item.copy(line[:i].rstrip()) - return self.process_subitem(newitem) - - # try fix90 statement classes - f77_classes = self.classes - classes = [] - for cls in self.get_classes(): - if 'fix90' in cls.modes and cls not in f77_classes: - classes.append(cls) - if classes: - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block'\ - ' maybe due to strict f77 mode.'\ - ' Trying f90 fix mode patterns..'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - self.show_message(message) - - item.reader.set_mode(False, False) - self.classes = classes - - r = BeginStatement.process_subitem(self, item) - if r is None: - # restore f77 fix mode - self.classes = f77_classes - item.reader.set_mode(False, True) - else: - message = item.reader.format_message(\ - 'INFORMATION', - 'The f90 fix mode resolved the parse pattern issue.'\ - ' Setting reader to f90 fix mode.', - item.span[0], item.span[1]) - self.show_message(message) - # set f90 fix mode - self.classes = f77_classes + classes - self.reader.set_mode(False, False) - return r - - self.handle_unknown_item(item) - return - - def handle_unknown_item(self, item): - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block.'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - self.show_message(message) - self.content.append(item) - #sys.exit() - return - - def analyze(self): - for stmt in self.content: - stmt.analyze() - return - -class EndStatement(Statement): - """ - END [<blocktype> [<name>]] - - EndStatement instances have additional attributes: - name - blocktype - """ - - def __init__(self, parent, item): - if not hasattr(self, 'blocktype'): - self.blocktype = self.__class__.__name__.lower()[3:] - Statement.__init__(self, parent, item) - - def process_item(self): - item = self.item - line = item.get_line().replace(' ','')[3:] - blocktype = self.blocktype - if line.startswith(blocktype): - line = line[len(blocktype):].strip() - else: - if line: - # not the end of expected block - line = '' - self.isvalid = False - if line: - if not line==self.parent.name: - self.warning(\ - 'expected the end of %r block but got the end of %r, skipping.'\ - % (self.parent.name, line)) - self.isvalid = False - self.name = self.parent.name - - def analyze(self): - return - - def __str__(self): - return self.get_indent_tab()[:-2] + 'END %s %s'\ - % (self.blocktype.upper(),self.name or '') - diff --git a/numpy/f2py/lib/block_statements.py b/numpy/f2py/lib/block_statements.py deleted file mode 100644 index 767bd0893..000000000 --- a/numpy/f2py/lib/block_statements.py +++ /dev/null @@ -1,892 +0,0 @@ -""" - -""" - -import re -import sys - -from base_classes import BeginStatement, EndStatement, Statement,\ - AttributeHolder, ProgramBlock -from readfortran import Line -from utils import filter_stmts, parse_bind, parse_result - -class HasImplicitStmt: - - a = AttributeHolder(implicit_rules = None) - - def get_type(self, name): - implicit_rules = self.a.implicit_rules - if implicit_rules=={}: - raise ValueError,'Implicit rules mapping is null' - l = name[0].lower() - if implicit_rules.has_key(l): - return implicit_rules[l] - # default rules - if l in 'ijklmn': - return implicit_rules['default_integer'] - return implicit_rules['default_real'] - - def initialize(self): - implicit_rules = self.a.implicit_rules - if implicit_rules is not None: - return - self.a.implicit_rules = implicit_rules = {} - real = Real(self, self.item.copy('real')) - assert real.isvalid - integer = Integer(self, self.item.copy('integer')) - assert integer.isvalid - implicit_rules['default_real'] = real - implicit_rules['default_integer'] = integer - return - -class HasUseStmt: - - a = AttributeHolder(use = {}) - - def get_entity(self, name): - for modname, modblock in self.top.a.module.items(): - for stmt in modblock.content: - if getattr(stmt,'name','') == name: - return stmt - return - - def initialize(self): - - return - -class HasVariables: - - a = AttributeHolder(variables = {}) - -class HasTypeDecls: - - a = AttributeHolder(type_decls = {}) - -class HasAttributes: - - a = AttributeHolder(attributes = []) - -class HasModuleProcedures: - - a = AttributeHolder(module_procedures = []) - -# File block - -class EndSource(EndStatement): - """ - Dummy End statement for BeginSource. - """ - match = staticmethod(lambda s: False) - -class BeginSource(BeginStatement): - """ - Fortran source content. - """ - match = staticmethod(lambda s: True) - end_stmt_cls = EndSource - a = AttributeHolder(module = {}, - external_subprogram = {}, - blockdata = {}, - ) - - def tostr(self): - return '!' + self.blocktype.upper() + ' '+ self.name - - def process_item(self): - self.name = self.reader.name - self.top = self - self.fill(end_flag = True) - return - - def analyze(self): - for stmt in self.content: - if isinstance(stmt, Module): - stmt.analyze() - self.a.module[stmt.name] = stmt - elif isinstance(stmt, SubProgramStatement): - stmt.analyze() - self.a.external_subprogram[stmt.name] = stmt - elif isinstance(stmt, BlockData): - stmt.analyze() - self.a.blockdata[stmt.name] = stmt - else: - stmt.analyze() - return - - def get_classes(self): - return program_unit - - def process_subitem(self, item): - # MAIN block does not define start/end line conditions, - # so it should never end until all lines are read. - # However, sometimes F77 programs lack the PROGRAM statement, - # and here we fix that: - if self.reader.isfix77: - line = item.get_line() - if line=='end': - message = item.reader.format_message(\ - 'WARNING', - 'assuming the end of undefined PROGRAM statement', - item.span[0],item.span[1]) - print >> sys.stderr, message - p = Program(self) - p.content.extend(self.content) - p.content.append(EndProgram(p,item)) - self.content[:] = [p] - return - return BeginStatement.process_subitem(self, item) - -# Module - -class EndModule(EndStatement): - match = re.compile(r'end(\s*module\s*\w*|)\Z', re.I).match - -class Module(BeginStatement, HasAttributes, - HasImplicitStmt, HasUseStmt, HasVariables, - HasTypeDecls): - """ - MODULE <name> - .. - END [MODULE [name]] - """ - match = re.compile(r'module\s*\w+\Z', re.I).match - end_stmt_cls = EndModule - a = AttributeHolder(module_subprogram = {}, - module_data = {}, - ) - - def get_classes(self): - return access_spec + specification_part + module_subprogram_part - - def process_item(self): - name = self.item.get_line().replace(' ','')[len(self.blocktype):].strip() - self.name = name - return BeginStatement.process_item(self) - - def analyze(self): - content = self.content[:] - - [stmt.analyze() for stmt in filter_stmts(content, Use)] - HasUseStmt.initialize(self) - - [stmt.analyze() for stmt in filter_stmts(content, Implicit)] - HasImplicitStmt.initialize(self) - - while content: - stmt = content.pop(0) - if isinstance(stmt, Contains): - for stmt in filter_stmts(content, SubProgramStatement): - stmt.analyze() - self.a.module_subprogram[stmt.name] = stmt - stmt = content.pop(0) - assert isinstance(stmt, EndModule),`stmt` - continue - stmt.analyze() - - if content: - self.show_message('Not analyzed content: %s' % content) - - return - -# Python Module - -class EndPythonModule(EndStatement): - match = re.compile(r'end(\s*python\s*module\s*\w*|)\Z', re.I).match - -class PythonModule(BeginStatement, HasImplicitStmt, HasUseStmt): - """ - PYTHON MODULE <name> - .. - END [PYTHON MODULE [name]] - """ - modes = ['pyf'] - match = re.compile(r'python\s*module\s*\w+\Z', re.I).match - end_stmt_cls = EndPythonModule - - def get_classes(self): - return [Interface, Function, Subroutine, Module] - - def process_item(self): - self.name = self.item.get_line().replace(' ','')\ - [len(self.blocktype):].strip() - return BeginStatement.process_item(self) - -# Program - -class EndProgram(EndStatement): - """ - END [PROGRAM [name]] - """ - match = re.compile(r'end(\s*program\s*\w*|)\Z', re.I).match - -class Program(BeginStatement, ProgramBlock, HasAttributes, - HasImplicitStmt, HasUseStmt): - """ PROGRAM [name] - """ - match = re.compile(r'program\s*\w*\Z', re.I).match - end_stmt_cls = EndProgram - - def get_classes(self): - return specification_part + execution_part + internal_subprogram_part - - def process_item(self): - if self.item is not None: - name = self.item.get_line().replace(' ','')\ - [len(self.blocktype):].strip() - if name: - self.name = name - return BeginStatement.process_item(self) - -# BlockData - -class EndBlockData(EndStatement): - """ - END [ BLOCK DATA [ <block-data-name> ] ] - """ - match = re.compile(r'end(\s*block\s*data\s*\w*|)\Z', re.I).match - blocktype = 'blockdata' - -class BlockData(BeginStatement, HasImplicitStmt, HasUseStmt, - HasVariables): - """ - BLOCK DATA [ <block-data-name> ] - """ - end_stmt_cls = EndBlockData - match = re.compile(r'block\s*data\s*\w*\Z', re.I).match - - def process_item(self): - self.name = self.item.get_line()[5:].lstrip()[4:].lstrip() - return BeginStatement.process_item(self) - - def get_classes(self): - return specification_part - -# Interface - -class EndInterface(EndStatement): - match = re.compile(r'end\s*interface\s*\w*\Z', re.I).match - blocktype = 'interface' - -class Interface(BeginStatement, HasImplicitStmt, HasUseStmt, - HasModuleProcedures - ): - """ - INTERFACE [<generic-spec>] | ABSTRACT INTERFACE - END INTERFACE [<generic-spec>] - - <generic-spec> = <generic-name> - | OPERATOR ( <defined-operator> ) - | ASSIGNMENT ( = ) - | <dtio-generic-spec> - <dtio-generic-spec> = READ ( FORMATTED ) - | READ ( UNFORMATTED ) - | WRITE ( FORMATTED ) - | WRITE ( UNFORMATTED ) - - """ - modes = ['free90', 'fix90', 'pyf'] - match = re.compile(r'(interface\s*(\w+\s*\(.*\)|\w*)|abstract\s*interface)\Z',re.I).match - end_stmt_cls = EndInterface - blocktype = 'interface' - - def get_classes(self): - return intrinsic_type_spec + interface_specification - - def process_item(self): - line = self.item.get_line() - self.isabstract = line.startswith('abstract') - if self.isabstract: - self.generic_spec = '' - else: - self.generic_spec = line[len(self.blocktype):].strip() - self.name = self.generic_spec # XXX - return BeginStatement.process_item(self) - - def tostr(self): - if self.isabstract: - return 'ABSTRACT INTERFACE' - return 'INTERFACE '+ str(self.generic_spec) - - -# Subroutine - -class SubProgramStatement(BeginStatement, ProgramBlock, - HasImplicitStmt, HasAttributes, - HasUseStmt, HasVariables, HasTypeDecls - ): - """ - [ <prefix> ] <FUNCTION|SUBROUTINE> <name> [ ( <args> ) ] [ <suffix> ] - """ - a = AttributeHolder(internal_subprogram = {}) - - def process_item(self): - clsname = self.__class__.__name__.lower() - item = self.item - line = item.get_line() - m = self.match(line) - i = line.find(clsname) - assert i!=-1,`line` - self.prefix = line[:i].rstrip() - self.name = line[i:m.end()].lstrip()[len(clsname):].strip() - line = line[m.end():].lstrip() - args = [] - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - line2 = item.apply_map(line[:i+1]) - for a in line2[1:-1].split(','): - a=a.strip() - if not a: continue - args.append(a) - line = line[i+1:].lstrip() - suffix = item.apply_map(line) - self.bind, suffix = parse_bind(suffix, item) - self.result = None - if isinstance(self, Function): - self.result, suffix = parse_result(suffix, item) - if suffix: - assert self.bind is None,`self.bind` - self.bind, suffix = parse_result(suffix, item) - if self.result is None: - self.result = self.name - assert not suffix,`suffix` - self.args = args - self.typedecl = None - return BeginStatement.process_item(self) - - def tostr(self): - clsname = self.__class__.__name__.upper() - s = '' - if self.prefix: - s += self.prefix + ' ' - if self.typedecl is not None: - assert isinstance(self, Function),`self.__class__.__name__` - s += self.typedecl.tostr() + ' ' - s += clsname - suf = '' - if self.result and self.result!=self.name: - suf += ' RESULT ( %s )' % (self.result) - if self.bind: - suf += ' BIND ( %s )' % (', '.join(self.bind)) - return '%s %s(%s)%s' % (s, self.name,', '.join(self.args),suf) - - def get_classes(self): - return f2py_stmt + specification_part + execution_part \ - + internal_subprogram_part - - def analyze(self): - content = self.content[:] - - variables = self.a.variables - for a in self.args: - assert not variables.has_key(a) - assert is_name(a) - variables[a] = Variable(self, a) - - if isinstance(self, Function): - variables[self.result] = Variable(self, self.result) - - [stmt.analyze() for stmt in filter_stmts(content, Use)] - HasUseStmt.initialize(self) - - [stmt.analyze() for stmt in filter_stmts(content, Implicit)] - HasImplicitStmt.initialize(self) - - while content: - stmt = content.pop(0) - if isinstance(stmt, Contains): - for stmt in filter_stmts(content, SubProgramStatement): - stmt.analyze() - self.a.internal_subprogram[stmt.name] = stmt - stmt = content.pop(0) - assert isinstance(stmt, self.end_stmt_cls),`stmt` - elif isinstance(stmt, self.end_stmt_cls): - continue - else: - stmt.analyze() - if content: - self.show_message('Not analyzed content: %s' % content) - - return - -class EndSubroutine(EndStatement): - """ - END [SUBROUTINE [name]] - """ - match = re.compile(r'end(\s*subroutine\s*\w*|)\Z', re.I).match - - -class Subroutine(SubProgramStatement): - """ - [ <prefix> ] SUBROUTINE <name> [ ( [ <dummy-arg-list> ] ) [ <proc-language-binding-spec> ]] - """ - end_stmt_cls = EndSubroutine - match = re.compile(r'(recursive|pure|elemental|\s)*subroutine\s*\w+', re.I).match - -# Function - -class EndFunction(EndStatement): - """ - END [FUNCTION [name]] - """ - match = re.compile(r'end(\s*function\s*\w*|)\Z', re.I).match - -class Function(SubProgramStatement): - """ - [ <prefix> ] FUNCTION <name> ( [<dummy-arg-list>] ) [<suffix>] - <prefix> = <prefix-spec> [ <prefix-spec> ]... - <prefix-spec> = <declaration-type-spec> - | RECURSIVE | PURE | ELEMENTAL - <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] - | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] - """ - end_stmt_cls = EndFunction - match = re.compile(r'(recursive|pure|elemental|\s)*function\s*\w+', re.I).match - -# Handle subprogram prefixes - -class SubprogramPrefix(Statement): - """ - <prefix> <declaration-type-spec> <function|subroutine> ... - """ - match = re.compile(r'(pure|elemental|recursive|\s)+\b',re.I).match - def process_item(self): - line = self.item.get_line() - m = self.match(line) - prefix = line[:m.end()].rstrip() - rest = self.item.get_line()[m.end():].lstrip() - if rest: - self.parent.put_item(self.item.copy(prefix)) - self.item.clone(rest) - self.isvalid = False - return - if self.parent.__class__ not in [Function, Subroutine]: - self.isvalid = False - return - prefix = prefix + ' ' + self.parent.prefix - self.parent.prefix = prefix.strip() - self.ignore = True - return - -# SelectCase - -class EndSelect(EndStatement): - match = re.compile(r'end\s*select\s*\w*\Z', re.I).match - blocktype = 'select' - -class Select(BeginStatement): - """ - [ <case-construct-name> : ] SELECT CASE ( <case-expr> ) - - """ - match = re.compile(r'select\s*case\s*\(.*\)\Z',re.I).match - end_stmt_cls = EndSelect - name = '' - def tostr(self): - return 'SELECT CASE ( %s )' % (self.expr) - def process_item(self): - self.expr = self.item.get_line()[6:].lstrip()[4:].lstrip()[1:-1].strip() - self.name = self.item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Case] + execution_part_construct - -# Where - -class EndWhere(EndStatement): - """ - END WHERE [ <where-construct-name> ] - """ - match = re.compile(r'end\s*\where\s*\w*\Z',re.I).match - - -class Where(BeginStatement): - """ - [ <where-construct-name> : ] WHERE ( <mask-expr> ) - <mask-expr> = <logical-expr> - """ - match = re.compile(r'where\s*\([^)]*\)\Z',re.I).match - end_stmt_cls = EndWhere - name = '' - def tostr(self): - return 'WHERE ( %s )' % (self.expr) - def process_item(self): - self.expr = self.item.get_line()[5:].lstrip()[1:-1].strip() - self.name = self.item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Assignment, WhereStmt, - WhereConstruct, ElseWhere - ] - -WhereConstruct = Where - -# Forall - -class EndForall(EndStatement): - """ - END FORALL [ <forall-construct-name> ] - """ - match = re.compile(r'end\s*forall\s*\w*\Z',re.I).match - -class Forall(BeginStatement): - """ - [ <forall-construct-name> : ] FORALL <forall-header> - [ <forall-body-construct> ]... - <forall-body-construct> = <forall-assignment-stmt> - | <where-stmt> - | <where-construct> - | <forall-construct> - | <forall-stmt> - <forall-header> = ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) - <forall-triplet-spec> = <index-name> = <subscript> : <subscript> [ : <stride> ] - <subscript|stride> = <scalar-int-expr> - <forall-assignment-stmt> = <assignment-stmt> | <pointer-assignment-stmt> - """ - end_stmt_cls = EndForall - match = re.compile(r'forarr\s*\(.*\)\Z',re.I).match - name = '' - def process_item(self): - self.specs = self.item.get_line()[6:].lstrip()[1:-1].strip() - return BeginStatement.process_item(self) - def tostr(self): - return 'FORALL (%s)' % (self.specs) - def get_classes(self): - return [GeneralAssignment, WhereStmt, WhereConstruct, - ForallConstruct, ForallStmt] - -ForallConstruct = Forall - -# IfThen - -class EndIfThen(EndStatement): - """ - END IF [ <if-construct-name> ] - """ - match = re.compile(r'end\s*if\s*\w*\Z', re.I).match - blocktype = 'if' - -class IfThen(BeginStatement): - """ - [<if-construct-name> :] IF ( <scalar-logical-expr> ) THEN - - IfThen instance has the following attributes: - expr - """ - - match = re.compile(r'if\s*\(.*\)\s*then\Z',re.I).match - end_stmt_cls = EndIfThen - name = '' - - def tostr(self): - return 'IF (%s) THEN' % (self.expr) - - def process_item(self): - item = self.item - line = item.get_line()[2:-4].strip() - assert line[0]=='(' and line[-1]==')',`line` - self.expr = line[1:-1].strip() - self.name = item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Else, ElseIf] + execution_part_construct - -class If(BeginStatement): - """ - IF ( <scalar-logical-expr> ) action-stmt - """ - - match = re.compile(r'if\s*\(').match - - def process_item(self): - item = self.item - mode = self.reader.mode - classes = self.get_classes() - classes = [cls for cls in classes if mode in cls.modes] - - line = item.get_line()[2:] - i = line.find(')') - expr = line[1:i].strip() - line = line[i+1:].strip() - if line.lower()=='then': - self.isvalid = False - return - self.expr = expr[1:-1] - - if not line: - newitem = self.get_item() - else: - newitem = item.copy(line) - newline = newitem.get_line() - for cls in classes: - if cls.match(newline): - stmt = cls(self, newitem) - if stmt.isvalid: - self.content.append(stmt) - return - if not line: - self.put_item(newitem) - self.isvalid = False - return - - def tostr(self): - assert len(self.content)==1,`self.content` - return 'IF (%s) %s' % (self.expr, str(self.content[0]).lstrip()) - - def __str__(self): - return self.get_indent_tab(colon=':') + self.tostr() - - def get_classes(self): - return action_stmt - -# Do - -class EndDo(EndStatement): - """ - END DO [ <do-construct-name> ] - """ - match = re.compile(r'end\s*do\s*\w*\Z', re.I).match - blocktype = 'do' - -class Do(BeginStatement): - """ - [ <do-construct-name> : ] DO label [loopcontrol] - [ <do-construct-name> : ] DO [loopcontrol] - - """ - - match = re.compile(r'do\b\s*\d*',re.I).match - item_re = re.compile(r'do\b\s*(?P<label>\d*)\s*,?\s*(?P<loopcontrol>.*)\Z',re.I).match - end_stmt_cls = EndDo - name = '' - - def tostr(self): - return 'DO %s %s' % (self.endlabel, self.loopcontrol) - - def process_item(self): - item = self.item - line = item.get_line() - m = self.item_re(line) - self.endlabel = m.group('label').strip() - self.name = item.label - self.loopcontrol = m.group('loopcontrol').strip() - return BeginStatement.process_item(self) - - def process_subitem(self, item): - r = False - if self.endlabel: - label = item.label - if label == self.endlabel: - r = True - if isinstance(self.parent, Do) and label==self.parent.endlabel: - # the same item label may be used for different block ends - self.put_item(item) - return BeginStatement.process_subitem(self, item) or r - - def get_classes(self): - return execution_part_construct - -# Associate - -class EndAssociate(EndStatement): - """ - END ASSOCIATE [ <associate-construct-name> ] - """ - match = re.compile(r'end\s*associate\s*\w*\Z',re.I).match - -class Associate(BeginStatement): - """ - [ <associate-construct-name> : ] ASSOCIATE ( <association-list> ) - <block> - - <association> = <associate-name> => <selector> - <selector> = <expr> | <variable> - """ - match = re.compile(r'associate\s*\(.*\)\Z',re.I).match - end_stmt_cls = EndAssociate - - def process_item(self): - line = self.item.get_line()[9:].lstrip() - self.associations = line[1:-1].strip() - return BeginStatement.process_item(self) - def tostr(self): - return 'ASSOCIATE (%s)' % (self.associations) - def get_classes(self): - return execution_part_construct - -# Type - -class EndType(EndStatement): - """ - END TYPE [<type-name>] - """ - match = re.compile(r'end\s*type\s*\w*\Z', re.I).match - blocktype = 'type' - -class Type(BeginStatement, HasVariables, HasAttributes): - """ - TYPE [ [, <type-attr-spec-list>] ::] <type-name> [ ( <type-param-name-list> ) ] - <type-attr-spec> = <access-spec> | EXTENDS ( <parent-type-name> ) - | ABSTRACT | BIND(C) - """ - match = re.compile(r'type\b\s*').match - end_stmt_cls = EndType - is_name = re.compile(r'\w+\Z').match - - def process_item(self): - line = self.item.get_line()[4:].lstrip() - if line.startswith('('): - self.isvalid = False - return - specs = [] - i = line.find('::') - if i!=-1: - for s in line[:i].split(','): - s = s.strip() - if s: specs.append(s) - line = line[i+2:].lstrip() - self.specs = specs - i = line.find('(') - if i!=-1: - self.name = line[:i].rstrip() - assert line[-1]==')',`line` - self.params = line[i+1:-1].lstrip() - else: - self.name = line - self.params = '' - if not self.is_name(self.name): - self.isvalid = False - return - return BeginStatement.process_item(self) - - def tostr(self): - s = 'TYPE' - if self.specs: - s += ', '.join(['']+self.specs) + ' ::' - s += ' ' + self.name - if self.params: - s += ' ('+self.params+')' - return s - - def get_classes(self): - return [Integer] + private_or_sequence + component_part +\ - type_bound_procedure_part - - def analyze(self): - BeginStatement.analyze(self) - assert isinstance(self.parent,HasTypeDecls) - self.parent.a.type_decls[self.name] = self - return - -TypeDecl = Type - -# Enum - -class EndEnum(EndStatement): - """ - END ENUM - """ - match = re.compile(r'end\s*enum\Z',re.I).match - blocktype = 'enum' - -class Enum(BeginStatement): - """ - ENUM , BIND(C) - <enumerator-def-stmt> - [ <enumerator-def-stmt> ]... - """ - blocktype = 'enum' - end_stmt_cls = EndEnum - match = re.compile(r'enum\s*,\s*bind\s*\(\s*c\s*\)\Z',re.I).match - def process_item(self): - return BeginStatement.process_item(self) - def get_classes(self): - return [Enumerator] - -################################################### - -from statements import * -from typedecl_statements import * - -f2py_stmt = [Threadsafe, FortranName, Depend, Check, CallStatement, - CallProtoArgument] - -access_spec = [Public, Private] - -interface_specification = [Function, Subroutine, - ModuleProcedure - ] - -module_subprogram_part = [ Contains, Function, Subroutine ] - -specification_stmt = access_spec + [ Allocatable, Asynchronous, Bind, - Common, Data, Dimension, Equivalence, External, Intent, Intrinsic, - Namelist, Optional, Pointer, Protected, Save, Target, Volatile, - Value ] - -intrinsic_type_spec = [ SubprogramPrefix, Integer , Real, - DoublePrecision, Complex, DoubleComplex, Character, Logical, Byte - ] - -derived_type_spec = [ ] -type_spec = intrinsic_type_spec + derived_type_spec -declaration_type_spec = intrinsic_type_spec + [ TypeStmt, Class ] - -type_declaration_stmt = declaration_type_spec - -private_or_sequence = [ Private, Sequence ] - -component_part = declaration_type_spec + [ ModuleProcedure ] - -proc_binding_stmt = [SpecificBinding, GenericBinding, FinalBinding] - -type_bound_procedure_part = [Contains, Private] + proc_binding_stmt - -#R214 -action_stmt = [ Allocate, GeneralAssignment, Assign, Backspace, Call, Close, - Continue, Cycle, Deallocate, Endfile, Exit, Flush, ForallStmt, - Goto, If, Inquire, Nullify, Open, Print, Read, Return, Rewind, - Stop, Wait, WhereStmt, Write, ArithmeticIf, ComputedGoto, - AssignedGoto, Pause ] -# GeneralAssignment = Assignment + PointerAssignment -# EndFunction, EndProgram, EndSubroutine - part of the corresponding blocks - -executable_construct = [ Associate, Do, ForallConstruct, IfThen, - Select, WhereConstruct ] + action_stmt -#Case, see Select - -execution_part_construct = executable_construct + [ Format, Entry, - Data ] - -execution_part = execution_part_construct[:] - -#C201, R208 -for cls in [EndFunction, EndProgram, EndSubroutine]: - try: execution_part.remove(cls) - except ValueError: pass - -internal_subprogram = [Function, Subroutine] - -internal_subprogram_part = [ Contains, ] + internal_subprogram - -declaration_construct = [ TypeDecl, Entry, Enum, Format, Interface, - Parameter, ModuleProcedure, ] + specification_stmt + \ - type_declaration_stmt -# stmt-function-stmt - -implicit_part = [ Implicit, Parameter, Format, Entry ] - -specification_part = [ Use, Import ] + implicit_part + \ - declaration_construct - - -external_subprogram = [Function, Subroutine] - -main_program = [Program] + specification_part + execution_part + \ - internal_subprogram_part - -program_unit = main_program + external_subprogram + [Module, - BlockData ] diff --git a/numpy/f2py/lib/parsefortran.py b/numpy/f2py/lib/parsefortran.py deleted file mode 100644 index 00b53f0b0..000000000 --- a/numpy/f2py/lib/parsefortran.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/env python -""" -Defines FortranParser. - -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 -""" - -import re -import sys -import traceback -from numpy.distutils.misc_util import yellow_text, red_text - -from readfortran import FortranFileReader, FortranStringReader -from block_statements import BeginSource -from utils import AnalyzeError - -class FortranParser: - - cache = {} - - def __init__(self, reader): - self.reader = reader - if self.cache.has_key(reader.id): - parser = self.cache[reader.id] - self.block = parser.block - self.is_analyzed = parser.is_analyzed - self.block.show_message('using cached %s' % (reader.id)) - else: - self.cache[reader.id] = self - self.block = None - self.is_analyzed = False - return - - def get_item(self): - try: - return self.reader.next(ignore_comments = True) - except StopIteration: - pass - return - - def put_item(self, item): - self.reader.fifo_item.insert(0, item) - return - - def parse(self): - if self.block is not None: - return - try: - block = self.block = BeginSource(self) - except KeyboardInterrupt: - raise - except: - reader = self.reader - while reader is not None: - message = reader.format_message('FATAL ERROR', - 'while processing line', - reader.linecount, reader.linecount) - reader.show_message(message, sys.stdout) - reader = reader.reader - traceback.print_exc(file=sys.stdout) - self.reader.show_message(red_text('STOPPED PARSING'), sys.stdout) - return - return - - def analyze(self): - if self.is_analyzed: - return - if self.block is None: - self.reader.show_message('Nothing to analyze.') - return - - try: - self.block.analyze() - except AnalyzeError: - pass - except: - raise - self.is_analyzed = True - return - -def test_pyf(): - string = """ -python module foo - interface tere - subroutine bar - real r - end subroutine bar - end interface tere -end python module foo -""" - reader = FortranStringReader(string, True, True) - parser = FortranParser(reader) - block = parser.parse() - print block - -def test_free90(): - string = """ -module foo - - subroutine bar - real r - if ( pc_get_lun() .ne. 6) & - write ( pc_get_lun(), '( & - & /, a, /, " p=", i4, " stopping c_flag=", a, & - & /, " print unit=", i8)') & - trim(title), pcpsx_i_pel(), trim(c_flag), pc_get_lun() - if (.true.) then - call smth - end if - aaa : if (.false.) then - else if (a) then aaa - else aaa - end if aaa - hey = 1 - end subroutine bar - abstract interface - - end interface - -end module foo -""" - reader = FortranStringReader(string, True, False) - parser = FortranParser(reader) - block = parser.parse() - print block - -def test_f77(): - string = """\ - program foo - a = 3 - end - subroutine bar - end - pure function foo(a) - end - pure real*4 recursive function bar() - end -""" - reader = FortranStringReader(string, False, True) - parser = FortranParser(reader) - block = parser.parse() - print block - -def simple_main(): - import sys - if not sys.argv[1:]: - return parse_all_f() - for filename in sys.argv[1:]: - reader = FortranFileReader(filename) - print yellow_text('Processing '+filename+' (mode=%r)' % (reader.mode)) - parser = FortranParser(reader) - parser.parse() - parser.analyze() - #print parser.block - -def profile_main(): - import hotshot, hotshot.stats - prof = hotshot.Profile("_parsefortran.prof") - prof.runcall(simple_main) - prof.close() - stats = hotshot.stats.load("_parsefortran.prof") - stats.strip_dirs() - stats.sort_stats('time', 'calls') - stats.print_stats(30) - -def parse_all_f(): - for filename in open('opt_all_f.txt'): - filename = filename.strip() - reader = FortranFileReader(filename) - print yellow_text('Processing '+filename+' (mode=%r)' % (reader.mode)) - parser = FortranParser(reader) - block = parser.parse() - print block - -if __name__ == "__main__": - #test_f77() - #test_free90() - #test_pyf() - simple_main() - #profile_main() - #parse_all_f() - diff --git a/numpy/f2py/lib/readfortran.py b/numpy/f2py/lib/readfortran.py deleted file mode 100644 index b23a7368f..000000000 --- a/numpy/f2py/lib/readfortran.py +++ /dev/null @@ -1,824 +0,0 @@ -#!/usr/bin/env python -""" -Defines FortranReader classes for reading Fortran codes from -files and strings. FortranReader handles comments and line continuations -of both fix and free format Fortran codes. - -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 -""" - -__all__ = ['FortranFileReader', - 'FortranStringReader', - 'FortranReaderError', - 'Line', 'SyntaxErrorLine', - 'Comment', - 'MultiLine','SyntaxErrorMultiLine', - ] - -import re -import os -import sys -import tempfile -import traceback -from cStringIO import StringIO -from numpy.distutils.misc_util import yellow_text, red_text, blue_text - -from sourceinfo import get_source_info -from splitline import String, string_replace_map, splitquote - -_spacedigits=' 0123456789' -_cf2py_re = re.compile(r'(?P<indent>\s*)!f2py(?P<rest>.*)',re.I) -_is_fix_cont = lambda line: line and len(line)>5 and line[5]!=' ' and line[:5]==5*' ' -_is_f90_cont = lambda line: line and '&' in line and line.rstrip()[-1]=='&' -_f90label_re = re.compile(r'\s*(?P<label>(\w+\s*:|\d+))\s*(\b|(?=&)|\Z)',re.I) -_is_include_line = re.compile(r'\s*include\s*("[^"]+"|\'[^\']+\')\s*\Z',re.I).match -_is_fix_comment = lambda line: line and line[0] in '*cC!' -_hollerith_start_search = re.compile(r'(?P<pre>\A|,\s*)(?P<num>\d+)h',re.I).search -_is_call_stmt = re.compile(r'call\b', re.I).match - -class FortranReaderError: # TODO: may be derive it from Exception - def __init__(self, message): - self.message = message - print >> sys.stderr,message - sys.stderr.flush() - -class Line: - """ Holds a Fortran source line. - """ - - f2py_strmap_findall = re.compile(r'(_F2PY_STRING_CONSTANT_\d+_|F2PY_EXPR_TUPLE_\d+)').findall - - def __init__(self, line, linenospan, label, reader): - self.line = line.strip() - self.span = linenospan - self.label = label - self.reader = reader - self.strline = None - self.is_f2py_directive = linenospan[0] in reader.f2py_comment_lines - - def has_map(self): - return not not (hasattr(self,'strlinemap') and self.strlinemap) - - def apply_map(self, line): - if not hasattr(self,'strlinemap') or not self.strlinemap: - return line - findall = self.f2py_strmap_findall - str_map = self.strlinemap - keys = findall(line) - for k in keys: - line = line.replace(k, str_map[k]) - return line - - def copy(self, line = None, apply_map = False): - if line is None: - line = self.line - if apply_map: - line = self.apply_map(line) - return Line(line, self.span, self.label, self.reader) - - def clone(self, line): - self.line = self.apply_map(line) - self.strline = None - return - - def __repr__(self): - return self.__class__.__name__+'(%r,%s,%r)' \ - % (self.line, self.span, self.label) - - def isempty(self, ignore_comments=False): - return not (self.line.strip() or self.label) - - def get_line(self): - if self.strline is not None: - return self.strline - line = self.line - if self.reader.isfix77: - # Handle Hollerith constants by replacing them - # with char-literal-constants. - # H constants may appear only in DATA statements and - # in the argument list of CALL statement. - # Holleriht constants were removed from the Fortran 77 standard. - # The following handling is not perfect but works for simple - # usage cases. - # todo: Handle hollerith constants in DATA statement - if _is_call_stmt(line): - l2 = self.line[4:].lstrip() - i = l2.find('(') - if i != -1 and l2[-1]==')': - substrings = ['call '+l2[:i+1]] - start_search = _hollerith_start_search - l2 = l2[i+1:-1].strip() - m = start_search(l2) - while m: - substrings.append(l2[:m.start()]) - substrings.append(m.group('pre')) - num = int(m.group('num')) - substrings.append("'"+l2[m.end():m.end()+num]+"'") - l2 = l2[m.end()+num:] - m = start_search(l2) - substrings.append(l2) - substrings.append(')') - line = ''.join(substrings) - - line, str_map = string_replace_map(line, lower=not self.reader.ispyf) - self.strline = line - self.strlinemap = str_map - return line - -class SyntaxErrorLine(Line, FortranReaderError): - def __init__(self, line, linenospan, label, reader, message): - Line.__init__(self, line, linenospan, label, reader) - FortranReaderError.__init__(self, message) - -class Comment: - """ Holds Fortran comment. - """ - def __init__(self, comment, linenospan, reader): - self.comment = comment - self.span = linenospan - self.reader = reader - def __repr__(self): - return self.__class__.__name__+'(%r,%s)' \ - % (self.comment, self.span) - def isempty(self, ignore_comments=False): - return ignore_comments or len(self.comment)<2 - -class MultiLine: - """ Holds (prefix, line list, suffix) representing multiline - syntax in .pyf files: - prefix+'''+lines+'''+suffix. - """ - def __init__(self, prefix, block, suffix, linenospan, reader): - self.prefix = prefix - self.block = block - self.suffix = suffix - self.span = linenospan - self.reader = reader - def __repr__(self): - return self.__class__.__name__+'(%r,%r,%r,%s)' \ - % (self.prefix,self.block,self.suffix, - self.span) - def isempty(self, ignore_comments=False): - return not (self.prefix or self.block or self.suffix) - -class SyntaxErrorMultiLine(MultiLine, FortranReaderError): - def __init__(self, prefix, block, suffix, linenospan, reader, message): - MultiLine.__init__(self, prefix, block, suffix, linenospan, reader) - FortranReaderError.__init__(self, message) - - -class FortranReaderBase: - - def __init__(self, source, isfree, isstrict): - """ - source - file-like object with .next() method - used to retrive a line. - source may contain - - Fortran 77 code - - fixed format Fortran 90 code - - free format Fortran 90 code - - .pyf signatures - extended free format Fortran 90 syntax - """ - - self.linecount = 0 - self.source = source - self.isclosed = False - - self.filo_line = [] - self.fifo_item = [] - self.source_lines = [] - - self.f2py_comment_lines = [] # line numbers that contain f2py directives - - self.reader = None - self.include_dirs = ['.'] - - self.set_mode(isfree, isstrict) - return - - def set_mode(self, isfree, isstrict): - self.isfree90 = isfree and not isstrict - self.isfix90 = not isfree and not isstrict - self.isfix77 = not isfree and isstrict - self.ispyf = isfree and isstrict - self.isfree = isfree - self.isfix = not isfree - self.isstrict = isstrict - - if self.isfree90: mode = 'free90' - elif self.isfix90: mode = 'fix90' - elif self.isfix77: mode = 'fix77' - else: mode = 'pyf' - self.mode = mode - self.name = '%s mode=%s' % (self.source, mode) - return - - def close_source(self): - # called when self.source.next() raises StopIteration. - pass - - # For handling raw source lines: - - def put_single_line(self, line): - self.filo_line.append(line) - self.linecount -= 1 - return - - def get_single_line(self): - try: - line = self.filo_line.pop() - self.linecount += 1 - return line - except IndexError: - pass - if self.isclosed: - return None - try: - line = self.source.next() - except StopIteration: - self.isclosed = True - self.close_source() - return None - self.linecount += 1 - # expand tabs, replace special symbols, get rid of nl characters - line = line.expandtabs().replace('\xa0',' ').rstrip() - self.source_lines.append(line) - if not line: - return self.get_single_line() - return line - - def get_next_line(self): - line = self.get_single_line() - if line is None: return - self.put_single_line(line) - return line - - # Iterator methods: - - def __iter__(self): - return self - - def next(self, ignore_comments = False): - - try: - if self.reader is not None: - try: - return self.reader.next() - except StopIteration: - self.reader = None - item = self._next(ignore_comments) - if isinstance(item, Line) and _is_include_line(item.line): - reader = item.reader - filename = item.line.strip()[7:].lstrip()[1:-1] - include_dirs = self.include_dirs[:] - path = filename - for incl_dir in include_dirs: - path = os.path.join(incl_dir, filename) - if os.path.exists(path): - break - if not os.path.isfile(path): - dirs = os.pathsep.join(include_dirs) - message = reader.format_message(\ - 'WARNING', - 'include file %r not found in %r,'\ - ' ignoring.' % (filename, dirs), - item.span[0], item.span[1]) - reader.show_message(message, sys.stdout) - return self.next(ignore_comments = ignore_comments) - message = reader.format_message('INFORMATION', - 'found file %r' % (path), - item.span[0], item.span[1]) - reader.show_message(message, sys.stdout) - self.reader = FortranFileReader(path, include_dirs = include_dirs) - return self.reader.next(ignore_comments = ignore_comments) - return item - except StopIteration: - raise - except: - message = self.format_message('FATAL ERROR', - 'while processing line', - self.linecount, self.linecount) - self.show_message(message, sys.stdout) - traceback.print_exc(file=sys.stdout) - self.show_message(red_text('STOPPED READING'), sys.stdout) - raise StopIteration - - def _next(self, ignore_comments = False): - fifo_item_pop = self.fifo_item.pop - while 1: - try: - item = fifo_item_pop(0) - except IndexError: - item = self.get_source_item() - if item is None: - raise StopIteration - if not item.isempty(ignore_comments): - break - # else ignore empty lines and comments - if not isinstance(item, Comment): - if not self.ispyf and isinstance(item, Line) \ - and not item.is_f2py_directive \ - and ';' in item.get_line(): - # ;-separator not recognized in pyf-mode - items = [] - for line in item.get_line().split(';'): - line = line.strip() - items.append(item.copy(line, apply_map=True)) - items.reverse() - for newitem in items: - self.fifo_item.insert(0, newitem) - return fifo_item_pop(0) - return item - # collect subsequent comments to one comment instance - comments = [] - start = item.span[0] - while isinstance(item, Comment): - comments.append(item.comment) - end = item.span[1] - while 1: - try: - item = fifo_item_pop(0) - except IndexError: - item = self.get_source_item() - if item is None or not item.isempty(ignore_comments): - break - if item is None: - break # hold raising StopIteration for the next call. - if item is not None: - self.fifo_item.insert(0,item) - return self.comment_item('\n'.join(comments), start, end) - - # Interface to returned items: - - def line_item(self, line, startlineno, endlineno, label, errmessage=None): - if errmessage is None: - return Line(line, (startlineno, endlineno), label, self) - return SyntaxErrorLine(line, (startlineno, endlineno), - label, self, errmessage) - - def multiline_item(self, prefix, lines, suffix, - startlineno, endlineno, errmessage=None): - if errmessage is None: - return MultiLine(prefix, lines, suffix, (startlineno, endlineno), self) - return SyntaxErrorMultiLine(prefix, lines, suffix, - (startlineno, endlineno), self, errmessage) - - def comment_item(self, comment, startlineno, endlineno): - return Comment(comment, (startlineno, endlineno), self) - - # For handling messages: - - def show_message(self, message, stream = sys.stdout): - stream.write(message+'\n') - stream.flush() - - def format_message(self, kind, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - back_index = {'warning':2,'error':3,'info':0}.get(kind.lower(),3) - r = ['%s while processing %r (mode=%r)..' % (kind, self.id, self.mode)] - for i in range(max(1,startlineno-back_index),startlineno): - r.append('%5d:%s' % (i,self.source_lines[i-1])) - for i in range(startlineno,min(endlineno+back_index,len(self.source_lines))+1): - if i==0 and not self.source_lines: - break - linenostr = '%5d:' % (i) - if i==endlineno: - sourceline = self.source_lines[i-1] - l0 = linenostr+sourceline[:startcolno] - if endcolno==-1: - l1 = sourceline[startcolno:] - l2 = '' - else: - l1 = sourceline[startcolno:endcolno] - l2 = sourceline[endcolno:] - r.append('%s%s%s <== %s' % (l0,yellow_text(l1),l2,red_text(message))) - else: - r.append(linenostr+ self.source_lines[i-1]) - return '\n'.join(r) - - def format_error_message(self, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - return self.format_message('ERROR',message, startlineno, - endlineno, startcolno, endcolno) - - def format_warning_message(self, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - return self.format_message('WARNING',message, startlineno, - endlineno, startcolno, endcolno) - - # Auxiliary methods for processing raw source lines: - - def handle_cf2py_start(self, line): - """ - f2py directives can be used only in Fortran codes. - They are ignored when used inside .pyf files. - """ - if not line or self.ispyf: return line - if self.isfix: - if line[0] in '*cC!#': - if line[1:5].lower() == 'f2py': - line = 5*' ' + line[5:] - self.f2py_comment_lines.append(self.linecount) - if self.isfix77: - return line - m = _cf2py_re.match(line) - if m: - newline = m.group('indent')+5*' '+m.group('rest') - self.f2py_comment_lines.append(self.linecount) - assert len(newline)==len(line),`newlinel,line` - return newline - return line - - def handle_inline_comment(self, line, lineno, quotechar=None): - if quotechar is None and '!' not in line and \ - '"' not in line and "'" not in line: - return line, quotechar - i = line.find('!') - put_item = self.fifo_item.append - if quotechar is None and i!=-1: - # first try a quick method - newline = line[:i] - if '"' not in newline and '\'' not in newline: - if self.isfix77 or not line[i:].startswith('!f2py'): - put_item(self.comment_item(line[i:], lineno, lineno)) - return newline, quotechar - # handle cases where comment char may be a part of a character content - #splitter = LineSplitter(line, quotechar) - #items = [item for item in splitter] - #newquotechar = splitter.quotechar - items, newquotechar = splitquote(line, quotechar) - - noncomment_items = [] - noncomment_items_append = noncomment_items.append - n = len(items) - commentline = None - for k in range(n): - item = items[k] - if isinstance(item, String) or '!' not in item: - noncomment_items_append(item) - continue - j = item.find('!') - noncomment_items_append(item[:j]) - items[k] = item[j:] - commentline = ''.join(items[k:]) - break - if commentline is not None: - if commentline.startswith('!f2py'): - # go to next iteration: - newline = ''.join(noncomment_items) + commentline[5:] - self.f2py_comment_lines.append(lineno) - return self.handle_inline_comment(newline, lineno, quotechar) - put_item(self.comment_item(commentline, lineno, lineno)) - return ''.join(noncomment_items), newquotechar - - def handle_multilines(self, line, startlineno, mlstr): - i = line.find(mlstr) - if i != -1: - prefix = line[:i] - # skip fake multiline starts - p,k = prefix,0 - while p.endswith('\\'): - p,k = p[:-1],k+1 - if k % 2: return - if i != -1 and '!' not in prefix: - # Note character constans like 'abc"""123', - # so multiline prefix should better not contain `'' or `"' not `!'. - for quote in '"\'': - if prefix.count(quote) % 2: - message = self.format_warning_message(\ - 'multiline prefix contains odd number of %r characters' \ - % (quote), startlineno, startlineno, - 0, len(prefix)) - self.show_message(message, sys.stderr) - - suffix = None - multilines = [] - line = line[i+3:] - while line is not None: - j = line.find(mlstr) - if j != -1 and '!' not in line[:j]: - multilines.append(line[:j]) - suffix = line[j+3:] - break - multilines.append(line) - line = self.get_single_line() - if line is None: - message = self.format_error_message(\ - 'multiline block never ends', startlineno, - startlineno, i) - return self.multiline_item(\ - prefix,multilines,suffix,\ - startlineno, self.linecount, message) - suffix,qc = self.handle_inline_comment(suffix, self.linecount) - # no line continuation allowed in multiline suffix - if qc is not None: - message = self.format_message(\ - 'ASSERTION FAILURE(pyf)', - 'following character continuation: %r, expected None.' % (qc), - startlineno, self.linecount) - self.show_message(message, sys.stderr) - # XXX: should we do line.replace('\\'+mlstr[0],mlstr[0]) - # for line in multilines? - return self.multiline_item(prefix,multilines,suffix, - startlineno, self.linecount) - - # The main method of interpreting raw source lines within - # the following contexts: f77, fixed f90, free f90, pyf. - - def get_source_item(self): - """ - a source item is .. - - a fortran line - - a list of continued fortran lines - - a multiline - lines inside triple-qoutes, only when in ispyf mode - """ - get_single_line = self.get_single_line - line = get_single_line() - if line is None: return - startlineno = self.linecount - line = self.handle_cf2py_start(line) - is_f2py_directive = startlineno in self.f2py_comment_lines - - label = None - if self.ispyf: - # handle multilines - for mlstr in ['"""',"'''"]: - r = self.handle_multilines(line, startlineno, mlstr) - if r: return r - - if self.isfix: - label = line[:5].strip().lower() - if label.endswith(':'): label = label[:-1].strip() - if not line.strip(): - # empty line - return self.line_item(line[6:],startlineno,self.linecount,label) - if _is_fix_comment(line): - return self.comment_item(line, startlineno, startlineno) - for i in range(5): - if line[i] not in _spacedigits: - message = 'non-space/digit char %r found in column %i'\ - ' of fixed Fortran code' % (line[i],i+1) - if self.isfix90: - message = message + ', switching to free format mode' - message = self.format_warning_message(\ - message,startlineno, self.linecount) - self.show_message(message, sys.stderr) - self.set_mode(True, False) - else: - return self.line_item(line[6:], startlineno, self.linecount, - label, self.format_error_message(\ - message, startlineno, self.linecount)) - - if self.isfix77 and not is_f2py_directive: - lines = [line[6:72]] - while _is_fix_cont(self.get_next_line()): - # handle fix format line continuations for F77 code - line = get_single_line() - lines.append(line[6:72]) - return self.line_item(''.join(lines),startlineno,self.linecount,label) - - handle_inline_comment = self.handle_inline_comment - - if self.isfix90 and not is_f2py_directive: - # handle inline comment - newline,qc = handle_inline_comment(line[6:], startlineno) - lines = [newline] - next_line = self.get_next_line() - while _is_fix_cont(next_line) or _is_fix_comment(next_line): - # handle fix format line continuations for F90 code. - # mixing fix format and f90 line continuations is not allowed - # nor detected, just eject warnings. - line2 = get_single_line() - if _is_fix_comment(line2): - # handle fix format comments inside line continuations - citem = self.comment_item(line2,self.linecount,self.linecount) - self.fifo_item.append(citem) - else: - newline, qc = self.handle_inline_comment(line2[6:], - self.linecount, qc) - lines.append(newline) - next_line = self.get_next_line() - # no character continuation should follows now - if qc is not None: - message = self.format_message(\ - 'ASSERTION FAILURE(fix90)', - 'following character continuation: %r, expected None.'\ - % (qc), startlineno, self.linecount) - self.show_message(message, sys.stderr) - if len(lines)>1: - for i in range(len(lines)): - l = lines[i] - if l.rstrip().endswith('&'): - message = self.format_warning_message(\ - 'f90 line continuation character `&\' detected'\ - ' in fix format code', - startlineno + i, startlineno + i, l.rfind('&')+5) - self.show_message(message, sys.stderr) - return self.line_item(''.join(lines),startlineno, - self.linecount,label) - start_index = 0 - if self.isfix90: - start_index = 6 - - lines = [] - lines_append = lines.append - put_item = self.fifo_item.append - qc = None - while line is not None: - if start_index: # fix format code - line,qc = handle_inline_comment(line[start_index:], - self.linecount,qc) - is_f2py_directive = self.linecount in self.f2py_comment_lines - else: - line_lstrip = line.lstrip() - if lines: - if line_lstrip.startswith('!'): - # check for comment line within line continuation - put_item(self.comment_item(line_lstrip, - self.linecount, self.linecount)) - line = get_single_line() - continue - else: - # first line, check for a f90 label - m = _f90label_re.match(line) - if m: - assert not label,`label,m.group('label')` - label = m.group('label').strip() - if label.endswith(':'): label = label[:-1].strip() - if not self.ispyf: label = label.lower() - line = line[m.end():] - line,qc = handle_inline_comment(line, self.linecount, qc) - is_f2py_directive = self.linecount in self.f2py_comment_lines - - i = line.rfind('&') - if i!=-1: - line_i1_rstrip = line[i+1:].rstrip() - if not lines: - # first line - if i == -1 or line_i1_rstrip: - lines_append(line) - break - lines_append(line[:i]) - line = get_single_line() - continue - if i == -1 or line_i1_rstrip: - # no line continuation follows - i = len(line) - k = -1 - if i != -1: - # handle the beggining of continued line - k = line[:i].find('&') - if k != 1 and line[:k].lstrip(): - k = -1 - lines_append(line[k+1:i]) - if i==len(line): - break - line = get_single_line() - - if qc is not None: - message = self.format_message('ASSERTION FAILURE(free)', - 'following character continuation: %r, expected None.' % (qc), - startlineno, self.linecount) - self.show_message(message, sys.stderr) - return self.line_item(''.join(lines),startlineno,self.linecount,label) - - ## FortranReaderBase - -# Fortran file and string readers: - -class FortranFileReader(FortranReaderBase): - - def __init__(self, filename, - include_dirs = None): - isfree, isstrict = get_source_info(filename) - self.id = filename - self.file = open(filename,'r') - FortranReaderBase.__init__(self, self.file, isfree, isstrict) - if include_dirs is None: - self.include_dirs.insert(0, os.path.dirname(filename)) - else: - self.include_dirs = include_dirs[:] - return - - def close_source(self): - self.file.close() - -class FortranStringReader(FortranReaderBase): - - def __init__(self, string, isfree, isstrict): - self.id = 'string-'+str(id(string)) - source = StringIO(string) - FortranReaderBase.__init__(self, source, isfree, isstrict) - -# Testing: - -def test_f77(): - string_f77 = """ -c12346 comment - subroutine foo - call foo - 'bar -a 'g - abc=2 -cf2py call me ! hey - call you ! hi - end - '""" - reader = FortranStringReader(string_f77,False,True) - for item in reader: - print item - - filename = tempfile.mktemp()+'.f' - f = open(filename,'w') - f.write(string_f77) - f.close() - - reader = FortranFileReader(filename) - for item in reader: - print item - -def test_pyf(): - string_pyf = """\ -python module foo - interface - beginml '''1st line - 2nd line - end line'''endml='tere!fake comment'!should be a comment - a = 2 - 'charc\"onstant' ''' single line mline '''a='hi!fake comment'!should be a comment - a=\\\\\\\\\\'''not a multiline''' - !blah='''never ending multiline - b=3! hey, fake line continuation:& - c=4& !line cont - &45 - thisis_label_2 : c = 3 - xxif_isotropic_2 : if ( string_upper_compare ( o%opt_aniso, 'ISOTROPIC' ) ) then - g=3 - endif - end interface - if ( pc_get_lun() .ne. 6) & - - write ( pc_get_lun(), '( & - & /, a, /, " p=", i4, " stopping c_flag=", a, & - & /, " print unit=", i8)') & - trim(title), pcpsx_i_pel(), trim(c_flag), pc_get_lun() -end python module foo -! end of file -""" - reader = FortranStringReader(string_pyf,True, True) - for item in reader: - print item - -def test_fix90(): - string_fix90 = """\ - subroutine foo -cComment - 1234 a = 3 !inline comment - b = 3 -! - !4!line cont. with comment symbol - &5 - a = 3!f2py.14 ! pi! -! KDMO - write (obj%print_lun, *) ' KDMO : ' - write (obj%print_lun, *) ' COORD = ',coord, ' BIN_WID = ', & - obj%bin_wid,' VEL_DMO = ', obj%vel_dmo - end subroutine foo - subroutine - - & foo - end -""" - reader = FortranStringReader(string_fix90,False, False) - for item in reader: - print item - -def simple_main(): - for filename in sys.argv[1:]: - print 'Processing',filename - reader = FortranFileReader(filename) - for item in reader: - print >> sys.stdout, item - sys.stdout.flush() - pass - -def profile_main(): - import hotshot, hotshot.stats - prof = hotshot.Profile("readfortran.prof") - prof.runcall(simple_main) - prof.close() - stats = hotshot.stats.load("readfortran.prof") - stats.strip_dirs() - stats.sort_stats('time', 'calls') - stats.print_stats(30) - -if __name__ == "__main__": - #test_pyf() - #test_fix90() - #profile_main() - simple_main() diff --git a/numpy/f2py/lib/research/rat/main.c b/numpy/f2py/lib/research/rat/main.c deleted file mode 100644 index 007c24807..000000000 --- a/numpy/f2py/lib/research/rat/main.c +++ /dev/null @@ -1,38 +0,0 @@ - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -typedef void* obj_type; -typedef obj_type (*rat_create_func)(void); -typedef obj_type (*rat_add_func)(obj_type, obj_type); -typedef void (*rat_show_func)(obj_type); -typedef void (*rat_set_func)(obj_type, int*, int*); - -static void** rational_funcs; - -static void set_f90_funcs2(int* n,...) { - int i; - va_list ap; - //printf("In set_f90_funcs n=%d\n",(*n)); - va_start(ap,n); - rational_funcs = (void*)malloc((*n)*sizeof(void*)); - for (i=0;i<(*n);i++) - rational_funcs[i] = va_arg(ap,void*); - va_end(ap); -} - -int main(void) { - init_f90_funcs_(set_f90_funcs2); - rat_create_func rat_create = rational_funcs[0]; - rat_show_func rat_show = rational_funcs[1]; - rat_set_func rat_set = rational_funcs[2]; - rat_add_func rat_add = rational_funcs[3]; - - obj_type obj_ptr = NULL; - obj_ptr = (*rat_create)(); - int n=2,d=3; - (*rat_set)(obj_ptr, &n, &d); - (*rat_show)(obj_ptr); - (*rat_show)((*rat_add)(obj_ptr,obj_ptr)); -} diff --git a/numpy/f2py/lib/research/rat/main.f90 b/numpy/f2py/lib/research/rat/main.f90 deleted file mode 100644 index d222318ab..000000000 --- a/numpy/f2py/lib/research/rat/main.f90 +++ /dev/null @@ -1,16 +0,0 @@ - -program a - - use rational - - type(rat_struct), pointer :: r - - r => rat_create() - - print*,r - - call rat_set(r, 3,4) - - call rat_show(r) - -end program a diff --git a/numpy/f2py/lib/research/rat/rational.f90 b/numpy/f2py/lib/research/rat/rational.f90 deleted file mode 100644 index 9cbc57e15..000000000 --- a/numpy/f2py/lib/research/rat/rational.f90 +++ /dev/null @@ -1,44 +0,0 @@ - -module rational - - implicit none - - type, public :: rat_struct - integer :: numer ! numerator - integer :: denom ! denominator - end type rat_struct - - contains - - function rat_create() result (obj) - type(rat_struct), pointer :: obj - print*,'In rat_create' - allocate(obj) - call rat_set(obj, 0, 1) - end function rat_create - - subroutine rat_set(obj, n, d) - type(rat_struct) :: obj - integer :: n,d - print*,'In rat_set' - obj % numer = n - obj % denom = d - end subroutine rat_set - - subroutine rat_show(obj) - type(rat_struct) :: obj - print*,'In rat_show' - print*, "object numer,denom = ",obj % numer, obj % denom - end subroutine rat_show - - function rat_add(a,b) result (ab) - type(rat_struct), pointer :: ab - type(rat_struct) :: a,b - allocate(ab) - ab % numer = a % numer * b % denom + b % numer * a % denom - ab % denom = a % denom * b % denom - end function rat_add - -end module rational - - diff --git a/numpy/f2py/lib/research/rat/wrap.f90 b/numpy/f2py/lib/research/rat/wrap.f90 deleted file mode 100644 index 6c9da8491..000000000 --- a/numpy/f2py/lib/research/rat/wrap.f90 +++ /dev/null @@ -1,5 +0,0 @@ -subroutine init_f90_funcs(set_f90_funcs) - use rational - external set_f90_funcs - call set_f90_funcs(4, rat_create, rat_show, rat_set, rat_add) -end subroutine init_f90_funcs diff --git a/numpy/f2py/lib/sourceinfo.py b/numpy/f2py/lib/sourceinfo.py deleted file mode 100644 index 65b90ca21..000000000 --- a/numpy/f2py/lib/sourceinfo.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 -""" - -__all__ = ['get_source_info'] -import re -import os -import sys - -_has_f_extension = re.compile(r'.*[.](for|ftn|f77|f)\Z',re.I).match -_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-',re.I).search -_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-',re.I).search -_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-',re.I).search -_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]',re.I).match - -def get_source_info(filename): - """ - Determine if fortran file is - - in fix format and contains Fortran 77 code -> False, True - - in fix format and contains Fortran 90 code -> False, False - - in free format and contains Fortran 90 code -> True, False - - in free format and contains signatures (.pyf) -> True, True - """ - base,ext = os.path.splitext(filename) - if ext=='.pyf': - return True, True - isfree = False - isstrict = False - f = open(filename,'r') - firstline = f.readline() - f.close() - if _has_f_extension(filename) and \ - not (_has_f90_header(firstline) or _has_fix_header(firstline)): - isstrict = True - elif is_free_format(filename) and not _has_fix_header(firstline): - isfree = True - return isfree,isstrict - -def is_free_format(file): - """Check if file is in free format Fortran.""" - # f90 allows both fixed and free format, assuming fixed unless - # signs of free format are detected. - isfree = False - f = open(file,'r') - line = f.readline() - n = 10000 # the number of non-comment lines to scan for hints - if _has_f_header(line): - n = 0 - elif _has_f90_header(line): - n = 0 - isfree = True - contline = False - while n>0 and line: - line = line.rstrip() - if line and line[0]!='!': - n -= 1 - if line[0]!='\t' and _free_f90_start(line[:5]) or line[-1:]=='&': - isfree = True - break - line = f.readline() - f.close() - return isfree - -def simple_main(): - for filename in sys.argv[1:]: - isfree, isstrict = get_source_info(filename) - print '%s: isfree=%s, isstrict=%s' % (filename, isfree, isstrict) - -if __name__ == '__main__': - simple_main() diff --git a/numpy/f2py/lib/splitline.py b/numpy/f2py/lib/splitline.py deleted file mode 100644 index 1bbd77b6e..000000000 --- a/numpy/f2py/lib/splitline.py +++ /dev/null @@ -1,415 +0,0 @@ -#!/usr/bin/env python -""" -Defines LineSplitter and helper functions. - -Copyright 2006 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@cens.ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the LGPL. See http://www.fsf.org - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Revision:$ -$Date: 2000/07/31 07:04:03 $ -Pearu Peterson -""" - -__all__ = ['String','string_replace_map','splitquote','splitparen'] - -import re - -class String(str): pass -class ParenString(str): pass - -def split2(line, lower=False): - """ - Split line into non-string part and into a start of a string part. - Returns 2-tuple. The second item either is empty string or start - of a string part. - """ - return LineSplitter(line,lower=lower).split2() - -_f2py_str_findall = re.compile(r"_F2PY_STRING_CONSTANT_\d+_").findall -_is_name = re.compile(r'\w*\Z',re.I).match -_is_simple_str = re.compile(r'\w*\Z',re.I).match - -def string_replace_map(line, lower=False, - _cache={'index':0,'pindex':0}): - """ - 1) Replaces string constants with symbol `'_F2PY_STRING_CONSTANT_<index>_'` - 2) Replaces (expression) with symbol `(F2PY_EXPR_TUPLE_<index>)` - Returns a new line and the replacement map. - """ - items = [] - string_map = {} - rev_string_map = {} - for item in splitquote(line, lower=lower)[0]: - if isinstance(item, String) and not _is_simple_str(item[1:-1]): - key = rev_string_map.get(item) - if key is None: - _cache['index'] += 1 - index = _cache['index'] - key = "_F2PY_STRING_CONSTANT_%s_" % (index) - it = item[1:-1] - string_map[key] = it - rev_string_map[it] = key - items.append(item[0]+key+item[-1]) - else: - items.append(item) - newline = ''.join(items) - items = [] - expr_keys = [] - for item in splitparen(newline): - if isinstance(item, ParenString) and not _is_name(item[1:-1]): - key = rev_string_map.get(item) - if key is None: - _cache['pindex'] += 1 - index = _cache['pindex'] - key = 'F2PY_EXPR_TUPLE_%s' % (index) - it = item[1:-1].strip() - string_map[key] = it - rev_string_map[it] = key - expr_keys.append(key) - items.append(item[0]+key+item[-1]) - else: - items.append(item) - found_keys = set() - for k in expr_keys: - v = string_map[k] - l = _f2py_str_findall(v) - if l: - found_keys = found_keys.union(l) - for k1 in l: - v = v.replace(k1, string_map[k1]) - string_map[k] = v - for k in found_keys: - del string_map[k] - return ''.join(items), string_map - -def splitquote(line, stopchar=None, lower=False, quotechars = '"\''): - """ - Fast LineSplitter - """ - items = [] - i = 0 - while 1: - try: - char = line[i]; i += 1 - except IndexError: - break - l = [] - l_append = l.append - nofslashes = 0 - if stopchar is None: - # search for string start - while 1: - if char in quotechars and not nofslashes % 2: - stopchar = char - i -= 1 - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - if not l: continue - item = ''.join(l) - if lower: item = item.lower() - items.append(item) - continue - if char==stopchar: - # string starts with quotechar - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - if l: - item = String(''.join(l)) - items.append(item) - break - # else continued string - while 1: - if char==stopchar and not nofslashes % 2: - l_append(char) - stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - if l: - item = String(''.join(l)) - items.append(item) - return items, stopchar - -class LineSplitterBase: - - def __iter__(self): - return self - - def next(self): - item = '' - while not item: - item = self.get_item() # get_item raises StopIteration - return item - -class LineSplitter(LineSplitterBase): - """ Splits a line into non strings and strings. E.g. - abc=\"123\" -> ['abc=','\"123\"'] - Handles splitting lines with incomplete string blocks. - """ - def __init__(self, line, - quotechar = None, - lower=False, - ): - self.fifo_line = [c for c in line] - self.fifo_line.reverse() - self.quotechar = quotechar - self.lower = lower - - def split2(self): - """ - Split line until the first start of a string. - """ - try: - item1 = self.get_item() - except StopIteration: - return '','' - i = len(item1) - l = self.fifo_line[:] - l.reverse() - item2 = ''.join(l) - return item1,item2 - - def get_item(self): - fifo_pop = self.fifo_line.pop - try: - char = fifo_pop() - except IndexError: - raise StopIteration - fifo_append = self.fifo_line.append - quotechar = self.quotechar - l = [] - l_append = l.append - - nofslashes = 0 - if quotechar is None: - # search for string start - while 1: - if char in '"\'' and not nofslashes % 2: - self.quotechar = char - fifo_append(char) - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - item = ''.join(l) - if self.lower: item = item.lower() - return item - - if char==quotechar: - # string starts with quotechar - l_append(char) - try: - char = fifo_pop() - except IndexError: - return String(''.join(l)) - # else continued string - while 1: - if char==quotechar and not nofslashes % 2: - l_append(char) - self.quotechar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - return String(''.join(l)) - -def splitparen(line,paren='()'): - """ - Fast LineSplitterParen. - """ - stopchar = None - startchar, endchar = paren[0],paren[1] - - items = [] - i = 0 - while 1: - try: - char = line[i]; i += 1 - except IndexError: - break - nofslashes = 0 - l = [] - l_append = l.append - if stopchar is None: - # search for parenthesis start - while 1: - if char==startchar and not nofslashes % 2: - stopchar = endchar - i -= 1 - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - item = ''.join(l) - else: - nofstarts = 0 - while 1: - if char==stopchar and not nofslashes % 2 and nofstarts==1: - l_append(char) - stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - if char==startchar: - nofstarts += 1 - elif char==endchar: - nofstarts -= 1 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - item = ParenString(''.join(l)) - items.append(item) - return items - -class LineSplitterParen(LineSplitterBase): - """ Splits a line into strings and strings with parenthesis. E.g. - a(x) = b(c,d) -> ['a','(x)',' = b','(c,d)'] - """ - def __init__(self, line, paren = '()'): - self.fifo_line = [c for c in line] - self.fifo_line.reverse() - self.startchar = paren[0] - self.endchar = paren[1] - self.stopchar = None - - def get_item(self): - fifo_pop = self.fifo_line.pop - try: - char = fifo_pop() - except IndexError: - raise StopIteration - fifo_append = self.fifo_line.append - startchar = self.startchar - endchar = self.endchar - stopchar = self.stopchar - l = [] - l_append = l.append - - nofslashes = 0 - if stopchar is None: - # search for parenthesis start - while 1: - if char==startchar and not nofslashes % 2: - self.stopchar = endchar - fifo_append(char) - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - item = ''.join(l) - return item - - nofstarts = 0 - while 1: - if char==stopchar and not nofslashes % 2 and nofstarts==1: - l_append(char) - self.stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - if char==startchar: - nofstarts += 1 - elif char==endchar: - nofstarts -= 1 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - return ParenString(''.join(l)) - -def test(): - splitter = LineSplitter('abc\\\' def"12\\"3""56"dfad\'a d\'') - l = [item for item in splitter] - assert l==['abc\\\' def','"12\\"3"','"56"','dfad','\'a d\''],`l` - assert splitter.quotechar is None - l,stopchar=splitquote('abc\\\' def"12\\"3""56"dfad\'a d\'') - assert l==['abc\\\' def','"12\\"3"','"56"','dfad','\'a d\''],`l` - assert stopchar is None - - splitter = LineSplitter('"abc123&') - l = [item for item in splitter] - assert l==['"abc123&'],`l` - assert splitter.quotechar=='"' - l,stopchar = splitquote('"abc123&') - assert l==['"abc123&'],`l` - assert stopchar=='"' - - splitter = LineSplitter(' &abc"123','"') - l = [item for item in splitter] - assert l==[' &abc"','123'] - assert splitter.quotechar is None - l,stopchar = splitquote(' &abc"123','"') - assert l==[' &abc"','123'] - assert stopchar is None - - l = split2('') - assert l==('',''),`l` - l = split2('12') - assert l==('12',''),`l` - l = split2('1"a"//"b"') - assert l==('1','"a"//"b"'),`l` - l = split2('"ab"') - assert l==('','"ab"'),`l` - - splitter = LineSplitterParen('a(b) = b(x,y(1)) b\((a)\)') - l = [item for item in splitter] - assert l==['a', '(b)', ' = b', '(x,y(1))', ' b\\(', '(a)', '\\)'],`l` - l = splitparen('a(b) = b(x,y(1)) b\((a)\)') - assert l==['a', '(b)', ' = b', '(x,y(1))', ' b\\(', '(a)', '\\)'],`l` - - l = string_replace_map('a()') - print l -if __name__ == '__main__': - test() - diff --git a/numpy/f2py/lib/statements.py b/numpy/f2py/lib/statements.py deleted file mode 100644 index b3bd34e51..000000000 --- a/numpy/f2py/lib/statements.py +++ /dev/null @@ -1,1818 +0,0 @@ - -import re -import sys - -from base_classes import Statement, Variable -#from expression import Expression - -# Auxiliary tools - -from utils import split_comma, specs_split_comma, AnalyzeError, ParseError,\ - get_module_file, parse_bind, parse_result, is_name - -class StatementWithNamelist(Statement): - """ - <statement> [ :: ] <name-list> - """ - def process_item(self): - if self.item.has_map(): - self.isvalid = False - return - if hasattr(self,'stmtname'): - clsname = self.stmtname - else: - clsname = self.__class__.__name__ - line = self.item.get_line()[len(clsname):].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = items = [] - for item in split_comma(line): - if not is_name(item): - self.isvalid = False - return - items.append(item) - return - def __str__(self): - if hasattr(self,'stmtname'): - clsname = self.stmtname.upper() - else: - clsname = self.__class__.__name__.upper() - s = ', '.join(self.items) - if s: - s = ' ' + s - return self.get_indent_tab() + clsname + s - -# Execution statements - -class GeneralAssignment(Statement): - """ - <variable> = <expr> - <pointer variable> => <expr> - """ - - match = re.compile(r'\w[^=]*\s*=\>?').match - item_re = re.compile(r'(?P<variable>\w[^=]*)\s*(?P<sign>=\>?)\s*(?P<expr>.*)\Z',re.I).match - - def process_item(self): - m = self.item_re(self.item.get_line()) - if not m: - self.isvalid = False - return - self.sign = sign = m.group('sign') - if isinstance(self, Assignment) and sign != '=': - self.isvalid = False - return - elif isinstance(self, PointerAssignment) and sign != '=>': - self.isvalid = False - return - else: - if sign=='=>': - self.__class__ = PointerAssignment - else: - self.__class__ = Assignment - apply_map = self.item.apply_map - self.variable = apply_map(m.group('variable').replace(' ','')) - self.expr = apply_map(m.group('expr')) - return - - def __str__(self): - return self.get_indent_tab() + '%s %s %s' \ - % (self.variable, self.sign, self.expr) - - def analyze(self): return - -class Assignment(GeneralAssignment): - pass - -class PointerAssignment(GeneralAssignment): - pass - -class Assign(Statement): - """ - ASSIGN <label> TO <int-variable-name> - """ - modes = ['fix77'] - match = re.compile(r'assign\s*\d+\s*to\s*\w+\s*\Z',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.lower().find('to') - assert not self.item.has_map() - self.items = [line[:i].rstrip(),line[i+2:].lstrip()] - return - def __str__(self): - return self.get_indent_tab() + 'ASSIGN %s TO %s' \ - % (self.items[0], self.items[1]) - def analyze(self): return - -class Call(Statement): - """Call statement class - CALL <procedure-designator> [ ( [ <actual-arg-spec-list> ] ) ] - - <procedure-designator> = <procedure-name> - | <proc-component-ref> - | <data-ref> % <binding-name> - - <actual-arg-spec> = [ <keyword> = ] <actual-arg> - <actual-arg> = <expr> - | <variable> - | <procedure-name> - | <proc-component-ref> - | <alt-return-spec> - <alt-return-spec> = * <label> - - <proc-component-ref> = <variable> % <procedure-component-name> - - <variable> = <designator> - - Call instance has attributes: - designator - arg_list - """ - match = re.compile(r'call\b', re.I).match - - def process_item(self): - item = self.item - apply_map = item.apply_map - line = item.get_line()[4:].strip() - i = line.find('(') - items = [] - if i==-1: - self.designator = apply_map(line).strip() - else: - j = line.find(')') - if j == -1 or len(line)-1 != j: - self.isvalid = False - return - self.designator = apply_map(line[:i]).strip() - items = split_comma(line[i+1:-1], item) - self.items = items - return - - def __str__(self): - s = self.get_indent_tab() + 'CALL '+str(self.designator) - if self.items: - s += '('+', '.join(map(str,self.items))+ ')' - return s - - def analyze(self): - a = self.programblock.a - if hasattr(a, 'external'): - external = a.external - if self.designator in external: - print 'Need to analyze:',self - return - -class Goto(Statement): - """ - GO TO <label> - """ - match = re.compile(r'go\s*to\s*\d+\s*\Z', re.I).match - - def process_item(self): - assert not self.item.has_map() - self.label = self.item.get_line()[2:].lstrip()[2:].lstrip() - return - - def __str__(self): - return self.get_indent_tab() + 'GO TO %s' % (self.label) - def analyze(self): return - -class ComputedGoto(Statement): - """ - GO TO ( <label-list> ) [ , ] <scalar-int-expr> - """ - match = re.compile(r'go\s*to\s*\(',re.I).match - def process_item(self): - apply_map = self.item.apply_map - line = self.item.get_line()[2:].lstrip()[2:].lstrip() - i = line.index(')') - self.items = split_comma(line[1:i], self.item) - line = line[i+1:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - self.expr = apply_map(line) - return - def __str__(self): - return self.get_indent_tab() + 'GO TO (%s) %s' \ - % (', '.join(self.items), self.expr) - def analyze(self): return - -class AssignedGoto(Statement): - """ - GO TO <int-variable-name> [ ( <label> [ , <label> ]... ) ] - """ - modes = ['fix77'] - match = re.compile(r'go\s*to\s*\w+\s*\(?',re.I).match - def process_item(self): - line = self.item.get_line()[2:].lstrip()[2:].lstrip() - i = line.find('(') - if i==-1: - self.varname = line - self.items = [] - return - self.varname = line[:i].rstrip() - assert line[-1]==')',`line` - self - self.items = split_comma(line[i+1:-1], self.item) - return - - def __str__(self): - tab = self.get_indent_tab() - if self.items: - return tab + 'GO TO %s (%s)' \ - % (self.varname, ', '.join(self.items)) - return tab + 'GO TO %s' % (self.varname) - def analyze(self): return - -class Continue(Statement): - """ - CONTINUE - """ - match = re.compile(r'continue\Z',re.I).match - - def process_item(self): - self.label = self.item.label - return - - def __str__(self): - return self.get_indent_tab(deindent=True) + 'CONTINUE' - - def analyze(self): return - -class Return(Statement): - """ - RETURN [ <scalar-int-expr> ] - """ - match = re.compile(r'return\b',re.I).match - - def process_item(self): - self.expr = self.item.apply_map(self.item.get_line()[6:].lstrip()) - return - - def __str__(self): - tab = self.get_indent_tab() - if self.expr: - return tab + 'RETURN %s' % (self.expr) - return tab + 'RETURN' - - def analyze(self): return - -class Stop(Statement): - """ - STOP [ <stop-code> ] - <stop-code> = <scalar-char-constant> | <1-5-digit> - """ - match = re.compile(r'stop\s*(\'\w*\'|"\w*"|\d+|)\Z',re.I).match - - def process_item(self): - self.code = self.item.apply_map(self.item.get_line()[4:].lstrip()) - return - - def __str__(self): - tab = self.get_indent_tab() - if self.code: - return tab + 'STOP %s' % (self.code) - return tab + 'STOP' - - def analyze(self): return - -class Print(Statement): - """ - PRINT <format> [, <output-item-list>] - <format> = <default-char-expr> | <label> | * - - <output-item> = <expr> | <io-implied-do> - <io-implied-do> = ( <io-implied-do-object-list> , <implied-do-control> ) - <io-implied-do-object> = <input-item> | <output-item> - <implied-do-control> = <do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] - <input-item> = <variable> | <io-implied-do> - """ - match = re.compile(r'print\s*(\'\w*\'|\"\w*\"|\d+|[*]|\b\w)', re.I).match - - def process_item(self): - item = self.item - apply_map = item.apply_map - line = item.get_line()[5:].lstrip() - items = split_comma(line, item) - self.format = items[0] - self.items = items[1:] - return - - def __str__(self): - return self.get_indent_tab() + 'PRINT %s' \ - % (', '.join([self.format]+self.items)) - def analyze(self): return - -class Read(Statement): - """ -Read0: READ ( <io-control-spec-list> ) [ <input-item-list> ] - - <io-control-spec-list> = [ UNIT = ] <io-unit> - | [ FORMAT = ] <format> - | [ NML = ] <namelist-group-name> - | ADVANCE = <scalar-default-char-expr> - ... - -Read1: READ <format> [, <input-item-list>] - <format> == <default-char-expr> | <label> | * - """ - match = re.compile(r'read\b\s*[\w(*\'"]', re.I).match - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - if line.startswith('('): - self.__class__ = Read0 - else: - self.__class__ = Read1 - self.process_item() - return - def analyze(self): return - -class Read0(Read): - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - i = line.find(')') - self.specs = specs_split_comma(line[1:i], item) - self.items = split_comma(line[i+1:], item) - return - - def __str__(self): - s = self.get_indent_tab() + 'READ (%s)' % (', '.join(self.specs)) - if self.items: - return s + ' ' + ', '.join(self.items) - return s - -class Read1(Read): - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - items = split_comma(line, item) - self.format = items[0] - self.items = items[1:] - return - - def __str__(self): - return self.get_indent_tab() + 'READ ' \ - + ', '.join([self.format]+self.items) - -class Write(Statement): - """ - WRITE ( io-control-spec-list ) [<output-item-list>] - """ - match = re.compile(r'write\s*\(', re.I).match - def process_item(self): - item = self.item - line = item.get_line()[5:].lstrip() - i = line.find(')') - assert i != -1, `line` - self.specs = specs_split_comma(line[1:i], item) - self.items = split_comma(line[i+1:], item) - return - - def __str__(self): - s = self.get_indent_tab() + 'WRITE (%s)' % ', '.join(self.specs) - if self.items: - s += ' ' + ', '.join(self.items) - return s - def analyze(self): return - - -class Flush(Statement): - """ - FLUSH <file-unit-number> - FLUSH ( <flush-spec-list> ) - <flush-spec> = [ UNIT = ] <file-unit-number> - | IOSTAT = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | ERR = <label> - """ - match = re.compile(r'flush\b',re.I).match - - def process_item(self): - line = self.item.get_line()[5:].lstrip() - if not line: - self.isvalid = False - return - if line.startswith('('): - assert line[-1] == ')', `line` - self.specs = specs_split_comma(line[1:-1],self.item) - else: - self.specs = specs_split_comma(line,self.item) - return - - def __str__(self): - tab = self.get_indent_tab() - return tab + 'FLUSH (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Wait(Statement): - """ - WAIT ( <wait-spec-list> ) - <wait-spec> = [ UNIT = ] <file-unit-number> - | END = <label> - | EOR = <label> - | ERR = <label> - | ID = <scalar-int-expr> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - - """ - match = re.compile(r'wait\s*\(.*\)\Z',re.I).match - def process_item(self): - self.specs = specs_split_comma(\ - self.item.get_line()[4:].lstrip()[1:-1], self.item) - return - def __str__(self): - tab = self.get_indent_tab() - return tab + 'WAIT (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Contains(Statement): - """ - CONTAINS - """ - match = re.compile(r'contains\Z',re.I).match - def process_item(self): return - def __str__(self): return self.get_indent_tab() + 'CONTAINS' - -class Allocate(Statement): - """ - ALLOCATE ( [ <type-spec> :: ] <allocation-list> [ , <alloc-opt-list> ] ) - <alloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - | SOURCE = <source-expr> - <allocation> = <allocate-object> [ ( <allocate-shape-spec-list> ) ] - """ - match = re.compile(r'allocate\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[8:].lstrip()[1:-1].strip() - item2 = self.item.copy(line, True) - line2 = item2.get_line() - i = line2.find('::') - if i != -1: - spec = item2.apply_map(line2[:i].rstrip()) - from block_statements import type_spec - stmt = None - for cls in type_spec: - if cls.match(spec): - stmt = cls(self, item2.copy(spec)) - if stmt.isvalid: - break - if stmt is not None and stmt.isvalid: - spec = stmt - else: - self.warning('TODO: unparsed type-spec' + `spec`) - line2 = line2[i+2:].lstrip() - else: - spec = None - self.spec = spec - self.items = specs_split_comma(line2, item2) - return - - def __str__(self): - t = '' - if self.spec: - t = self.spec.tostr() + ' :: ' - return self.get_indent_tab() \ - + 'ALLOCATE (%s%s)' % (t,', '.join(self.items)) - def analyze(self): return - -class Deallocate(Statement): - """ - DEALLOCATE ( <allocate-object-list> [ , <dealloc-opt-list> ] ) - <allocate-object> = <variable-name> - | <structure-component> - <structure-component> = <data-ref> - <dealloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - """ - match = re.compile(r'deallocate\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[10:].lstrip()[1:-1].strip() - self.items = specs_split_comma(line, self.item) - return - def __str__(self): return self.get_indent_tab() \ - + 'DEALLOCATE (%s)' % (', '.join(self.items)) - def analyze(self): return - -class ModuleProcedure(Statement): - """ - [ MODULE ] PROCEDURE <procedure-name-list> - """ - match = re.compile(r'(module\s*|)procedure\b',re.I).match - def process_item(self): - line = self.item.get_line() - m = self.match(line) - assert m,`line` - items = split_comma(line[m.end():].strip(), self.item) - for n in items: - if not is_name(n): - self.isvalid = False - return - self.items = items - return - - def __str__(self): - tab = self.get_indent_tab() - return tab + 'MODULE PROCEDURE %s' % (', '.join(self.items)) - - def analyze(self): - module_procedures = self.parent.a.module_procedures - module_procedures.extend(self.items) - return - -class Access(Statement): - """ - <access-spec> [ [::] <access-id-list>] - <access-spec> = PUBLIC | PRIVATE - <access-id> = <use-name> | <generic-spec> - """ - match = re.compile(r'(public|private)\b',re.I).match - def process_item(self): - clsname = self.__class__.__name__.lower() - line = self.item.get_line() - if not line.lower().startswith(clsname): - self.isvalid = False - return - line = line[len(clsname):].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - - def __str__(self): - clsname = self.__class__.__name__.upper() - tab = self.get_indent_tab() - if self.items: - return tab + clsname + ' ' + ', '.join(self.items) - return tab + clsname - - def analyze(self): - clsname = self.__class__.__name__.upper() - if self.items: - for name in self.items: - var = self.get_variable(name) - var.update(clsname) - else: - self.parent.a.attributes.append(clsname) - return - -class Public(Access): - is_public = True -class Private(Access): - is_public = False - -class Close(Statement): - """ - CLOSE ( <close-spec-list> ) - <close-spec> = [ UNIT = ] <file-unit-number> - | IOSTAT = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | ERR = <label> - | STATUS = <scalar-default-char-expr> - """ - match = re.compile(r'close\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip()[1:-1].strip() - self.specs = specs_split_comma(line, self.item) - return - def __str__(self): - tab = self.get_indent_tab() - return tab + 'CLOSE (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Cycle(Statement): - """ - CYCLE [ <do-construct-name> ] - """ - match = re.compile(r'cycle\b\s*\w*\s*\Z',re.I).match - def process_item(self): - self.name = self.item.get_line()[5:].lstrip() - return - def __str__(self): - if self.name: - return self.get_indent_tab() + 'CYCLE ' + self.name - return self.get_indent_tab() + 'CYCLE' - def analyze(self): return - -class FilePositioningStatement(Statement): - """ - REWIND <file-unit-number> - REWIND ( <position-spec-list> ) - <position-spec-list> = [ UNIT = ] <file-unit-number> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | ERR = <label> - The same for BACKSPACE, ENDFILE. - """ - match = re.compile(r'(rewind|backspace|endfile)\b',re.I).match - - def process_item(self): - clsname = self.__class__.__name__.lower() - line = self.item.get_line() - if not line.lower().startswith(clsname): - self.isvalid = False - return - line = line[len(clsname):].lstrip() - if line.startswith('('): - assert line[-1]==')',`line` - spec = line[1:-1].strip() - else: - spec = line - self.specs = specs_split_comma(spec, self.item) - return - - def __str__(self): - clsname = self.__class__.__name__.upper() - return self.get_indent_tab() + clsname + ' (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Backspace(FilePositioningStatement): pass - -class Endfile(FilePositioningStatement): pass - -class Rewind(FilePositioningStatement): pass - -class Open(Statement): - """ - OPEN ( <connect-spec-list> ) - <connect-spec> = [ UNIT = ] <file-unit-number> - | ACCESS = <scalar-default-char-expr> - | .. - """ - match = re.compile(r'open\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[4:].lstrip()[1:-1].strip() - self.specs = specs_split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'OPEN (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Format(Statement): - """ - FORMAT <format-specification> - <format-specification> = ( [ <format-item-list> ] ) - <format-item> = [ <r> ] <data-edit-descr> - | <control-edit-descr> - | <char-string-edit-descr> - | [ <r> ] ( <format-item-list> ) - <data-edit-descr> = I <w> [ . <m> ] - | B <w> [ . <m> ] - ... - <r|w|m|d|e> = <int-literal-constant> - <v> = <signed-int-literal-constant> - <control-edit-descr> = <position-edit-descr> - | [ <r> ] / - | : - ... - <position-edit-descr> = T <n> - | TL <n> - ... - <sign-edit-descr> = SS | SP | S - ... - - """ - match = re.compile(r'format\s*\(.*\)\Z', re.I).match - def process_item(self): - item = self.item - if not item.label: - # R1001: - self.warning('R1001: FORMAT statement must be labeled but got %r.' \ - % (item.label)) - line = item.get_line()[6:].lstrip() - assert line[0]+line[-1]=='()',`line` - self.specs = split_comma(line[1:-1], item) - return - def __str__(self): - return self.get_indent_tab() + 'FORMAT (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Save(Statement): - """ - SAVE [ [ :: ] <saved-entity-list> ] - <saved-entity> = <object-name> - | <proc-pointer-name> - | / <common-block-name> / - <proc-pointer-name> = <name> - <object-name> = <name> - """ - match = re.compile(r'save\b',re.I).match - def process_item(self): - assert not self.item.has_map() - line = self.item.get_line()[4:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - items = [] - for s in line.split(','): - s = s.strip() - if not s: continue - if s.startswith('/'): - assert s.endswith('/'),`s` - n = s[1:-1].strip() - assert is_name(n),`n` - items.append('/%s/' % (n)) - elif is_name(s): - items.append(s) - else: - self.isvalid = False - return - self.items = items - return - def __str__(self): - tab = self.get_indent_tab() - if not self.items: - return tab + 'SAVE' - return tab + 'SAVE %s' % (', '.join(self.items)) - def analyze(self): return - -class Data(Statement): - """ - DATA <data-stmt-set> [ [ , ] <data-stmt-set> ]... - <data-stmt-set> = <data-stmt-object-list> / <data-stmt-value-list> / - <data-stmt-object> = <variable> | <data-implied-do> - <data-implied-do> = ( <data-i-do-object-list> , <data-i-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] ) - <data-i-do-object> = <array-element> | <scalar-structure-component> | <data-implied-do> - <data-i-do-variable> = <scalar-int-variable> - <variable> = <designator> - <designator> = <object-name> - | <array-element> - | <array-section> - | <structure-component> - | <substring> - <array-element> = <data-ref> - <array-section> = <data-ref> [ ( <substring-range> ) ] - - """ - match = re.compile(r'data\b',re.I).match - - def process_item(self): - line = self.item.get_line()[4:].lstrip() - stmts = [] - self.isvalid = False - while line: - i = line.find('/') - if i==-1: return - j = line.find('/',i+1) - if j==-1: return - l1, l2 = line[:i].rstrip(),line[i+1:j].strip() - l1 = split_comma(l1, self.item) - l2 = split_comma(l2, self.item) - stmts.append((l1,l2)) - line = line[j+1:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - self.stmts = stmts - self.isvalid = True - return - - def __str__(self): - tab = self.get_indent_tab() - l = [] - for o,v in self.stmts: - l.append('%s / %s /' %(', '.join(o),', '.join(v))) - return tab + 'DATA ' + ' '.join(l) - def analyze(self): return - -class Nullify(Statement): - """ - NULLIFY ( <pointer-object-list> ) - <pointer-object> = <variable-name> - """ - match = re.compile(r'nullify\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip()[1:-1].strip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'NULLIFY (%s)' % (', '.join(self.items)) - def analyze(self): return - -class Use(Statement): - """ - USE [ [ , <module-nature> ] :: ] <module-name> [ , <rename-list> ] - USE [ [ , <module-nature> ] :: ] <module-name> , ONLY : [ <only-list> ] - <module-nature> = INTRINSIC | NON_INTRINSIC - <rename> = <local-name> => <use-name> - | OPERATOR ( <local-defined-operator> ) => OPERATOR ( <use-defined-operator> ) - <only> = <generic-spec> | <only-use-name> | <rename> - <only-use-name> = <use-name> - """ - match = re.compile(r'use\b',re.I).match - def process_item(self): - line = self.item.get_line()[3:].lstrip() - nature = '' - if line.startswith(','): - i = line.find('::') - nature = line[1:i].strip().upper() - line = line[i+2:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - if nature and not is_name(nature): - self.isvalid = False - return - self.nature = nature - i = line.find(',') - self.isonly = False - if i==-1: - self.name = line - self.items = [] - else: - self.name = line[:i].rstrip() - line = line[i+1:].lstrip() - if line.lower().startswith('only') and line[4:].lstrip().startswith(':'): - self.isonly = True - line = line[4:].lstrip()[1:].lstrip() - self.items = split_comma(line, self.item) - return - - def __str__(self): - tab = self.get_indent_tab() - s = 'USE' - if self.nature: - s += ' ' + self.nature + ' ::' - s += ' ' + self.name - if self.isonly: - s += ', ONLY:' - elif self.items: - s += ',' - if self.items: - s += ' ' + ', '.join(self.items) - return tab + s - - def analyze(self): - modules = self.top.a.module - - if not modules.has_key(self.name): - fn = None - for d in self.reader.include_dirs: - fn = get_module_file(self.name, d) - if fn is not None: - break - if 1 and fn is not None: - from readfortran import FortranFileReader - from parsefortran import FortranParser - self.info('looking module information from %r' % (fn)) - reader = FortranFileReader(fn) - parser = FortranParser(reader) - parser.parse() - parser.block.a.module.update(modules) - parser.analyze() - modules.update(parser.block.a.module) - - if not modules.has_key(self.name): - self.warning('no information about the use module %r' % (self.name)) - return - -class Exit(Statement): - """ - EXIT [ <do-construct-name> ] - """ - match = re.compile(r'exit\b\s*\w*\s*\Z',re.I).match - def process_item(self): - self.name = self.item.get_line()[4:].lstrip() - return - def __str__(self): - if self.name: - return self.get_indent_tab() + 'EXIT ' + self.name - return self.get_indent_tab() + 'EXIT' - def analyze(self): return - -class Parameter(Statement): - """ - PARAMETER ( <named-constant-def-list> ) - <named-constant-def> = <named-constant> = <initialization-expr> - """ - match = re.compile(r'parameter\s*\(.*\)\Z', re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip()[1:-1].strip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'PARAMETER (%s)' % (', '.join(self.items)) - def analyze(self): - for item in self.items: - i = item.find('=') - assert i!=-1,`item` - name = item[:i].rstrip() - value = item[i+1:].lstrip() - var = self.get_variable(name) - var.update('parameter') - var.set_init(value) - return - -class Equivalence(Statement): - """ - EQUIVALENCE <equivalence-set-list> - <equivalence-set> = ( <equivalence-object> , <equivalence-object-list> ) - <equivalence-object> = <variable-name> | <array-element> | <substring> - """ - match = re.compile(r'equivalence\s*\(.*\)\Z', re.I).match - def process_item(self): - items = [] - for s in self.item.get_line()[11:].lstrip().split(','): - s = s.strip() - assert s[0]+s[-1]=='()',`s,self.item.get_line()` - s = ', '.join(split_comma(s[1:-1], self.item)) - items.append('('+s+')') - self.items = items - return - def __str__(self): - return self.get_indent_tab() + 'EQUIVALENCE %s' % (', '.join(self.items)) - def analyze(self): return - -class Dimension(Statement): - """ - DIMENSION [ :: ] <array-name> ( <array-spec> ) [ , <array-name> ( <array-spec> ) ]... - - """ - match = re.compile(r'dimension\b', re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'DIMENSION %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - assert i!=-1 and line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - return - -class Target(Statement): - """ - TARGET [ :: ] <object-name> ( <array-spec> ) [ , <object-name> ( <array-spec> ) ]... - - """ - match = re.compile(r'target\b', re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'TARGET %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - assert i!=-1 and line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - var.update('target') - return - - -class Pointer(Statement): - """ - POINTER [ :: ] <pointer-decl-list> - <pointer-decl> = <object-name> [ ( <deferred-shape-spec-list> ) ] - | <proc-entity-name> - - """ - match = re.compile(r'pointer\b',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'POINTER %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - if i==-1: - name = line - array_spec = None - else: - assert line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - var.update('pointer') - return - -class Protected(StatementWithNamelist): - """ - PROTECTED [ :: ] <entity-name-list> - """ - match = re.compile(r'protected\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('protected') - return - -class Volatile(StatementWithNamelist): - """ - VOLATILE [ :: ] <object-name-list> - """ - match = re.compile(r'volatile\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('volatile') - return - -class Value(StatementWithNamelist): - """ - VALUE [ :: ] <dummy-arg-name-list> - """ - match = re.compile(r'value\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('value') - return - -class ArithmeticIf(Statement): - """ - IF ( <scalar-numeric-expr> ) <label> , <label> , <label> - """ - match = re.compile(r'if\s*\(.*\)\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\Z', re.I).match - def process_item(self): - line = self.item.get_line()[2:].lstrip() - line,l2,l3 = line.rsplit(',',2) - i = line.rindex(')') - l1 = line[i+1:] - self.expr = self.item.apply_map(line[1:i]).strip() - self.labels = [l1.strip(),l2.strip(),l3.strip()] - return - - def __str__(self): - return self.get_indent_tab() + 'IF (%s) %s' \ - % (self.expr,', '.join(self.labels)) - def analyze(self): return - -class Intrinsic(StatementWithNamelist): - """ - INTRINSIC [ :: ] <intrinsic-procedure-name-list> - """ - match = re.compile(r'intrinsic\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('intrinsic') - return - -class Inquire(Statement): - """ - INQUIRE ( <inquire-spec-list> ) - INQUIRE ( IOLENGTH = <scalar-int-variable> ) <output-item-list> - - <inquire-spec> = [ UNIT = ] <file-unit-number> - | FILE = <file-name-expr> - ... - <output-item> = <expr> - | <io-implied-do> - """ - match = re.compile(r'inquire\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - i = line.index(')') - self.specs = specs_split_comma(line[1:i].strip(), self.item) - self.items = split_comma(line[i+1:].lstrip(), self.item) - return - def __str__(self): - if self.items: - return self.get_indent_tab() + 'INQUIRE (%s) %s' \ - % (', '.join(self.specs), ', '.join(self.items)) - return self.get_indent_tab() + 'INQUIRE (%s)' \ - % (', '.join(self.specs)) - def analyze(self): return - -class Sequence(Statement): - """ - SEQUENCE - """ - match = re.compile(r'sequence\Z',re.I).match - def process_item(self): - return - def __str__(self): return self.get_indent_tab() + 'SEQUENCE' - def analyze(self): - self.parent.a.attributes.append('SEQUENCE') - return - -class External(StatementWithNamelist): - """ - EXTERNAL [ :: ] <external-name-list> - """ - match = re.compile(r'external\b', re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('external') - return - - -class Namelist(Statement): - """ - NAMELIST / <namelist-group-name> / <namelist-group-object-list> [ [ , ] / <namelist-group-name> / <namelist-group-object-list> ]... - <namelist-group-object> = <variable-name> - """ - match = re.compile(r'namelist\b',re.I).match - def process_item(self): - line = self.item.get_line()[8:].lstrip() - items = [] - while line: - assert line.startswith('/'),`line` - i = line.find('/',1) - assert i!=-1,`line` - name = line[:i+1] - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - items.append((name,line)) - line = '' - continue - s = line[:i].rstrip() - if s.endswith(','): - s = s[:-1].rstrip() - items.append((name,s)) - line = line[i+1:].lstrip() - self.items = items - return - - def __str__(self): - l = [] - for name,s in self.items: - l.append('%s %s' % (name,s)) - tab = self.get_indent_tab() - return tab + 'NAMELIST ' + ', '.join(l) - -class Common(Statement): - """ - COMMON [ / [ <common-block-name> ] / ] <common-block-object-list> \ - [ [ , ] / [ <common-block-name> ] / <common-block-object-list> ]... - <common-block-object> = <variable-name> [ ( <explicit-shape-spec-list> ) ] - | <proc-pointer-name> - """ - match = re.compile(r'common\b',re.I).match - def process_item(self): - item = self.item - line = item.get_line()[6:].lstrip() - items = [] - while line: - if not line.startswith('/'): - name = '' - assert not items,`line` - else: - i = line.find('/',1) - assert i!=-1,`line` - name = line[1:i].strip() - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - items.append((name,split_comma(line, item))) - line = '' - continue - s = line[:i].rstrip() - if s.endswith(','): - s = s[:-1].rstrip() - items.append((name,split_comma(s,item))) - line = line[i:].lstrip() - self.items = items - return - def __str__(self): - l = [] - for name,s in self.items: - s = ', '.join(s) - if name: - l.append('/ %s / %s' % (name,s)) - else: - l.append(s) - tab = self.get_indent_tab() - return tab + 'COMMON ' + ' '.join(l) - def analyze(self): - for cname, items in self.items: - for item in items: - i = item.find('(') - if i!=-1: - assert item.endswith(')'),`item` - name = item[:i].rstrip() - shape = split_comma(item[i+1:-1].strip(), self.item) - else: - name = item - shape = None - var = self.get_variable(name) - if shape is not None: - var.set_bounds(shape) - return - -class Optional(StatementWithNamelist): - """ - OPTIONAL [ :: ] <dummy-arg-name-list> - <dummy-arg-name> = <name> - """ - match = re.compile(r'optional\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('optional') - return - -class Intent(Statement): - """ - INTENT ( <intent-spec> ) [ :: ] <dummy-arg-name-list> - <intent-spec> = IN | OUT | INOUT - - generalization for pyf-files: - INTENT ( <intent-spec-list> ) [ :: ] <dummy-arg-name-list> - <intent-spec> = IN | OUT | INOUT | CACHE | HIDE | OUT = <name> - """ - match = re.compile(r'intent\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.find(')') - self.specs = specs_split_comma(line[1:i], self.item, upper=True) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = [s.strip() for s in line.split(',')] - for n in self.items: - if not is_name(n): - self.isvalid = False - return - return - def __str__(self): - return self.get_indent_tab() + 'INTENT (%s) %s' \ - % (', '.join(self.specs), ', '.join(self.items)) - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.set_intent(self.specs) - return - - -class Entry(Statement): - """ - ENTRY <entry-name> [ ( [ <dummy-arg-list> ] ) [ <suffix> ] ] - <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] - | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] - <proc-language-binding-spec> = <language-binding-spec> - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr> ] ) - <dummy-arg> = <dummy-arg-name> | * - """ - match = re.compile(r'entry\b', re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - m = re.match(r'\w+', line) - name = line[:m.end()] - line = line[m.end():].lstrip() - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - items = split_comma(line[1:i], self.item) - line = line[i+1:].lstrip() - else: - items = [] - self.bind, line = parse_bind(line, self.item) - self.result, line = parse_result(line, self.item) - if line: - assert self.bind is None,`self.bind` - self.bind, line = parse_bind(line, self.item) - assert not line,`line` - self.name = name - self.items = items - return - def __str__(self): - tab = self.get_indent_tab() - s = tab + 'ENTRY '+self.name - if self.items: - s += ' (%s)' % (', '.join(self.items)) - if self.result: - s += ' RESULT (%s)' % (self.result) - if self.bind: - s += ' BIND (%s)' % (', '.join(self.bind)) - return s - -class Import(StatementWithNamelist): - """ - IMPORT [ [ :: ] <import-name-list> ] - """ - match = re.compile(r'import(\b|\Z)',re.I).match - -class Forall(Statement): - """ - FORALL <forall-header> <forall-assignment-stmt> - <forall-header> = ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) - <forall-triplet-spec> = <index-name> = <subscript> : <subscript> [ : <stride> ] - <subscript|stride> = <scalar-int-expr> - <forall-assignment-stmt> = <assignment-stmt> | <pointer-assignment-stmt> - """ - match = re.compile(r'forall\s*\(.*\).*=', re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.index(')') - - line0 = line[1:i] - line = line[i+1:].lstrip() - stmt = GeneralAssignment(self, self.item.copy(line, True)) - if stmt.isvalid: - self.content = [stmt] - else: - self.isvalid = False - return - - specs = [] - mask = '' - for l in split_comma(line0,self.item): - j = l.find('=') - if j==-1: - assert not mask,`mask,l` - mask = l - continue - assert j!=-1,`l` - index = l[:j].rstrip() - it = self.item.copy(l[j+1:].lstrip()) - l = it.get_line() - k = l.split(':') - if len(k)==3: - s1, s2, s3 = map(it.apply_map, - [k[0].strip(),k[1].strip(),k[2].strip()]) - else: - assert len(k)==2,`k` - s1, s2 = map(it.apply_map, - [k[0].strip(),k[1].strip()]) - s3 = '1' - specs.append((index,s1,s2,s3)) - - self.specs = specs - self.mask = mask - return - - def __str__(self): - tab = self.get_indent_tab() - l = [] - for index,s1,s2,s3 in self.specs: - s = '%s = %s : %s' % (index,s1,s2) - if s3!='1': - s += ' : %s' % (s3) - l.append(s) - s = ', '.join(l) - if self.mask: - s += ', ' + self.mask - return tab + 'FORALL (%s) %s' % \ - (s, str(self.content[0]).lstrip()) - def analyze(self): return - -ForallStmt = Forall - -class SpecificBinding(Statement): - """ - PROCEDURE [ ( <interface-name> ) ] [ [ , <binding-attr-list> ] :: ] <binding-name> [ => <procedure-name> ] - <binding-attr> = PASS [ ( <arg-name> ) ] - | NOPASS - | NON_OVERRIDABLE - | DEFERRED - | <access-spec> - <access-spec> = PUBLIC | PRIVATE - """ - match = re.compile(r'procedure\b',re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip() - if line.startswith('('): - i = line.index(')') - name = line[1:i].strip() - line = line[i+1:].lstrip() - else: - name = '' - self.iname = name - if line.startswith(','): - line = line[1:].lstrip() - i = line.find('::') - if i != -1: - attrs = split_comma(line[:i], self.item) - line = line[i+2:].lstrip() - else: - attrs = [] - attrs1 = [] - for attr in attrs: - if is_name(attr): - attr = attr.upper() - else: - i = attr.find('(') - assert i!=-1 and attr.endswith(')'),`attr` - attr = '%s (%s)' % (attr[:i].rstrip().upper(), attr[i+1:-1].strip()) - attrs1.append(attr) - self.attrs = attrs1 - i = line.find('=') - if i==-1: - self.name = line - self.bname = '' - else: - self.name = line[:i].rstrip() - self.bname = line[i+1:].lstrip()[1:].lstrip() - return - def __str__(self): - tab = self.get_indent_tab() - s = 'PROCEDURE ' - if self.iname: - s += '(' + self.iname + ') ' - if self.attrs: - s += ', ' + ', '.join(self.attrs) + ' :: ' - if self.bname: - s += '%s => %s' % (self.name, self.bname) - else: - s += self.name - return tab + s - -class GenericBinding(Statement): - """ - GENERIC [ , <access-spec> ] :: <generic-spec> => <binding-name-list> - """ - match = re.compile(r'generic\b.*::.*=\>.*\Z', re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - i = line.index('::') - self.aspec = line[:i].rstrip().upper() - line = line[i+2:].lstrip() - i = line.index('=>') - self.spec = self.item.apply_map(line[:i].rstrip()) - self.items = split_comma(line[i+2:].lstrip()) - return - - def __str__(self): - tab = self.get_indent_tab() - s = 'GENERIC' - if self.aspec: - s += ', '+self.aspec - s += ' :: ' + self.spec + ' => ' + ', '.join(self.items) - return tab + s - - -class FinalBinding(StatementWithNamelist): - """ - FINAL [ :: ] <final-subroutine-name-list> - """ - stmtname = 'final' - match = re.compile(r'final\b', re.I).match - -class Allocatable(Statement): - """ - ALLOCATABLE [ :: ] <object-name> [ ( <deferred-shape-spec-list> ) ] [ , <object-name> [ ( <deferred-shape-spec-list> ) ] ]... - """ - match = re.compile(r'allocatable\b',re.I).match - def process_item(self): - line = self.item.get_line()[11:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'ALLOCATABLE ' + ', '.join(self.items) - def analyze(self): - for line in self.items: - i = line.find('(') - if i==-1: - name = line - array_spec = None - else: - assert line.endswith(')') - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1], self.item) - var = self.get_variable(name) - var.update('allocatable') - if array_spec is not None: - var.set_bounds(array_spec) - return - -class Asynchronous(StatementWithNamelist): - """ - ASYNCHRONOUS [ :: ] <object-name-list> - """ - match = re.compile(r'asynchronous\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('asynchronous') - return - - -class Bind(Statement): - """ - <language-binding-spec> [ :: ] <bind-entity-list> - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr> ] ) - <bind-entity> = <entity-name> | / <common-block-name> / - """ - match = re.compile(r'bind\s*\(.*\)',re.I).match - def process_item(self): - line = self.item.line - self.specs, line = parse_bind(line, self.item) - if line.startswith('::'): - line = line[2:].lstrip() - items = [] - for item in split_comma(line, self.item): - if item.startswith('/'): - assert item.endswith('/'),`item` - item = '/ ' + item[1:-1].strip() + ' /' - items.append(item) - self.items = items - return - def __str__(self): - return self.get_indent_tab() + 'BIND (%s) %s' %\ - (', '.join(self.specs), ', '.join(self.items)) - -# IF construct statements - -class Else(Statement): - """ - ELSE [<if-construct-name>] - """ - match = re.compile(r'else\b\s*\w*\s*\Z',re.I).match - - def process_item(self): - item = self.item - self.name = item.get_line()[4:].strip() - parent_name = getattr(self.parent,'name','') - if self.name and self.name!=parent_name: - self.warning('expected if-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def __str__(self): - if self.name: - return self.get_indent_tab(deindent=True) + 'ELSE ' + self.name - return self.get_indent_tab(deindent=True) + 'ELSE' - - def analyze(self): return - -class ElseIf(Statement): - """ - ELSE IF ( <scalar-logical-expr> ) THEN [ <if-construct-name> ] - """ - match = re.compile(r'else\s*if\s*\(.*\)\s*then\s*\w*\s*\Z',re.I).match - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip()[2:].lstrip() - i = line.find(')') - assert line[0]=='(' - self.expr = item.apply_map(line[1:i]) - self.name = line[i+1:].lstrip()[4:].strip() - parent_name = getattr(self.parent,'name','') - if self.name and self.name!=parent_name: - self.warning('expected if-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def __str__(self): - s = '' - if self.name: - s = ' ' + self.name - return self.get_indent_tab(deindent=True) + 'ELSE IF (%s) THEN%s' \ - % (self.expr, s) - - def analyze(self): return - -# SelectCase construct statements - -class Case(Statement): - """ - CASE <case-selector> [ <case-constract-name> ] - <case-selector> = ( <case-value-range-list> ) | DEFAULT - <case-value-range> = <case-value> - | <case-value> : - | : <case-value> - | <case-value> : <case-value> - <case-value> = <scalar-(int|char|logical)-initialization-expr> - """ - match = re.compile(r'case\b\s*(\(.*\)|DEFAULT)\s*\w*\Z',re.I).match - def process_item(self): - #assert self.parent.__class__.__name__=='Select',`self.parent.__class__` - line = self.item.get_line()[4:].lstrip() - if line.startswith('('): - i = line.find(')') - items = split_comma(line[1:i].strip(), self.item) - line = line[i+1:].lstrip() - else: - assert line.lower().startswith('default'),`line` - items = [] - line = line[7:].lstrip() - for i in range(len(items)): - it = self.item.copy(items[i]) - rl = [] - for r in it.get_line().split(':'): - rl.append(it.apply_map(r.strip())) - items[i] = rl - self.items = items - self.name = line - parent_name = getattr(self.parent, 'name', '') - if self.name and self.name!=parent_name: - self.warning('expected case-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def __str__(self): - tab = self.get_indent_tab() - s = 'CASE' - if self.items: - l = [] - for item in self.items: - l.append((' : '.join(item)).strip()) - s += ' ( %s )' % (', '.join(l)) - else: - s += ' DEFAULT' - if self.name: - s += ' ' + self.name - return s - def analyze(self): return - -# Where construct statements - -class Where(Statement): - """ - WHERE ( <mask-expr> ) <where-assignment-stmt> - """ - match = re.compile(r'where\s*\(.*\)\s*\w.*\Z',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - i = line.index(')') - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - newitem = self.item.copy(line) - cls = Assignment - if cls.match(line): - stmt = cls(self, newitem) - if stmt.isvalid: - self.content = [stmt] - return - self.isvalid = False - return - - def __str__(self): - tab = self.get_indent_tab() - return tab + 'WHERE ( %s ) %s' % (self.expr, str(self.content[0]).lstrip()) - def analyze(self): return - -WhereStmt = Where - -class ElseWhere(Statement): - """ - ELSE WHERE ( <mask-expr> ) [ <where-construct-name> ] - ELSE WHERE [ <where-construct-name> ] - """ - match = re.compile(r'else\s*where\b',re.I).match - def process_item(self): - line = self.item.get_line()[4:].lstrip()[5:].lstrip() - self.expr = None - if line.startswith('('): - i = line.index(')') - assert i != -1,`line` - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - self.name = line - parent_name = getattr(self.parent,'name','') - if self.name and not self.name==parent_name: - self.warning('expected where-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def __str__(self): - tab = self.get_indent_tab() - s = 'ELSE WHERE' - if self.expr is not None: - s += ' ( %s )' % (self.expr) - if self.name: - s += ' ' + self.name - return tab + s - def analyze(self): return - -# Enum construct statements - -class Enumerator(Statement): - """ - ENUMERATOR [ :: ] <enumerator-list> - <enumerator> = <named-constant> [ = <scalar-int-initialization-expr> ] - """ - match = re.compile(r'enumerator\b',re.I).match - def process_item(self): - line = self.item.get_line()[10:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def __str__(self): - return self.get_indent_tab() + 'ENUMERATOR ' + ', '.join(self.items) - -# F2PY specific statements - -class FortranName(Statement): - """ - FORTRANNAME <name> - """ - match = re.compile(r'fortranname\s*\w+\Z',re.I).match - def process_item(self): - self.value = self.item.get_line()[11:].lstrip() - return - def __str__(self): - return self.get_indent_tab() + 'FORTRANNAME ' + self.value - -class Threadsafe(Statement): - """ - THREADSAFE - """ - match = re.compile(r'threadsafe\Z',re.I).match - def process_item(self): - return - def __str__(self): - return self.get_indent_tab() + 'THREADSAFE' - -class Depend(Statement): - """ - DEPEND ( <name-list> ) [ :: ] <dummy-arg-name-list> - - """ - match = re.compile(r'depend\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.find(')') - self.depends = split_comma(line[1:i].strip(), self.item) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line) - return - - def __str__(self): - return self.get_indent_tab() + 'DEPEND ( %s ) %s' \ - % (', '.join(self.depends), ', '.join(self.items)) - -class Check(Statement): - """ - CHECK ( <c-int-scalar-expr> ) [ :: ] <name> - - """ - match = re.compile(r'check\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - i = line.find(')') - assert i!=-1,`line` - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.value = line - return - def __str__(self): - return self.get_indent_tab() + 'CHECK ( %s ) %s' \ - % (self.expr, self.value) - -class CallStatement(Statement): - """ - CALLSTATEMENT <c-expr> - """ - match = re.compile(r'callstatement\b', re.I).match - def process_item(self): - self.expr = self.item.apply_map(self.item.get_line()[13:].lstrip()) - return - def __str__(self): - return self.get_indent_tab() + 'CALLSTATEMENT ' + self.expr - -class CallProtoArgument(Statement): - """ - CALLPROTOARGUMENT <c-type-spec-list> - """ - match = re.compile(r'callprotoargument\b', re.I).match - def process_item(self): - self.specs = self.item.apply_map(self.item.get_line()[17:].lstrip()) - return - def __str__(self): - return self.get_indent_tab() + 'CALLPROTOARGUMENT ' + self.specs - -# Non-standard statements - -class Pause(Statement): - """ - PAUSE [ <char-literal-constant|int-literal-constant> ] - """ - match = re.compile(r'pause\s*(\d+|\'\w*\'|"\w*"|)\Z', re.I).match - def process_item(self): - self.value = self.item.apply_map(self.item.get_line()[5:].lstrip()) - return - def __str__(self): - if self.value: - return self.get_indent_tab() + 'PAUSE ' + self.value - return self.get_indent_tab() + 'PAUSE' - def analyze(self): return - diff --git a/numpy/f2py/lib/test_parser.py b/numpy/f2py/lib/test_parser.py deleted file mode 100644 index af54efdf2..000000000 --- a/numpy/f2py/lib/test_parser.py +++ /dev/null @@ -1,480 +0,0 @@ - -from numpy.testing import * -from block_statements import * -from readfortran import Line, FortranStringReader - - -def parse(cls, line, label='', - isfree=True, isstrict=False): - if label: - line = label + ' : ' + line - reader = FortranStringReader(line, isfree, isstrict) - item = reader.next() - if not cls.match(item.get_line()): - raise ValueError, '%r does not match %s pattern' % (line, cls.__name__) - stmt = cls(item, item) - if stmt.isvalid: - r = str(stmt) - if not isstrict: - r1 = parse(cls, r, isstrict=True) - if r != r1: - raise ValueError, 'Failed to parse %r with %s pattern in pyf mode, got %r' % (r, cls.__name__, r1) - return r - raise ValueError, 'parsing %r with %s pattern failed' % (line, cls.__name__) - -class test_Statements(NumpyTestCase): - - def check_assignment(self): - assert_equal(parse(Assignment,'a=b'), 'a = b') - assert_equal(parse(PointerAssignment,'a=>b'), 'a => b') - assert_equal(parse(Assignment,'a (2)=b(n,m)'), 'a(2) = b(n,m)') - assert_equal(parse(Assignment,'a % 2(2,4)=b(a(i))'), 'a%2(2,4) = b(a(i))') - - def check_assign(self): - assert_equal(parse(Assign,'assign 10 to a'),'ASSIGN 10 TO a') - - def check_call(self): - assert_equal(parse(Call,'call a'),'CALL a') - assert_equal(parse(Call,'call a()'),'CALL a') - assert_equal(parse(Call,'call a(1)'),'CALL a(1)') - assert_equal(parse(Call,'call a(1,2)'),'CALL a(1, 2)') - assert_equal(parse(Call,'call a % 2 ( n , a+1 )'),'CALL a % 2(n, a+1)') - - def check_goto(self): - assert_equal(parse(Goto,'go to 19'),'GO TO 19') - assert_equal(parse(Goto,'goto 19'),'GO TO 19') - assert_equal(parse(ComputedGoto,'goto (1, 2 ,3) a+b(2)'), - 'GO TO (1, 2, 3) a+b(2)') - assert_equal(parse(ComputedGoto,'goto (1, 2 ,3) , a+b(2)'), - 'GO TO (1, 2, 3) a+b(2)') - assert_equal(parse(AssignedGoto,'goto a'),'GO TO a') - assert_equal(parse(AssignedGoto,'goto a ( 1 )'),'GO TO a (1)') - assert_equal(parse(AssignedGoto,'goto a ( 1 ,2)'),'GO TO a (1, 2)') - - def check_continue(self): - assert_equal(parse(Continue,'continue'),'CONTINUE') - - def check_return(self): - assert_equal(parse(Return,'return'),'RETURN') - assert_equal(parse(Return,'return a'),'RETURN a') - assert_equal(parse(Return,'return a+1'),'RETURN a+1') - assert_equal(parse(Return,'return a(c, a)'),'RETURN a(c, a)') - - def check_stop(self): - assert_equal(parse(Stop,'stop'),'STOP') - assert_equal(parse(Stop,'stop 1'),'STOP 1') - assert_equal(parse(Stop,'stop "a"'),'STOP "a"') - assert_equal(parse(Stop,'stop "a b"'),'STOP "a b"') - - def check_print(self): - assert_equal(parse(Print, 'print*'),'PRINT *') - assert_equal(parse(Print, 'print "a b( c )"'),'PRINT "a b( c )"') - assert_equal(parse(Print, 'print 12, a'),'PRINT 12, a') - assert_equal(parse(Print, 'print 12, a , b'),'PRINT 12, a, b') - assert_equal(parse(Print, 'print 12, a(c,1) , b'),'PRINT 12, a(c,1), b') - - def check_read(self): - assert_equal(parse(Read, 'read ( 10 )'),'READ (10)') - assert_equal(parse(Read, 'read ( 10 ) a '),'READ (10) a') - assert_equal(parse(Read, 'read ( 10 ) a , b'),'READ (10) a, b') - assert_equal(parse(Read, 'read *'),'READ *') - assert_equal(parse(Read, 'read 12'),'READ 12') - assert_equal(parse(Read, 'read "a b"'),'READ "a b"') - assert_equal(parse(Read, 'read "a b",a'),'READ "a b", a') - assert_equal(parse(Read, 'read * , a'),'READ *, a') - assert_equal(parse(Read, 'read "hey a" , a'),'READ "hey a", a') - assert_equal(parse(Read, 'read * , a , b'),'READ *, a, b') - assert_equal(parse(Read, 'read ( unit =10 )'),'READ (UNIT = 10)') - - def check_write(self): - assert_equal(parse(Write, 'write ( 10 )'),'WRITE (10)') - assert_equal(parse(Write, 'write ( 10 , a )'),'WRITE (10, a)') - assert_equal(parse(Write, 'write ( 10 ) b'),'WRITE (10) b') - assert_equal(parse(Write, 'write ( 10 ) a(1) , b+2'),'WRITE (10) a(1), b+2') - assert_equal(parse(Write, 'write ( unit=10 )'),'WRITE (UNIT = 10)') - - def check_flush(self): - assert_equal(parse(Flush, 'flush 10'),'FLUSH (10)') - assert_equal(parse(Flush, 'flush (10)'),'FLUSH (10)') - assert_equal(parse(Flush, 'flush (UNIT = 10)'),'FLUSH (UNIT = 10)') - assert_equal(parse(Flush, 'flush (10, err= 23)'),'FLUSH (10, ERR = 23)') - - def check_wait(self): - assert_equal(parse(Wait, 'wait(10)'),'WAIT (10)') - assert_equal(parse(Wait, 'wait(10,err=129)'),'WAIT (10, ERR = 129)') - - def check_contains(self): - assert_equal(parse(Contains, 'contains'),'CONTAINS') - - def check_allocate(self): - assert_equal(parse(Allocate, 'allocate (a)'), 'ALLOCATE (a)') - assert_equal(parse(Allocate, \ - 'allocate (a, stat=b)'), 'ALLOCATE (a, STAT = b)') - assert_equal(parse(Allocate, 'allocate (a,b(:1))'), 'ALLOCATE (a, b(:1))') - assert_equal(parse(Allocate, \ - 'allocate (real(8)::a)'), 'ALLOCATE (REAL(KIND=8) :: a)') - def check_deallocate(self): - assert_equal(parse(Deallocate, 'deallocate (a)'), 'DEALLOCATE (a)') - assert_equal(parse(Deallocate, 'deallocate (a, stat=b)'), 'DEALLOCATE (a, STAT = b)') - - def check_moduleprocedure(self): - assert_equal(parse(ModuleProcedure,\ - 'ModuleProcedure a'), 'MODULE PROCEDURE a') - assert_equal(parse(ModuleProcedure,\ - 'module procedure a , b'), 'MODULE PROCEDURE a, b') - - def check_access(self): - assert_equal(parse(Public,'Public'),'PUBLIC') - assert_equal(parse(Public,'public a'),'PUBLIC a') - assert_equal(parse(Public,'public :: a'),'PUBLIC a') - assert_equal(parse(Public,'public a,b,c'),'PUBLIC a, b, c') - assert_equal(parse(Public,'public :: a(:,:)'),'PUBLIC a(:,:)') - assert_equal(parse(Private,'private'),'PRIVATE') - assert_equal(parse(Private,'private :: a'),'PRIVATE a') - - def check_close(self): - assert_equal(parse(Close,'close (12)'),'CLOSE (12)') - assert_equal(parse(Close,'close (12, err=99)'),'CLOSE (12, ERR = 99)') - assert_equal(parse(Close,'close (12, status = a(1,2))'),'CLOSE (12, STATUS = a(1,2))') - - def check_cycle(self): - assert_equal(parse(Cycle,'cycle'),'CYCLE') - assert_equal(parse(Cycle,'cycle ab'),'CYCLE ab') - - def check_rewind(self): - assert_equal(parse(Rewind,'rewind 1'),'REWIND (1)') - assert_equal(parse(Rewind,'rewind (1)'),'REWIND (1)') - assert_equal(parse(Rewind,'rewind (1, err = 123)'),'REWIND (1, ERR = 123)') - - def check_backspace(self): - assert_equal(parse(Backspace,'backspace 1'),'BACKSPACE (1)') - assert_equal(parse(Backspace,'backspace (1)'),'BACKSPACE (1)') - assert_equal(parse(Backspace,'backspace (1, err = 123)'),'BACKSPACE (1, ERR = 123)') - - def check_endfile(self): - assert_equal(parse(Endfile,'endfile 1'),'ENDFILE (1)') - assert_equal(parse(Endfile,'endfile (1)'),'ENDFILE (1)') - assert_equal(parse(Endfile,'endfile (1, err = 123)'),'ENDFILE (1, ERR = 123)') - - def check_open(self): - assert_equal(parse(Open,'open (1)'),'OPEN (1)') - assert_equal(parse(Open,'open (1, err = 123)'),'OPEN (1, ERR = 123)') - - def check_format(self): - assert_equal(parse(Format,'1: format ()'),'1: FORMAT ()') - assert_equal(parse(Format,'199 format (1)'),'199: FORMAT (1)') - assert_equal(parse(Format,'2 format (1 , SS)'),'2: FORMAT (1, ss)') - - def check_save(self): - assert_equal(parse(Save,'save'), 'SAVE') - assert_equal(parse(Save,'save :: a'), 'SAVE a') - assert_equal(parse(Save,'save a,b'), 'SAVE a, b') - - def check_data(self): - assert_equal(parse(Data,'data a /b/'), 'DATA a / b /') - assert_equal(parse(Data,'data a , c /b/'), 'DATA a, c / b /') - assert_equal(parse(Data,'data a /b ,c/'), 'DATA a / b, c /') - assert_equal(parse(Data,'data a /b/ c,e /d/'), 'DATA a / b / c, e / d /') - assert_equal(parse(Data,'data a(1,2) /b/'), 'DATA a(1,2) / b /') - assert_equal(parse(Data,'data a /b, c(1)/'), 'DATA a / b, c(1) /') - - def check_nullify(self): - assert_equal(parse(Nullify,'nullify(a)'),'NULLIFY (a)') - assert_equal(parse(Nullify,'nullify(a ,b)'),'NULLIFY (a, b)') - - def check_use(self): - assert_equal(parse(Use, 'use a'), 'USE a') - assert_equal(parse(Use, 'use :: a'), 'USE a') - assert_equal(parse(Use, 'use, intrinsic:: a'), 'USE INTRINSIC :: a') - assert_equal(parse(Use, 'use :: a ,only: b'), 'USE a, ONLY: b') - assert_equal(parse(Use, 'use :: a , only: b=>c'), 'USE a, ONLY: b=>c') - assert_equal(parse(Use, 'use :: a , b=>c'), 'USE a, b=>c') - assert_equal(parse(Use,\ - 'use :: a , only: operator(+) , b'),\ - 'USE a, ONLY: operator(+), b') - - def check_exit(self): - assert_equal(parse(Exit,'exit'),'EXIT') - assert_equal(parse(Exit,'exit ab'),'EXIT ab') - - def check_parameter(self): - assert_equal(parse(Parameter,'parameter (a = b(1,2))'), - 'PARAMETER (a = b(1,2))') - assert_equal(parse(Parameter,'parameter (a = b(1,2) , b=1)'), - 'PARAMETER (a = b(1,2), b=1)') - - def check_equivalence(self): - assert_equal(parse(Equivalence,'equivalence (a , b)'),'EQUIVALENCE (a, b)') - assert_equal(parse(Equivalence,'equivalence (a , b) , ( c, d(1) , g )'), - 'EQUIVALENCE (a, b), (c, d(1), g)') - - def check_dimension(self): - assert_equal(parse(Dimension,'dimension a(b)'),'DIMENSION a(b)') - assert_equal(parse(Dimension,'dimension::a(b)'),'DIMENSION a(b)') - assert_equal(parse(Dimension,'dimension a(b) , c(d)'),'DIMENSION a(b), c(d)') - assert_equal(parse(Dimension,'dimension a(b,c)'),'DIMENSION a(b,c)') - - def check_target(self): - assert_equal(parse(Target,'target a(b)'),'TARGET a(b)') - assert_equal(parse(Target,'target::a(b)'),'TARGET a(b)') - assert_equal(parse(Target,'target a(b) , c(d)'),'TARGET a(b), c(d)') - assert_equal(parse(Target,'target a(b,c)'),'TARGET a(b,c)') - - def check_pointer(self): - assert_equal(parse(Pointer,'pointer a=b'),'POINTER a=b') - assert_equal(parse(Pointer,'pointer :: a=b'),'POINTER a=b') - assert_equal(parse(Pointer,'pointer a=b, c=d(1,2)'),'POINTER a=b, c=d(1,2)') - - def check_protected(self): - assert_equal(parse(Protected,'protected a'),'PROTECTED a') - assert_equal(parse(Protected,'protected::a'),'PROTECTED a') - assert_equal(parse(Protected,'protected a , b'),'PROTECTED a, b') - - def check_volatile(self): - assert_equal(parse(Volatile,'volatile a'),'VOLATILE a') - assert_equal(parse(Volatile,'volatile::a'),'VOLATILE a') - assert_equal(parse(Volatile,'volatile a , b'),'VOLATILE a, b') - - def check_value(self): - assert_equal(parse(Value,'value a'),'VALUE a') - assert_equal(parse(Value,'value::a'),'VALUE a') - assert_equal(parse(Value,'value a , b'),'VALUE a, b') - - def check_arithmeticif(self): - assert_equal(parse(ArithmeticIf,'if (a) 1,2,3'),'IF (a) 1, 2, 3') - assert_equal(parse(ArithmeticIf,'if (a(1)) 1,2,3'),'IF (a(1)) 1, 2, 3') - assert_equal(parse(ArithmeticIf,'if (a(1,2)) 1,2,3'),'IF (a(1,2)) 1, 2, 3') - - def check_intrinsic(self): - assert_equal(parse(Intrinsic,'intrinsic a'),'INTRINSIC a') - assert_equal(parse(Intrinsic,'intrinsic::a'),'INTRINSIC a') - assert_equal(parse(Intrinsic,'intrinsic a , b'),'INTRINSIC a, b') - - def check_inquire(self): - assert_equal(parse(Inquire, 'inquire (1)'),'INQUIRE (1)') - assert_equal(parse(Inquire, 'inquire (1, err=123)'),'INQUIRE (1, ERR = 123)') - assert_equal(parse(Inquire, 'inquire (iolength=a) b'),'INQUIRE (IOLENGTH = a) b') - assert_equal(parse(Inquire, 'inquire (iolength=a) b ,c(1,2)'), - 'INQUIRE (IOLENGTH = a) b, c(1,2)') - - def check_sequence(self): - assert_equal(parse(Sequence, 'sequence'),'SEQUENCE') - - def check_external(self): - assert_equal(parse(External,'external a'),'EXTERNAL a') - assert_equal(parse(External,'external::a'),'EXTERNAL a') - assert_equal(parse(External,'external a , b'),'EXTERNAL a, b') - - def check_common(self): - assert_equal(parse(Common, 'common a'),'COMMON a') - assert_equal(parse(Common, 'common a , b'),'COMMON a, b') - assert_equal(parse(Common, 'common a , b(1,2)'),'COMMON a, b(1,2)') - assert_equal(parse(Common, 'common // a'),'COMMON a') - assert_equal(parse(Common, 'common / name/ a'),'COMMON / name / a') - assert_equal(parse(Common, 'common / name/ a , c'),'COMMON / name / a, c') - assert_equal(parse(Common, 'common / name/ a /foo/ c(1) ,d'), - 'COMMON / name / a / foo / c(1), d') - assert_equal(parse(Common, 'common / name/ a, /foo/ c(1) ,d'), - 'COMMON / name / a / foo / c(1), d') - - def check_optional(self): - assert_equal(parse(Optional,'optional a'),'OPTIONAL a') - assert_equal(parse(Optional,'optional::a'),'OPTIONAL a') - assert_equal(parse(Optional,'optional a , b'),'OPTIONAL a, b') - - def check_intent(self): - assert_equal(parse(Intent,'intent (in) a'),'INTENT (in) a') - assert_equal(parse(Intent,'intent(in)::a'),'INTENT (in) a') - assert_equal(parse(Intent,'intent(in) a , b'),'INTENT (in) a, b') - assert_equal(parse(Intent,'intent (in, out) a'),'INTENT (in, out) a') - - def check_entry(self): - assert_equal(parse(Entry,'entry a'), 'ENTRY a') - assert_equal(parse(Entry,'entry a()'), 'ENTRY a') - assert_equal(parse(Entry,'entry a(b)'), 'ENTRY a (b)') - assert_equal(parse(Entry,'entry a(b,*)'), 'ENTRY a (b, *)') - assert_equal(parse(Entry,'entry a bind(c , name="a b")'), - 'ENTRY a BIND (C, NAME = "a b")') - assert_equal(parse(Entry,'entry a result (b)'), 'ENTRY a RESULT (b)') - assert_equal(parse(Entry,'entry a bind(d) result (b)'), - 'ENTRY a RESULT (b) BIND (d)') - assert_equal(parse(Entry,'entry a result (b) bind( c )'), - 'ENTRY a RESULT (b) BIND (C)') - assert_equal(parse(Entry,'entry a(b,*) result (g)'), - 'ENTRY a (b, *) RESULT (g)') - - def check_import(self): - assert_equal(parse(Import,'import'),'IMPORT') - assert_equal(parse(Import,'import a'),'IMPORT a') - assert_equal(parse(Import,'import::a'),'IMPORT a') - assert_equal(parse(Import,'import a , b'),'IMPORT a, b') - - def check_forall(self): - assert_equal(parse(ForallStmt,'forall (i = 1:n(k,:) : 2) a(i) = i*i*b(i)'), - 'FORALL (i = 1 : n(k,:) : 2) a(i) = i*i*b(i)') - assert_equal(parse(ForallStmt,'forall (i=1:n,j=2:3) a(i) = b(i,i)'), - 'FORALL (i = 1 : n, j = 2 : 3) a(i) = b(i,i)') - assert_equal(parse(ForallStmt,'forall (i=1:n,j=2:3, 1+a(1,2)) a(i) = b(i,i)'), - 'FORALL (i = 1 : n, j = 2 : 3, 1+a(1,2)) a(i) = b(i,i)') - - def check_specificbinding(self): - assert_equal(parse(SpecificBinding,'procedure a'),'PROCEDURE a') - assert_equal(parse(SpecificBinding,'procedure :: a'),'PROCEDURE a') - assert_equal(parse(SpecificBinding,'procedure , NOPASS :: a'),'PROCEDURE , NOPASS :: a') - assert_equal(parse(SpecificBinding,'procedure , public, pass(x ) :: a'),'PROCEDURE , PUBLIC, PASS (x) :: a') - assert_equal(parse(SpecificBinding,'procedure(n) a'),'PROCEDURE (n) a') - assert_equal(parse(SpecificBinding,'procedure(n),pass :: a'), - 'PROCEDURE (n) , PASS :: a') - assert_equal(parse(SpecificBinding,'procedure(n) :: a'), - 'PROCEDURE (n) a') - assert_equal(parse(SpecificBinding,'procedure a= >b'),'PROCEDURE a => b') - assert_equal(parse(SpecificBinding,'procedure(n),pass :: a =>c'), - 'PROCEDURE (n) , PASS :: a => c') - - def check_genericbinding(self): - assert_equal(parse(GenericBinding,'generic :: a=>b'),'GENERIC :: a => b') - assert_equal(parse(GenericBinding,'generic, public :: a=>b'),'GENERIC, PUBLIC :: a => b') - assert_equal(parse(GenericBinding,'generic, public :: a(1,2)=>b ,c'), - 'GENERIC, PUBLIC :: a(1,2) => b, c') - - def check_finalbinding(self): - assert_equal(parse(FinalBinding,'final a'),'FINAL a') - assert_equal(parse(FinalBinding,'final::a'),'FINAL a') - assert_equal(parse(FinalBinding,'final a , b'),'FINAL a, b') - - def check_allocatable(self): - assert_equal(parse(Allocatable,'allocatable a'),'ALLOCATABLE a') - assert_equal(parse(Allocatable,'allocatable :: a'),'ALLOCATABLE a') - assert_equal(parse(Allocatable,'allocatable a (1,2)'),'ALLOCATABLE a (1,2)') - assert_equal(parse(Allocatable,'allocatable a (1,2) ,b'),'ALLOCATABLE a (1,2), b') - - def check_asynchronous(self): - assert_equal(parse(Asynchronous,'asynchronous a'),'ASYNCHRONOUS a') - assert_equal(parse(Asynchronous,'asynchronous::a'),'ASYNCHRONOUS a') - assert_equal(parse(Asynchronous,'asynchronous a , b'),'ASYNCHRONOUS a, b') - - def check_bind(self): - assert_equal(parse(Bind,'bind(c) a'),'BIND (C) a') - assert_equal(parse(Bind,'bind(c) :: a'),'BIND (C) a') - assert_equal(parse(Bind,'bind(c) a ,b'),'BIND (C) a, b') - assert_equal(parse(Bind,'bind(c) /a/'),'BIND (C) / a /') - assert_equal(parse(Bind,'bind(c) /a/ ,b'),'BIND (C) / a /, b') - assert_equal(parse(Bind,'bind(c,name="hey") a'),'BIND (C, NAME = "hey") a') - - def check_else(self): - assert_equal(parse(Else,'else'),'ELSE') - assert_equal(parse(ElseIf,'else if (a) then'),'ELSE IF (a) THEN') - assert_equal(parse(ElseIf,'else if (a.eq.b(1,2)) then'), - 'ELSE IF (a.eq.b(1,2)) THEN') - - def check_case(self): - assert_equal(parse(Case,'case (1)'),'CASE ( 1 )') - assert_equal(parse(Case,'case (1:)'),'CASE ( 1 : )') - assert_equal(parse(Case,'case (:1)'),'CASE ( : 1 )') - assert_equal(parse(Case,'case (1:2)'),'CASE ( 1 : 2 )') - assert_equal(parse(Case,'case (a(1,2))'),'CASE ( a(1,2) )') - assert_equal(parse(Case,'case ("ab")'),'CASE ( "ab" )') - assert_equal(parse(Case,'case default'),'CASE DEFAULT') - assert_equal(parse(Case,'case (1:2 ,3:4)'),'CASE ( 1 : 2, 3 : 4 )') - assert_equal(parse(Case,'case (a(1,:):)'),'CASE ( a(1,:) : )') - assert_equal(parse(Case,'case default'),'CASE DEFAULT') - - def check_where(self): - assert_equal(parse(WhereStmt,'where (1) a=1'),'WHERE ( 1 ) a = 1') - assert_equal(parse(WhereStmt,'where (a(1,2)) a=1'),'WHERE ( a(1,2) ) a = 1') - - def check_elsewhere(self): - assert_equal(parse(ElseWhere,'else where'),'ELSE WHERE') - assert_equal(parse(ElseWhere,'elsewhere (1)'),'ELSE WHERE ( 1 )') - assert_equal(parse(ElseWhere,'elsewhere(a(1,2))'),'ELSE WHERE ( a(1,2) )') - - def check_enumerator(self): - assert_equal(parse(Enumerator,'enumerator a'), 'ENUMERATOR a') - assert_equal(parse(Enumerator,'enumerator:: a'), 'ENUMERATOR a') - assert_equal(parse(Enumerator,'enumerator a,b'), 'ENUMERATOR a, b') - assert_equal(parse(Enumerator,'enumerator a=1'), 'ENUMERATOR a=1') - assert_equal(parse(Enumerator,'enumerator a=1 , b=c(1,2)'), 'ENUMERATOR a=1, b=c(1,2)') - - def check_fortranname(self): - assert_equal(parse(FortranName,'fortranname a'),'FORTRANNAME a') - - def check_threadsafe(self): - assert_equal(parse(Threadsafe,'threadsafe'),'THREADSAFE') - - def check_depend(self): - assert_equal(parse(Depend,'depend( a) b'), 'DEPEND ( a ) b') - assert_equal(parse(Depend,'depend( a) ::b'), 'DEPEND ( a ) b') - assert_equal(parse(Depend,'depend( a,c) b,e'), 'DEPEND ( a, c ) b, e') - - def check_check(self): - assert_equal(parse(Check,'check(1) a'), 'CHECK ( 1 ) a') - assert_equal(parse(Check,'check(1) :: a'), 'CHECK ( 1 ) a') - assert_equal(parse(Check,'check(b(1,2)) a'), 'CHECK ( b(1,2) ) a') - assert_equal(parse(Check,'check(a>1) :: a'), 'CHECK ( a>1 ) a') - - def check_callstatement(self): - assert_equal(parse(CallStatement,'callstatement (*func)()',isstrict=1), - 'CALLSTATEMENT (*func)()') - assert_equal(parse(CallStatement,'callstatement i=1;(*func)()',isstrict=1), - 'CALLSTATEMENT i=1;(*func)()') - - def check_callprotoargument(self): - assert_equal(parse(CallProtoArgument,'callprotoargument int(*), double'), - 'CALLPROTOARGUMENT int(*), double') - - def check_pause(self): - assert_equal(parse(Pause,'pause'),'PAUSE') - assert_equal(parse(Pause,'pause 1'),'PAUSE 1') - assert_equal(parse(Pause,'pause "hey"'),'PAUSE "hey"') - assert_equal(parse(Pause,'pause "hey pa"'),'PAUSE "hey pa"') - - def check_integer(self): - assert_equal(parse(Integer,'integer'),'INTEGER') - assert_equal(parse(Integer,'integer*4'),'INTEGER(KIND=4)') - assert_equal(parse(Integer,'integer*4 a'),'INTEGER(KIND=4) a') - assert_equal(parse(Integer,'integer*4, a'),'INTEGER(KIND=4) a') - assert_equal(parse(Integer,'integer*4 a ,b'),'INTEGER(KIND=4) a, b') - assert_equal(parse(Integer,'integer*4 :: a ,b'),'INTEGER(KIND=4) a, b') - assert_equal(parse(Integer,'integer*4 a(1,2)'),'INTEGER(KIND=4) a(1,2)') - assert_equal(parse(Integer,'integer*4 :: a(1,2),b'),'INTEGER(KIND=4) a(1,2), b') - assert_equal(parse(Integer,'integer*4 external :: a'), - 'INTEGER(KIND=4), external :: a') - assert_equal(parse(Integer,'integer*4, external :: a'), - 'INTEGER(KIND=4), external :: a') - assert_equal(parse(Integer,'integer*4 external , intent(in) :: a'), - 'INTEGER(KIND=4), external, intent(in) :: a') - assert_equal(parse(Integer,'integer(kind=4)'),'INTEGER(KIND=4)') - assert_equal(parse(Integer,'integer ( kind = 4)'),'INTEGER(KIND=4)') - assert_equal(parse(Integer,'integer(kind=2+2)'),'INTEGER(KIND=2+2)') - assert_equal(parse(Integer,'integer(kind=f(4,5))'),'INTEGER(KIND=f(4,5))') - - def check_character(self): - assert_equal(parse(Character,'character'),'CHARACTER') - assert_equal(parse(Character,'character*2'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character**'),'CHARACTER(LEN=*)') - assert_equal(parse(Character,'character*(2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =2),'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =:)'),'CHARACTER(LEN=:)') - assert_equal(parse(Character,'character(len =2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character(2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character(kind=2)'),'CHARACTER(KIND=2)') - assert_equal(parse(Character,'character(kind=2,len=3)'), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'character(lEN=3,kind=2)'), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'character(len=3,kind=2)', isstrict=True), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'chaRACTER(len=3,kind=fA(1,2))', isstrict=True), - 'CHARACTER(LEN=3, KIND=fA(1,2))') - assert_equal(parse(Character,'character(len=3,kind=fA(1,2))'), - 'CHARACTER(LEN=3, KIND=fa(1,2))') - - def check_implicit(self): - assert_equal(parse(Implicit,'implicit none'),'IMPLICIT NONE') - assert_equal(parse(Implicit,'implicit'),'IMPLICIT NONE') - assert_equal(parse(Implicit,'implicit integer (i-m)'), - 'IMPLICIT INTEGER ( i-m )') - -if __name__ == "__main__": - NumpyTest().run() diff --git a/numpy/f2py/lib/typedecl_statements.py b/numpy/f2py/lib/typedecl_statements.py deleted file mode 100644 index 63b9a346e..000000000 --- a/numpy/f2py/lib/typedecl_statements.py +++ /dev/null @@ -1,409 +0,0 @@ - -import re -import string -from base_classes import Statement, BeginStatement, EndStatement,\ - AttributeHolder, Variable -from utils import split_comma, AnalyzeError, name_re, is_entity_decl - -# Intrinsic type specification statements - -class TypeDeclarationStatement(Statement): - """ - <declaration-type-spec> [ [, <attr-spec>] :: ] <entity-decl-list> - <declaration-type-spec> = <intrinsic-type-spec> - | TYPE ( <derived-type-spec> ) - | CLASS ( <derived-type-spec> ) - | CLASS ( * ) - - <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ] - <type-param-spec> = [ <keyword> = ] <type-param-value> - <type-param-value> = <scalar-int-expr> | * | : - - <intrinsic-type-spec> = INTEGER [<kind-selector>] - | REAL [<kind-selector>] - | DOUBLE PRECISION - | COMPLEX [<kind-selector>] - | CHARACTER [<char-selector>] - | LOGICAL [<kind-selector>] - - <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> ) - <char-selector> = <length-selector> - | ( LEN = <type-param-value>, KIND = <scalar-int-initialization-expr> ) - | ( <type-param-value>, [ KIND = ] <scalar-int-initialization-expr> ) - | ( KIND = <scalar-int-initialization-expr> [, LEN = <type-param-value>] ) - <length-selector> = ( [ LEN = ] <type-param-value> ) - | * <char-length> [ , ] - <char-length> = ( <type-param-value> ) | <scalar-int-literal-constant> - - <attr-spec> = <access-spec> | ALLOCATABLE | ASYNCHRONOUS - | DIMENSION ( <array-spec> ) | EXTERNAL - | INTENT ( <intent-spec> ) | INTRINSIC - | <language-binding-spec> | OPTIONAL - | PARAMETER | POINTER | PROTECTED | SAVE - | TARGET | VALUE | VOLATILE - <entity-decl> = <object-name> [ ( <array-spec> ) ] [ * <char-length> ] [ <initialization> ] - | <function-name> [ * <char-length> ] - <initialization> = = <initialization-expr> - | => NULL - <access-spec> = PUBLIC | PRIVATE - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr>] ) - <array-spec> = <explicit-shape-spec-list> - | <assumed-shape-spec-list> - | <deferred-shape-spec-list> - | <assumed-size-spec> - <explicit-shape-spec> = [ <lower-bound> : ] <upper-bound> - <assumed-shape-spec> = [ <lower-bound> ] : - <deferred-shape-spec> = : - <assumed-size-spec> = [ <explicit-shape-spec-list> , ] [ <lower-bound> : ] * - <bound> = <specification-expr> - - <int-literal-constant> = <digit-string> [ _ <kind-param> ] - <digit-string> = <digit> [ <digit> ].. - <kind-param> = <digit-string> | <scalar-int-constant-name> - """ - - def process_item(self): - item = self.item - apply_map = item.apply_map - clsname = self.__class__.__name__.lower() - line = item.get_line() - from block_statements import Function - - if not line.lower().startswith(clsname): - i = 0 - j = 0 - for c in line: - i += 1 - if c==' ': continue - j += 1 - if j==len(clsname): - break - line = line[:i].replace(' ','') + line[i:] - - assert line.lower().startswith(clsname),`line,clsname` - line = line[len(clsname):].lstrip() - - if line.startswith('('): - i = line.find(')') - selector = apply_map(line[:i+1].strip()) - line = line[i+1:].lstrip() - elif line.startswith('*'): - selector = '*' - line = line[1:].lstrip() - if line.startswith('('): - i = line.find(')') - selector += apply_map(line[:i+1].rstrip()) - line = line[i+1:].lstrip() - else: - m = re.match(r'\d+(_\w+|)|[*]',line) - if not m: - self.isvalid = False - return - i = m.end() - selector += line[:i].rstrip() - line = line[i:].lstrip() - else: - selector = '' - - fm = Function.match(line) - if fm: - l2 = line[:fm.end()] - m2 = re.match(r'.*?\b(?P<name>\w+)\Z',l2) - if not m2: - self.isvalid = False - return - fname = m2.group('name') - fitem = item.copy(clsname+selector+' :: '+fname, - apply_map=True) - self.parent.put_item(fitem) - item.clone(line) - self.isvalid = False - return - - if line.startswith(','): - line = line[1:].lstrip() - - self.raw_selector = selector - if isinstance(self, Character): - self.selector = self._parse_char_selector(selector) - else: - self.selector = self._parse_kind_selector(selector) - - i = line.find('::') - if i==-1: - self.attrspec = [] - self.entity_decls = split_comma(line, self.item) - else: - self.attrspec = split_comma(line[:i].rstrip(), self.item) - self.entity_decls = split_comma(line[i+2:].lstrip(), self.item) - for entity in self.entity_decls: - if not is_entity_decl(entity): - self.isvalid = False - return - - if isinstance(self.parent, Function) \ - and self.parent.name in self.entity_decls: - assert self.parent.typedecl is None,`self.parent.typedecl` - self.parent.typedecl = self - self.ignore = True - return - - def _parse_kind_selector(self, selector): - if not selector: - return '' - if selector.startswith('*'): - kind = selector[1:].lstrip() - else: - assert selector[0]+selector[-1]=='()',`selector` - l = selector[1:-1].strip() - if l.lower().startswith('kind'): - l = l[4:].lstrip() - assert l.startswith('='),`l` - kind = l[1:].lstrip() - else: - kind = l - return kind - - def _parse_char_selector(self, selector): - if not selector: - return '','' - if selector.startswith('*'): - l = selector[1:].lstrip() - if l.startswith('('): - if l.endswith(','): l = l[:-1].rstrip() - assert l.endswith(')'),`l` - l = l[1:-1].strip() - if l.lower().startswith('len'): - l = l[3:].lstrip()[1:].lstrip() - kind='' - else: - assert selector[0]+selector[-1]=='()',`selector` - l = split_comma(selector[1:-1].strip(), self.item) - if len(l)==1: - l = l[0] - if l.lower().startswith('len'): - l=l[3:].lstrip() - assert l.startswith('='),`l` - l=l[1:].lstrip() - kind = '' - elif l.lower().startswith('kind'): - kind = l[4:].lstrip()[1:].lstrip() - l = '' - else: - kind = '' - else: - assert len(l)==2 - if l[0].lower().startswith('len'): - assert l[1].lower().startswith('kind'),`l` - kind = l[1][4:].lstrip()[1:].lstrip() - l = l[0][3:].lstrip()[1:].lstrip() - elif l[0].lower().startswith('kind'): - assert l[1].lower().startswith('len'),`l` - kind = l[0][4:].lstrip()[1:].lstrip() - l = l[1][3:].lstrip()[1:].lstrip() - else: - if l[1].lower().startswith('kind'): - kind = l[1][4:].lstrip()[1:].lstrip() - l = l[0] - else: - kind = l[1] - l = l[0] - return l,kind - - def tostr(self): - clsname = self.__class__.__name__.upper() - s = '' - if isinstance(self, Character): - length, kind = self.selector - if length and kind: - s += '(LEN=%s, KIND=%s)' % (length,kind) - elif length: - s += '(LEN=%s)' % (length) - elif kind: - s += '(KIND=%s)' % (kind) - else: - kind = self.selector - if kind: - s += '(KIND=%s)' % (kind) - return clsname + s - - def __str__(self): - tab = self.get_indent_tab() - s = self.tostr() - if self.attrspec: - s += ', ' + ', '.join(self.attrspec) - if self.entity_decls: - s += ' ::' - if self.entity_decls: - s += ' ' + ', '.join(self.entity_decls) - return tab + s - - def __eq__(self, other): - if self.__class__ is not other.__class__: - return False - return self.selector==other.selector - - def astypedecl(self): - return self.__class__(self.parent, self.item.copy(self.tostr())) - - def analyze(self): - if not self.entity_decls: - return - variables = self.parent.a.variables - typedecl = self.astypedecl() - for item in self.entity_decls: - name, array_spec, char_length, value = self._parse_entity(item) - if not variables.has_key(name): - variables[name] = var = Variable(self, name) - else: - var = variables[name] - var.add_parent(self) - if char_length: - var.set_length(char_length) - else: - var.set_type(typedecl) - var.update(self.attrspec) - if array_spec: - var.set_bounds(array_spec) - if value: - var.set_init(value) - return - - def _parse_entity(self, line): - m = name_re(line) - assert m,`line,self.item,self.__class__.__name__` - name = line[:m.end()] - line = line[m.end():].lstrip() - array_spec = None - item = self.item.copy(line) - line = item.get_line() - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - array_spec = split_comma(line[1:i].strip(), item) - line = line[i+1:].lstrip() - char_length = None - if line.startswith('*'): - i = line.find('=') - if i==-1: - char_length = item.apply_map(line[1:].lstrip()) - line = '' - else: - char_length = item.apply_map(line[1:i].strip()) - line = line[i:] - value = None - if line.startswith('='): - value = item.apply_map(line[1:].lstrip()) - return name, array_spec, char_length, value - -class Integer(TypeDeclarationStatement): - match = re.compile(r'integer\b',re.I).match - -class Real(TypeDeclarationStatement): - match = re.compile(r'real\b',re.I).match - -class DoublePrecision(TypeDeclarationStatement): - match = re.compile(r'double\s*precision\b',re.I).match - -class Complex(TypeDeclarationStatement): - match = re.compile(r'complex\b',re.I).match - -class DoubleComplex(TypeDeclarationStatement): - # not in standard - match = re.compile(r'double\s*complex\b',re.I).match - -class Logical(TypeDeclarationStatement): - match = re.compile(r'logical\b',re.I).match - -class Character(TypeDeclarationStatement): - match = re.compile(r'character\b',re.I).match - -class Byte(TypeDeclarationStatement): - # not in standard - match = re.compile(r'byte\b',re.I).match - -class Type(TypeDeclarationStatement): - match = re.compile(r'type\s*\(', re.I).match -TypeStmt = Type - -class Class(TypeDeclarationStatement): - match = re.compile(r'class\s*\(', re.I).match - -class Implicit(Statement): - """ - IMPLICIT <implicit-spec-list> - IMPLICIT NONE - <implicit-spec> = <declaration-type-spec> ( <letter-spec-list> ) - <letter-spec> = <letter> [ - <letter> ] - """ - match = re.compile(r'implicit\b',re.I).match - - letters = string.lowercase - - def process_item(self): - line = self.item.get_line()[8:].lstrip() - if line.lower()=='none': - self.items = [] - return - items = [] - for item in split_comma(line, self.item): - i = item.find('(') - assert i!=-1 and item.endswith(')'),`item` - specs = [] - for spec in split_comma(item[i+1:-1].strip(), self.item): - if '-' in spec: - s,e = spec.lower().split('-') - assert s in self.letters and e in self.letters - else: - e = s = spec.lower() - assert s in self.letters - specs.append((s,e)) - self.specs = specs - tspec = item[:i].rstrip() - stmt = None - for cls in declaration_type_spec: - if cls.match(tspec): - stmt = cls(self, self.item.copy(tspec)) - if stmt.isvalid: - break - assert stmt is not None,`item,line` - items.append((stmt,specs)) - self.items = items - return - - def __str__(self): - tab = self.get_indent_tab() - if not self.items: - return tab + 'IMPLICIT NONE' - l = [] - for stmt,specs in self.items: - l1 = [] - for s,e in specs: - if s==e: - l1.append(s) - else: - l1.append(s + '-' + e) - l.append('%s ( %s )' % (stmt.tostr(), ', '.join(l1))) - return tab + 'IMPLICIT ' + ', '.join(l) - - def analyze(self): - implicit_rules = self.parent.a.implicit_rules - if not self.items: - if implicit_rules: - raise AnalyzeError,'IMPLICIT NONE implies emtpy implicit_rules'\ - ' but got %r' % (implicit_rules) - return - if implicit_rules is None: - self.parent.a.implicit_rules = implicit_rules = {} - for stmt,specs in self.items: - s,e = specs - for l in string.lowercase[string.lowercase.index(s.lower()):\ - string.lowercase.index(e.lower())+1]: - implicit_rules[l] = stmt - return - -intrinsic_type_spec = [ \ - Integer , Real, - DoublePrecision, Complex, DoubleComplex, Character, Logical, Byte - ] -declaration_type_spec = intrinsic_type_spec + [ TypeStmt, Class ] diff --git a/numpy/f2py/lib/utils.py b/numpy/f2py/lib/utils.py deleted file mode 100644 index 7a194c9c7..000000000 --- a/numpy/f2py/lib/utils.py +++ /dev/null @@ -1,125 +0,0 @@ - -import re -import os, glob - -class ParseError(Exception): - pass - -class AnalyzeError(Exception): - pass - -is_name = re.compile(r'^[a-z_]\w*$',re.I).match -name_re = re.compile(r'[a-z_]\w*',re.I).match -is_entity_decl = re.compile(r'^[a-z_]\w*',re.I).match -is_int_literal_constant = re.compile(r'^\d+(_\w+|)$').match - -def split_comma(line, item = None, comma=','): - items = [] - if item is None: - for s in line.split(comma): - s = s.strip() - if not s: continue - items.append(s) - return items - newitem = item.copy(line, True) - apply_map = newitem.apply_map - for s in newitem.get_line().split(comma): - s = apply_map(s).strip() - if not s: continue - items.append(s) - return items - -def specs_split_comma(line, item = None, upper=False): - specs0 = split_comma(line, item) - specs = [] - for spec in specs0: - i = spec.find('=') - if i!=-1: - kw = spec[:i].strip().upper() - v = spec[i+1:].strip() - specs.append('%s = %s' % (kw, v)) - else: - if upper: - spec = spec.upper() - specs.append(spec) - return specs - -def parse_bind(line, item = None): - if not line.lower().startswith('bind'): - return None, line - if item is not None: - newitem = item.copy(line, apply_map=True) - newline = newitem.get_line() - else: - newitem = None - newline = newline[4:].lstrip() - i = newline.find(')') - assert i!=-1,`newline` - args = [] - for a in specs_split_comma(newline[1:i].strip(), newitem, upper=True): - args.append(a) - rest = newline[i+1:].lstrip() - if item is not None: - rest = newitem.apply_map(rest) - return args, rest - -def parse_result(line, item = None): - if not line.lower().startswith('result'): - return None, line - line = line[6:].lstrip() - i = line.find(')') - assert i != -1,`line` - name = line[1:i].strip() - assert is_name(name),`name` - return name, line[i+1:].lstrip() - -def filter_stmts(content, classes): - stmts = [] - indices = [] - for i in range(len(content)): - stmt = content[i] - if isinstance(stmt, classes): - stmts.append(stmt) - indices.append(i) - indices.reverse() - for i in indices: - del content[i] - return stmts - - -def get_module_files(directory, _cache={}): - if _cache.has_key(directory): - return _cache[directory] - module_line = re.compile(r'(\A|^)module\s+(?P<name>\w+)\s*(!.*|)$',re.I | re.M) - d = {} - for fn in glob.glob(os.path.join(directory,'*.f90')): - f = open(fn,'r') - for name in module_line.findall(f.read()): - name = name[1] - if d.has_key(name): - print d[name],'already defines',name - continue - d[name] = fn - _cache[directory] = d - return d - -def get_module_file(name, directory, _cache={}): - fn = _cache.get(name, None) - if fn is not None: - return fn - if name.endswith('_module'): - f1 = os.path.join(directory,name[:-7]+'.f90') - if os.path.isfile(f1): - _cache[name] = fn - return f1 - pattern = re.compile(r'\s*module\s+(?P<name>[a-z]\w*)', re.I).match - for fn in glob.glob(os.path.join(directory,'*.f90')): - f = open(fn,'r') - for line in f: - m = pattern(line) - if m and m.group('name')==name: - _cache[name] = fn - f.close() - return fn - f.close() - return diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py deleted file mode 100644 index 9d828aea2..000000000 --- a/numpy/f2py/rules.py +++ /dev/null @@ -1,1344 +0,0 @@ -#!/usr/bin/env python -""" - -Rules for building C/API module with f2py2e. - -Here is a skeleton of a new wrapper function (13Dec2001): - -wrapper_function(args) - declarations - get_python_arguments, say, `a' and `b' - - get_a_from_python - if (successful) { - - get_b_from_python - if (successful) { - - callfortran - if (succesful) { - - put_a_to_python - if (succesful) { - - put_b_to_python - if (succesful) { - - buildvalue = ... - - } - - } - - } - - } - cleanup_b - - } - cleanup_a - - return buildvalue -""" -""" -Copyright 1999,2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2005/08/30 08:58:42 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.129 $"[10:-1] - -import __version__ -f2py_version = __version__.version - -import pprint -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -import capi_maps -from capi_maps import * -import cfuncs -import common_rules -import use_rules -import f90mod_rules -import func2subr -options={} - -sepdict={} -#for k in ['need_cfuncs']: sepdict[k]=',' -for k in ['decl', - 'frompyobj', - 'cleanupfrompyobj', - 'topyarr','method', - 'pyobjfrom','closepyobjfrom', - 'freemem', - 'userincludes', - 'includes0','includes','typedefs','typedefs_generated', - 'cppmacros','cfuncs','callbacks', - 'latexdoc', - 'restdoc', - 'routine_defs','externroutines', - 'initf2pywraphooks', - 'commonhooks','initcommonhooks', - 'f90modhooks','initf90modhooks']: - sepdict[k]='\n' - -#################### Rules for C/API module ################# - -module_rules={ - 'modulebody':"""\ -/* File: #modulename#module.c - * This file is auto-generated with f2py (version:#f2py_version#). - * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition, - * written by Pearu Peterson <pearu@cens.ioc.ee>. - * See http://cens.ioc.ee/projects/f2py2e/ - * Generation date: """+time.asctime(time.localtime(time.time()))+""" - * $R"""+"""evision:$ - * $D"""+"""ate:$ - * Do not edit this file directly unless you know what you are doing!!! - */ -#ifdef __cplusplus -extern \"C\" { -#endif - -"""+gentitle("See f2py2e/cfuncs.py: includes")+""" -#includes# -#includes0# - -"""+gentitle("See f2py2e/rules.py: mod_rules['modulebody']")+""" -static PyObject *#modulename#_error; -static PyObject *#modulename#_module; - -"""+gentitle("See f2py2e/cfuncs.py: typedefs")+""" -#typedefs# - -"""+gentitle("See f2py2e/cfuncs.py: typedefs_generated")+""" -#typedefs_generated# - -"""+gentitle("See f2py2e/cfuncs.py: cppmacros")+""" -#cppmacros# - -"""+gentitle("See f2py2e/cfuncs.py: cfuncs")+""" -#cfuncs# - -"""+gentitle("See f2py2e/cfuncs.py: userincludes")+""" -#userincludes# - -"""+gentitle("See f2py2e/capi_rules.py: usercode")+""" -#usercode# - -/* See f2py2e/rules.py */ -#externroutines# - -"""+gentitle("See f2py2e/capi_rules.py: usercode1")+""" -#usercode1# - -"""+gentitle("See f2py2e/cb_rules.py: buildcallback")+""" -#callbacks# - -"""+gentitle("See f2py2e/rules.py: buildapi")+""" -#body# - -"""+gentitle("See f2py2e/f90mod_rules.py: buildhooks")+""" -#f90modhooks# - -"""+gentitle("See f2py2e/rules.py: module_rules['modulebody']")+""" - -"""+gentitle("See f2py2e/common_rules.py: buildhooks")+""" -#commonhooks# - -"""+gentitle("See f2py2e/rules.py")+""" - -static FortranDataDef f2py_routine_defs[] = { -#routine_defs# -\t{NULL} -}; - -static PyMethodDef f2py_module_methods[] = { -#pymethoddef# -\t{NULL,NULL} -}; - -PyMODINIT_FUNC init#modulename#(void) { -\tint i; -\tPyObject *m,*d, *s; -\tm = #modulename#_module = Py_InitModule(\"#modulename#\", f2py_module_methods); -\tPyFortran_Type.ob_type = &PyType_Type; -\timport_array(); -\tif (PyErr_Occurred()) -\t\tPy_FatalError(\"can't initialize module #modulename# (failed to import numpy)\"); -\td = PyModule_GetDict(m); -\ts = PyString_FromString(\"$R"""+"""evision: $\"); -\tPyDict_SetItemString(d, \"__version__\", s); -\ts = PyString_FromString(\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\"); -\tPyDict_SetItemString(d, \"__doc__\", s); -\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL); -\tPy_DECREF(s); -\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) -\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name,PyFortranObject_NewAsAttr(&f2py_routine_defs[i])); -#initf2pywraphooks# -#initf90modhooks# -#initcommonhooks# -#interface_usercode# - -#ifdef F2PY_REPORT_ATEXIT -\tif (! PyErr_Occurred()) -\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\"); -#endif - -} -#ifdef __cplusplus -} -#endif -""", - 'separatorsfor':{'latexdoc':'\n\n', - 'restdoc':'\n\n'}, - 'latexdoc':['\\section{Module \\texttt{#texmodulename#}}\n', - '#modnote#\n', - '#latexdoc#'], - 'restdoc':['Module #modulename#\n'+'='*80, - '\n#restdoc#'] - } - -defmod_rules=[ - {'body':'/*eof body*/', - 'method':'/*eof method*/', - 'externroutines':'/*eof externroutines*/', - 'routine_defs':'/*eof routine_defs*/', - 'initf90modhooks':'/*eof initf90modhooks*/', - 'initf2pywraphooks':'/*eof initf2pywraphooks*/', - 'initcommonhooks':'/*eof initcommonhooks*/', - 'latexdoc':'', - 'restdoc':'', - 'modnote':{hasnote:'#note#',l_not(hasnote):''}, - } - ] - -routine_rules={ - 'separatorsfor':sepdict, - 'body':""" -#begintitle# -static char doc_#apiname#[] = \"\\\nFunction signature:\\n\\\n\t#docreturn##name#(#docsignatureshort#)\\n\\\n#docstrsigns#\"; -/* #declfortranroutine# */ -static PyObject *#apiname#(const PyObject *capi_self, - PyObject *capi_args, - PyObject *capi_keywds, - #functype# (*f2py_func)(#callprotoargument#)) { -\tPyObject * volatile capi_buildvalue = NULL; -\tvolatile int f2py_success = 1; -#decl# -\tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL}; -#usercode# -#routdebugenter# -#ifdef F2PY_REPORT_ATEXIT -f2py_start_clock(); -#endif -\tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\ -\t\t\"#argformat#|#keyformat##xaformat#:#pyname#\",\\ -\t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL; -#frompyobj# -/*end of frompyobj*/ -#ifdef F2PY_REPORT_ATEXIT -f2py_start_call_clock(); -#endif -#callfortranroutine# -if (PyErr_Occurred()) - f2py_success = 0; -#ifdef F2PY_REPORT_ATEXIT -f2py_stop_call_clock(); -#endif -/*end of callfortranroutine*/ -\t\tif (f2py_success) { -#pyobjfrom# -/*end of pyobjfrom*/ -\t\tCFUNCSMESS(\"Building return value.\\n\"); -\t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#); -/*closepyobjfrom*/ -#closepyobjfrom# -\t\t} /*if (f2py_success) after callfortranroutine*/ -/*cleanupfrompyobj*/ -#cleanupfrompyobj# -\tif (capi_buildvalue == NULL) { -#routdebugfailure# -\t} else { -#routdebugleave# -\t} -\tCFUNCSMESS(\"Freeing memory.\\n\"); -#freemem# -#ifdef F2PY_REPORT_ATEXIT -f2py_stop_clock(); -#endif -\treturn capi_buildvalue; -} -#endtitle# -""", - 'routine_defs':'#routine_def#', - 'initf2pywraphooks':'#initf2pywraphook#', - 'externroutines':'#declfortranroutine#', - 'doc':'#docreturn##name#(#docsignature#)', - 'docshort':'#docreturn##name#(#docsignatureshort#)', - 'docs':'"\t#docreturn##name#(#docsignature#)\\n"\n', - 'need':['arrayobject.h','CFUNCSMESS','MINMAX'], - 'cppmacros':{debugcapi:'#define DEBUGCFUNCS'}, - 'latexdoc':['\\subsection{Wrapper function \\texttt{#texname#}}\n', - """ -\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)} -#routnote# - -#latexdocstrsigns# -"""], - 'restdoc':['Wrapped function ``#name#``\n'+'-'*80, - - ] - } - -################## Rules for C/API function ############## - -rout_rules=[ - { # Init - 'separatorsfor': {'callfortranroutine':'\n','routdebugenter':'\n','decl':'\n', - 'routdebugleave':'\n','routdebugfailure':'\n', - 'setjmpbuf':' || ', - 'docstrreq':'\n','docstropt':'\n','docstrout':'\n', - 'docstrcbs':'\n','docstrsigns':'\\n"\n"', - 'latexdocstrsigns':'\n', - 'latexdocstrreq':'\n','latexdocstropt':'\n', - 'latexdocstrout':'\n','latexdocstrcbs':'\n', - }, - 'kwlist':'','kwlistopt':'','callfortran':'','callfortranappend':'', - 'docsign':'','docsignopt':'','decl':'/*decl*/', - 'freemem':'/*freemem*/', - 'docsignshort':'','docsignoptshort':'', - 'docstrsigns':'','latexdocstrsigns':'', - 'docstrreq':'Required arguments:', - 'docstropt':'Optional arguments:', - 'docstrout':'Return objects:', - 'docstrcbs':'Call-back functions:', - 'latexdocstrreq':'\\noindent Required arguments:', - 'latexdocstropt':'\\noindent Optional arguments:', - 'latexdocstrout':'\\noindent Return objects:', - 'latexdocstrcbs':'\\noindent Call-back functions:', - 'args_capi':'','keys_capi':'','functype':'', - 'frompyobj':'/*frompyobj*/', - 'cleanupfrompyobj':['/*end of cleanupfrompyobj*/'], #this list will be reversed - 'pyobjfrom':'/*pyobjfrom*/', - 'closepyobjfrom':['/*end of closepyobjfrom*/'], #this list will be reversed - 'topyarr':'/*topyarr*/','routdebugleave':'/*routdebugleave*/', - 'routdebugenter':'/*routdebugenter*/', - 'routdebugfailure':'/*routdebugfailure*/', - 'callfortranroutine':'/*callfortranroutine*/', - 'argformat':'','keyformat':'','need_cfuncs':'', - 'docreturn':'','return':'','returnformat':'','rformat':'', - 'kwlistxa':'','keys_xa':'','xaformat':'','docsignxa':'','docsignxashort':'', - 'initf2pywraphook':'', - 'routnote':{hasnote:'--- #note#',l_not(hasnote):''}, - },{ - 'apiname':'f2py_rout_#modulename#_#name#', - 'pyname':'#modulename#.#name#', - 'decl':'', - '_check':l_not(ismoduleroutine) - },{ - 'apiname':'f2py_rout_#modulename#_#f90modulename#_#name#', - 'pyname':'#modulename#.#f90modulename#.#name#', - 'decl':'', - '_check':ismoduleroutine - },{ # Subroutine - 'functype':'void', - 'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', - l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern void #fortranname#(#callprotoargument#);', - ismoduleroutine:'', - isdummyroutine:'' - }, - 'routine_def':{l_not(l_or(ismoduleroutine,isintent_c,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', - l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', - l_and(l_not(ismoduleroutine),isdummyroutine):'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', - }, - 'need':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'F_FUNC'}, - 'callfortranroutine':[ - {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]}, - {hasexternals:"""\ -\t\tif (#setjmpbuf#) { -\t\t\tf2py_success = 0; -\t\t} else {"""}, - {isthreadsafe:'\t\t\tPy_BEGIN_ALLOW_THREADS'}, - {hascallstatement:'''\t\t\t\t#callstatement#; -\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''}, - {l_not(l_or(hascallstatement,isdummyroutine)):'\t\t\t\t(*f2py_func)(#callfortran#);'}, - {isthreadsafe:'\t\t\tPy_END_ALLOW_THREADS'}, - {hasexternals:"""\t\t}"""} - ], - '_check':issubroutine, - },{ # Wrapped function - 'functype':'void', - 'declfortranroutine':{l_not(l_or(ismoduleroutine,isdummyroutine)):'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);', - isdummyroutine:'', - }, - - 'routine_def':{l_not(l_or(ismoduleroutine,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},', - isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', - }, - 'initf2pywraphook':{l_not(l_or(ismoduleroutine,isdummyroutine)):''' - { - extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void); - PyObject* o = PyDict_GetItemString(d,"#name#"); - PyObject_SetAttrString(o,"_cpointer", PyCObject_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL)); - } - '''}, - 'need':{l_not(l_or(ismoduleroutine,isdummyroutine)):['F_WRAPPEDFUNC','F_FUNC']}, - 'callfortranroutine':[ - {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]}, - {hasexternals:"""\ -\tif (#setjmpbuf#) { -\t\tf2py_success = 0; -\t} else {"""}, - {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'}, - {l_not(l_or(hascallstatement,isdummyroutine)):'\t(*f2py_func)(#callfortran#);'}, - {hascallstatement:'\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'}, - {isthreadsafe:'\tPy_END_ALLOW_THREADS'}, - {hasexternals:'\t}'} - ], - '_check':isfunction_wrap, - },{ # Function - 'functype':'#ctype#', - 'docreturn':{l_not(isintent_hide):'#rname#,'}, - 'docstrout':'\t#pydocsignout#', - 'latexdocstrout':['\\item[]{{}\\verb@#pydocsignout#@{}}', - {hasresultnote:'--- #resultnote#'}], - 'callfortranroutine':[{l_and(debugcapi,isstringfunction):"""\ -#ifdef USESCOMPAQFORTRAN -\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\"); -#else -\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); -#endif -"""}, - {l_and(debugcapi,l_not(isstringfunction)):"""\ -\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); -"""} - ], - '_check':l_and(isfunction,l_not(isfunction_wrap)) - },{ # Scalar function - 'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', - l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern #ctype# #fortranname#(#callprotoargument#);', - isdummyroutine:'' - }, - 'routine_def':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', - l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', - isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', - }, - 'decl':[{iscomplexfunction_warn:'\t#ctype# #name#_return_value={0,0};', - l_not(iscomplexfunction):'\t#ctype# #name#_return_value=0;'}, - {iscomplexfunction:'\tPyObject *#name#_return_value_capi = Py_None;'} - ], - 'callfortranroutine':[ - {hasexternals:"""\ -\tif (#setjmpbuf#) { -\t\tf2py_success = 0; -\t} else {"""}, - {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'}, - {hascallstatement:'''\t#callstatement#; -/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/ -'''}, - {l_not(l_or(hascallstatement,isdummyroutine)):'\t#name#_return_value = (*f2py_func)(#callfortran#);'}, - {isthreadsafe:'\tPy_END_ALLOW_THREADS'}, - {hasexternals:'\t}'}, - {l_and(debugcapi,iscomplexfunction):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'}, - {l_and(debugcapi,l_not(iscomplexfunction)):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}], - 'pyobjfrom':{iscomplexfunction:'\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'}, - 'need':[{l_not(isdummyroutine):'F_FUNC'}, - {iscomplexfunction:'pyobj_from_#ctype#1'}, - {islong_longfunction:'long_long'}, - {islong_doublefunction:'long_double'}], - 'returnformat':{l_not(isintent_hide):'#rformat#'}, - 'return':{iscomplexfunction:',#name#_return_value_capi', - l_not(l_or(iscomplexfunction,isintent_hide)):',#name#_return_value'}, - '_check':l_and(isfunction,l_not(isstringfunction),l_not(isfunction_wrap)) - },{ # String function # in use for --no-wrap - 'declfortranroutine':'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', - 'routine_def':{l_not(l_or(ismoduleroutine,isintent_c)): -# '\t{\"#name#\",-1,{{-1}},0,(char *)F_FUNC(#fortranname#,#FORTRANNAME#),(void *)#apiname#,doc_#apiname#},', - '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', - l_and(l_not(ismoduleroutine),isintent_c): -# '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(void *)#apiname#,doc_#apiname#},' - '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},' - }, - 'decl':['\t#ctype# #name#_return_value = NULL;', - '\tint #name#_return_value_len = 0;'], - 'callfortran':'#name#_return_value,#name#_return_value_len,', - 'callfortranroutine':['\t#name#_return_value_len = #rlength#;', - '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {', - '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");', - '\t\tf2py_success = 0;', - '\t} else {', - "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';", - '\t}', - '\tif (f2py_success) {', - {hasexternals:"""\ -\t\tif (#setjmpbuf#) { -\t\t\tf2py_success = 0; -\t\t} else {"""}, - {isthreadsafe:'\t\tPy_BEGIN_ALLOW_THREADS'}, - """\ -#ifdef USESCOMPAQFORTRAN -\t\t(*f2py_func)(#callcompaqfortran#); -#else -\t\t(*f2py_func)(#callfortran#); -#endif -""", - {isthreadsafe:'\t\tPy_END_ALLOW_THREADS'}, - {hasexternals:'\t\t}'}, - {debugcapi:'\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'}, - '\t} /* if (f2py_success) after (string)malloc */', - ], - 'returnformat':'#rformat#', - 'return':',#name#_return_value', - 'freemem':'\tSTRINGFREE(#name#_return_value);', - 'need':['F_FUNC','#ctype#','STRINGFREE'], - '_check':l_and(isstringfunction,l_not(isfunction_wrap)) # ???obsolete - }, - { # Debugging - 'routdebugenter':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");', - 'routdebugleave':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");', - 'routdebugfailure':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");', - '_check':debugcapi - } - ] - -################ Rules for arguments ################## - -typedef_need_dict = {islong_long:'long_long', - islong_double:'long_double', - islong_complex:'complex_long_double', - isunsigned_char:'unsigned_char', - isunsigned_short:'unsigned_short', - isunsigned:'unsigned', - isunsigned_long_long:'unsigned_long_long'} - -aux_rules=[ - { - 'separatorsfor':sepdict - }, - { # Common - 'frompyobj':['\t/* Processing auxiliary variable #varname# */', - {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},], - 'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */', - 'need':typedef_need_dict, - }, -# Scalars (not complex) - { # Common - 'decl':'\t#ctype# #varname# = 0;', - 'need':{hasinitvalue:'math.h'}, - 'frompyobj':{hasinitvalue:'\t#varname# = #init#;'}, - '_check':l_and(isscalar,l_not(iscomplex)), - }, - { - 'return':',#varname#', - 'docstrout':'\t#pydocsignout#', - 'docreturn':'#outvarname#,', - 'returnformat':'#varrformat#', - '_check':l_and(isscalar,l_not(iscomplex),isintent_out), - }, -# Complex scalars - { # Common - 'decl':'\t#ctype# #varname#;', - 'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, - '_check':iscomplex - }, -# String - { # Common - 'decl':['\t#ctype# #varname# = NULL;', - '\tint slen(#varname#);', - ], - 'need':['len..'], - '_check':isstring - }, -# Array - { # Common - 'decl':['\t#ctype# *#varname# = NULL;', - '\tintp #varname#_Dims[#rank#] = {#rank*[-1]#};', - '\tconst int #varname#_Rank = #rank#;', - ], - 'need':['len..',{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}], - '_check':isarray - }, -# Scalararray - { # Common - '_check':l_and(isarray,l_not(iscomplexarray)) - },{ # Not hidden - '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide) - }, -# Integer*1 array - {'need':'#ctype#', - '_check':isint1array, - '_depend':'' - }, -# Integer*-1 array - {'need':'#ctype#', - '_check':isunsigned_chararray, - '_depend':'' - }, -# Integer*-2 array - {'need':'#ctype#', - '_check':isunsigned_shortarray, - '_depend':'' - }, -# Integer*-8 array - {'need':'#ctype#', - '_check':isunsigned_long_longarray, - '_depend':'' - }, -# Complexarray - {'need':'#ctype#', - '_check':iscomplexarray, - '_depend':'' - }, -# Stringarray - { - 'callfortranappend':{isarrayofstrings:'flen(#varname#),'}, - 'need':'string', - '_check':isstringarray - } - ] - -arg_rules=[ - { - 'separatorsfor':sepdict - }, - { # Common - 'frompyobj':['\t/* Processing variable #varname# */', - {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},], - 'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */', - '_depend':'', - 'need':typedef_need_dict, - }, -# Doc signatures - { - 'docstropt':{l_and(isoptional,isintent_nothide):'\t#pydocsign#'}, - 'docstrreq':{l_and(isrequired,isintent_nothide):'\t#pydocsign#'}, - 'docstrout':{isintent_out:'\t#pydocsignout#'}, - 'latexdocstropt':{l_and(isoptional,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}', - {hasnote:'--- #note#'}]}, - 'latexdocstrreq':{l_and(isrequired,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}', - {hasnote:'--- #note#'}]}, - 'latexdocstrout':{isintent_out:['\\item[]{{}\\verb@#pydocsignout#@{}}', - {l_and(hasnote,isintent_hide):'--- #note#', - l_and(hasnote,isintent_nothide):'--- See above.'}]}, - 'depend':'' - }, -# Required/Optional arguments - { - 'kwlist':'"#varname#",', - 'docsign':'#varname#,', - '_check':l_and(isintent_nothide,l_not(isoptional)) - }, - { - 'kwlistopt':'"#varname#",', - 'docsignopt':'#varname#=#showinit#,', - 'docsignoptshort':'#varname#,', - '_check':l_and(isintent_nothide,isoptional) - }, -# Docstring/BuildValue - { - 'docreturn':'#outvarname#,', - 'returnformat':'#varrformat#', - '_check':isintent_out - }, -# Externals (call-back functions) - { # Common - 'docsignxa':{isintent_nothide:'#varname#_extra_args=(),'}, - 'docsignxashort':{isintent_nothide:'#varname#_extra_args,'}, - 'docstropt':{isintent_nothide:'\t#varname#_extra_args := () input tuple'}, - 'docstrcbs':'#cbdocstr#', - 'latexdocstrcbs':'\\item[] #cblatexdocstr#', - 'latexdocstropt':{isintent_nothide:'\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'}, - 'decl':['\tPyObject *#varname#_capi = Py_None;', - '\tPyTupleObject *#varname#_xa_capi = NULL;', - '\tPyTupleObject *#varname#_args_capi = NULL;', - '\tint #varname#_nofargs_capi = 0;', - {l_not(isintent_callback):'\t#cbname#_typedef #varname#_cptr;'} - ], - 'kwlistxa':{isintent_nothide:'"#varname#_extra_args",'}, - 'argformat':{isrequired:'O'}, - 'keyformat':{isoptional:'O'}, - 'xaformat':{isintent_nothide:'O!'}, - 'args_capi':{isrequired:',&#varname#_capi'}, - 'keys_capi':{isoptional:',&#varname#_capi'}, - 'keys_xa':',&PyTuple_Type,&#varname#_xa_capi', - 'setjmpbuf':'(setjmp(#cbname#_jmpbuf))', - 'callfortran':{l_not(isintent_callback):'#varname#_cptr,'}, - 'need':['#cbname#','setjmp.h'], - '_check':isexternal - }, - { - 'frompyobj':[{l_not(isintent_callback):"""\ -if(PyCObject_Check(#varname#_capi)) { - #varname#_cptr = PyCObject_AsVoidPtr(#varname#_capi); -} else { - #varname#_cptr = #cbname#; -} -"""},{isintent_callback:"""\ -if (#varname#_capi==Py_None) { - #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\"); - if (#varname#_capi) { - if (#varname#_xa_capi==NULL) { - if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) { - PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\"); - if (capi_tmp) - #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp); - else - #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\"); - if (#varname#_xa_capi==NULL) { - PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\"); - return NULL; - } - } - } - } - if (#varname#_capi==NULL) { - PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\"); - return NULL; - } -} -"""}, -## {l_not(isintent_callback):"""\ -## if (#varname#_capi==Py_None) { -## printf(\"hoi\\n\"); -## } -## """}, -"""\ -\t#varname#_nofargs_capi = #cbname#_nofargs; -\tif (create_cb_arglist(#varname#_capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#cbname#_nofargs,&#varname#_args_capi,\"failed in processing argument list for call-back #varname#.\")) { -\t\tjmp_buf #varname#_jmpbuf;""", -{debugcapi:["""\ -\t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs); -\t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""", -{l_not(isintent_callback):"""\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]}, - """\ -\t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\"); -\t\tSWAP(#varname#_capi,#cbname#_capi,PyObject); -\t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject); -\t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""", - ], -'cleanupfrompyobj': -"""\ -\t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\"); -\t\t#cbname#_capi = #varname#_capi; -\t\tPy_DECREF(#cbname#_args_capi); -\t\t#cbname#_args_capi = #varname#_args_capi; -\t\t#cbname#_nofargs = #varname#_nofargs_capi; -\t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf)); -\t}""", - 'need':['SWAP','create_cb_arglist'], - '_check':isexternal, - '_depend':'' - }, -# Scalars (not complex) - { # Common - 'decl':'\t#ctype# #varname# = 0;', - 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, - 'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'}, - 'return':{isintent_out:',#varname#'}, - '_check':l_and(isscalar,l_not(iscomplex)) - },{ - 'need':{hasinitvalue:'math.h'}, - '_check':l_and(isscalar,l_not(iscomplex)), - #'_depend':'' - },{ # Not hidden - 'decl':'\tPyObject *#varname#_capi = Py_None;', - 'argformat':{isrequired:'O'}, - 'keyformat':{isoptional:'O'}, - 'args_capi':{isrequired:',&#varname#_capi'}, - 'keys_capi':{isoptional:',&#varname#_capi'}, - 'pyobjfrom':{isintent_inout:"""\ -\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); -\tif (f2py_success) {"""}, - 'closepyobjfrom':{isintent_inout:"\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, - 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, - '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide) - },{ - 'frompyobj':[ -# hasinitvalue... -# if pyobj is None: -# varname = init -# else -# from_pyobj(varname) -# -# isoptional and noinitvalue... -# if pyobj is not None: -# from_pyobj(varname) -# else: -# varname is uninitialized -# -# ... -# from_pyobj(varname) -# - {hasinitvalue:'\tif (#varname#_capi == Py_None) #varname# = #init#; else', - '_depend':''}, - {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)', - '_depend':''}, - {l_not(islogical):'''\ -\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#"); -\tif (f2py_success) {'''}, - {islogical:'''\ -\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi); -\t\tf2py_success = 1; -\tif (f2py_success) {'''}, - ], - 'cleanupfrompyobj':'\t} /*if (f2py_success) of #varname#*/', - 'need':{l_not(islogical):'#ctype#_from_pyobj'}, - '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide), - '_depend':'' -# },{ # Hidden -# '_check':l_and(isscalar,l_not(iscomplex),isintent_hide) - },{ # Hidden - 'frompyobj':{hasinitvalue:'\t#varname# = #init#;'}, - 'need':typedef_need_dict, - '_check':l_and(isscalar,l_not(iscomplex),isintent_hide), - '_depend':'' - },{ # Common - 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, - '_check':l_and(isscalar,l_not(iscomplex)), - '_depend':'' - }, -# Complex scalars - { # Common - 'decl':'\t#ctype# #varname#;', - 'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'}, - 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, - 'return':{isintent_out:',#varname#_capi'}, - '_check':iscomplex - },{ # Not hidden - 'decl':'\tPyObject *#varname#_capi = Py_None;', - 'argformat':{isrequired:'O'}, - 'keyformat':{isoptional:'O'}, - 'args_capi':{isrequired:',&#varname#_capi'}, - 'keys_capi':{isoptional:',&#varname#_capi'}, - 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, - 'pyobjfrom':{isintent_inout:"""\ -\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); -\t\tif (f2py_success) {"""}, - 'closepyobjfrom':{isintent_inout:"\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, - '_check':l_and(iscomplex,isintent_nothide) - },{ - 'frompyobj':[{hasinitvalue:'\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'}, - {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)'}, -# '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\\n");' - '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");' - '\n\tif (f2py_success) {'], - 'cleanupfrompyobj':'\t} /*if (f2py_success) of #varname# frompyobj*/', - 'need':['#ctype#_from_pyobj'], - '_check':l_and(iscomplex,isintent_nothide), - '_depend':'' - },{ # Hidden - 'decl':{isintent_out:'\tPyObject *#varname#_capi = Py_None;'}, - '_check':l_and(iscomplex,isintent_hide) - },{ - 'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, - '_check':l_and(iscomplex,isintent_hide), - '_depend':'' - },{ # Common - 'pyobjfrom':{isintent_out:'\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'}, - 'need':['pyobj_from_#ctype#1'], - '_check':iscomplex - },{ - 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, - '_check':iscomplex, - '_depend':'' - }, -# String - { # Common - 'decl':['\t#ctype# #varname# = NULL;', - '\tint slen(#varname#);', - '\tPyObject *#varname#_capi = Py_None;'], - 'callfortran':'#varname#,', - 'callfortranappend':'slen(#varname#),', - 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, -# 'freemem':'\tSTRINGFREE(#varname#);', - 'return':{isintent_out:',#varname#'}, - 'need':['len..'],#'STRINGFREE'], - '_check':isstring - },{ # Common - 'frompyobj':"""\ -\tslen(#varname#) = #length#; -\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\"); -\tif (f2py_success) {""", - 'cleanupfrompyobj':"""\ -\t\tSTRINGFREE(#varname#); -\t} /*if (f2py_success) of #varname#*/""", - 'need':['#ctype#_from_pyobj','len..','STRINGFREE'], - '_check':isstring, - '_depend':'' - },{ # Not hidden - 'argformat':{isrequired:'O'}, - 'keyformat':{isoptional:'O'}, - 'args_capi':{isrequired:',&#varname#_capi'}, - 'keys_capi':{isoptional:',&#varname#_capi'}, - 'pyobjfrom':{isintent_inout:'''\ -\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#); -\tif (f2py_success) {'''}, - 'closepyobjfrom':{isintent_inout:'\t} /*if (f2py_success) of #varname# pyobjfrom*/'}, - 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, - '_check':l_and(isstring,isintent_nothide) - },{ # Hidden - '_check':l_and(isstring,isintent_hide) - },{ - 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, - '_check':isstring, - '_depend':'' - }, -# Array - { # Common - 'decl':['\t#ctype# *#varname# = NULL;', - '\tintp #varname#_Dims[#rank#] = {#rank*[-1]#};', - '\tconst int #varname#_Rank = #rank#;', - '\tPyArrayObject *capi_#varname#_tmp = NULL;', - '\tint capi_#varname#_intent = 0;', - ], - 'callfortran':'#varname#,', - 'return':{isintent_out:',capi_#varname#_tmp'}, - 'need':'len..', - '_check':isarray - },{ # intent(overwrite) array - 'decl':'\tint capi_overwrite_#varname# = 1;', - 'kwlistxa':'"overwrite_#varname#",', - 'xaformat':'i', - 'keys_xa':',&capi_overwrite_#varname#', - 'docsignxa':'overwrite_#varname#=1,', - 'docsignxashort':'overwrite_#varname#,', - 'docstropt':'\toverwrite_#varname# := 1 input int', - '_check':l_and(isarray,isintent_overwrite), - },{ - 'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', - '_check':l_and(isarray,isintent_overwrite), - '_depend':'', - }, - { # intent(copy) array - 'decl':'\tint capi_overwrite_#varname# = 0;', - 'kwlistxa':'"overwrite_#varname#",', - 'xaformat':'i', - 'keys_xa':',&capi_overwrite_#varname#', - 'docsignxa':'overwrite_#varname#=0,', - 'docsignxashort':'overwrite_#varname#,', - 'docstropt':'\toverwrite_#varname# := 0 input int', - '_check':l_and(isarray,isintent_copy), - },{ - 'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', - '_check':l_and(isarray,isintent_copy), - '_depend':'', - },{ - 'need':[{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}], - '_check':isarray, - '_depend':'' - },{ # Not hidden - 'decl':'\tPyObject *#varname#_capi = Py_None;', - 'argformat':{isrequired:'O'}, - 'keyformat':{isoptional:'O'}, - 'args_capi':{isrequired:',&#varname#_capi'}, - 'keys_capi':{isoptional:',&#varname#_capi'}, -# 'pyobjfrom':{isintent_inout:"""\ -# /* Partly because of the following hack, intent(inout) is depreciated, -# Use intent(in,out) instead. - -# \tif ((#varname#_capi != Py_None) && PyArray_Check(#varname#_capi) \\ -# \t\t&& (#varname#_capi != (PyObject *)capi_#varname#_tmp)) { -# \t\tif (((PyArrayObject *)#varname#_capi)->nd != capi_#varname#_tmp->nd) { -# \t\t\tif (#varname#_capi != capi_#varname#_tmp->base) -# \t\t\t\tcopy_ND_array((PyArrayObject *)capi_#varname#_tmp->base,(PyArrayObject *)#varname#_capi); -# \t\t} else -# \t\t\tcopy_ND_array(capi_#varname#_tmp,(PyArrayObject *)#varname#_capi); -# \t} -# */ -# """}, -# 'need':{isintent_inout:'copy_ND_array'}, - '_check':l_and(isarray,isintent_nothide) - },{ - 'frompyobj':['\t#setdims#;', - '\tcapi_#varname#_intent |= #intent#;', - {isintent_hide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'}, - {isintent_nothide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'}, - """\ -\tif (capi_#varname#_tmp == NULL) { -\t\tif (!PyErr_Occurred()) -\t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" ); -\t} else { -\t\t#varname# = (#ctype# *)(capi_#varname#_tmp->data); -""", -{hasinitvalue:[ - {isintent_nothide:'\tif (#varname#_capi == Py_None) {'}, - {isintent_hide:'\t{'}, - {iscomplexarray:'\t\t#ctype# capi_c;'}, - """\ -\t\tint *_i,capi_i=0; -\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\"); -\t\tif (initforcomb(capi_#varname#_tmp->dimensions,capi_#varname#_tmp->nd,1)) { -\t\t\twhile ((_i = nextforcomb())) -\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */ -\t\t} else { -\t\t\tif (!PyErr_Occurred()) -\t\t\t\tPyErr_SetString(#modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\"); -\t\t\tf2py_success = 0; -\t\t} -\t} -\tif (f2py_success) {"""]}, - ], - 'cleanupfrompyobj':[ # note that this list will be reversed - '\t} /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/', - {l_not(l_or(isintent_out,isintent_hide)):"""\ -\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) { -\t\tPy_XDECREF(capi_#varname#_tmp); }"""}, - {l_and(isintent_hide,l_not(isintent_out)):"""\t\tPy_XDECREF(capi_#varname#_tmp);"""}, - {hasinitvalue:'\t} /*if (f2py_success) of #varname# init*/'}, - ], - '_check':isarray, - '_depend':'' - }, -# { # Hidden -# 'freemem':{l_not(isintent_out):'\tPy_XDECREF(capi_#varname#_tmp);'}, -# '_check':l_and(isarray,isintent_hide) -# }, -# Scalararray - { # Common - '_check':l_and(isarray,l_not(iscomplexarray)) - },{ # Not hidden - '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide) - }, -# Integer*1 array - {'need':'#ctype#', - '_check':isint1array, - '_depend':'' - }, -# Integer*-1 array - {'need':'#ctype#', - '_check':isunsigned_chararray, - '_depend':'' - }, -# Integer*-2 array - {'need':'#ctype#', - '_check':isunsigned_shortarray, - '_depend':'' - }, -# Integer*-8 array - {'need':'#ctype#', - '_check':isunsigned_long_longarray, - '_depend':'' - }, -# Complexarray - {'need':'#ctype#', - '_check':iscomplexarray, - '_depend':'' - }, -# Stringarray - { - 'callfortranappend':{isarrayofstrings:'flen(#varname#),'}, - 'need':'string', - '_check':isstringarray - } - ] - -################# Rules for checking ############### - -check_rules=[ - { - 'frompyobj':{debugcapi:'\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'}, - 'need':'len..' - },{ - 'frompyobj':'\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', - 'cleanupfrompyobj':'\t} /*CHECKSCALAR(#check#)*/', - 'need':'CHECKSCALAR', - '_check':l_and(isscalar,l_not(iscomplex)), - '_break':'' - },{ - 'frompyobj':'\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', - 'cleanupfrompyobj':'\t} /*CHECKSTRING(#check#)*/', - 'need':'CHECKSTRING', - '_check':isstring, - '_break':'' - },{ - 'need':'CHECKARRAY', - 'frompyobj':'\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {', - 'cleanupfrompyobj':'\t} /*CHECKARRAY(#check#)*/', - '_check':isarray, - '_break':'' - },{ - 'need':'CHECKGENERIC', - 'frompyobj':'\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {', - 'cleanupfrompyobj':'\t} /*CHECKGENERIC(#check#)*/', - } -] - -########## Applying the rules. No need to modify what follows ############# - -#################### Build C/API module ####################### - -def buildmodule(m,um): - """ - Return - """ - global f2py_version,options - outmess('\tBuilding module "%s"...\n'%(m['name'])) - ret = {} - mod_rules=defmod_rules[:] - vrd=modsign2map(m) - rd=dictappend({'f2py_version':f2py_version},vrd) - funcwrappers = [] - funcwrappers2 = [] # F90 codes - for n in m['interfaced']: - nb=None - for bi in m['body']: - if not bi['block']=='interface': - errmess('buildmodule: Expected interface block. Skipping.\n') - continue - for b in bi['body']: - if b['name']==n: nb=b;break - - if not nb: - errmess('buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n'%(n)) - continue - nb_list = [nb] - if nb.has_key('entry'): - for k,a in nb['entry'].items(): - nb1 = copy.deepcopy(nb) - del nb1['entry'] - nb1['name'] = k - nb1['args'] = a - nb_list.append(nb1) - for nb in nb_list: - api,wrap=buildapi(nb) - if wrap: - if ismoduleroutine(nb): - funcwrappers2.append(wrap) - else: - funcwrappers.append(wrap) - ar=applyrules(api,vrd) - rd=dictappend(rd,ar) - - # Construct COMMON block support - cr,wrap = common_rules.buildhooks(m) - if wrap: - funcwrappers.append(wrap) - ar=applyrules(cr,vrd) - rd=dictappend(rd,ar) - - # Construct F90 module support - mr,wrap = f90mod_rules.buildhooks(m) - if wrap: - funcwrappers2.append(wrap) - ar=applyrules(mr,vrd) - rd=dictappend(rd,ar) - - for u in um: - ar=use_rules.buildusevars(u,m['use'][u['name']]) - rd=dictappend(rd,ar) - - needs=cfuncs.get_needs() - code={} - for n in needs.keys(): - code[n]=[] - for k in needs[n]: - c='' - if cfuncs.includes0.has_key(k): c=cfuncs.includes0[k] - elif cfuncs.includes.has_key(k): c=cfuncs.includes[k] - elif cfuncs.userincludes.has_key(k): c=cfuncs.userincludes[k] - elif cfuncs.typedefs.has_key(k): c=cfuncs.typedefs[k] - elif cfuncs.typedefs_generated.has_key(k): - c=cfuncs.typedefs_generated[k] - elif cfuncs.cppmacros.has_key(k): c=cfuncs.cppmacros[k] - elif cfuncs.cfuncs.has_key(k): c=cfuncs.cfuncs[k] - elif cfuncs.callbacks.has_key(k): c=cfuncs.callbacks[k] - elif cfuncs.f90modhooks.has_key(k): c=cfuncs.f90modhooks[k] - elif cfuncs.commonhooks.has_key(k): c=cfuncs.commonhooks[k] - else: errmess('buildmodule: unknown need %s.\n'%(`k`));continue - code[n].append(c) - mod_rules.append(code) - for r in mod_rules: - if (r.has_key('_check') and r['_check'](m)) or (not r.has_key('_check')): - ar=applyrules(r,vrd,m) - rd=dictappend(rd,ar) - ar=applyrules(module_rules,rd) - - fn = os.path.join(options['buildpath'],vrd['modulename']+'module.c') - ret['csrc'] = fn - f=open(fn,'w') - f.write(string.replace(ar['modulebody'],'\t',2*' ')) - f.close() - outmess('\tWrote C/API module "%s" to file "%s/%smodule.c"\n'%(m['name'],options['buildpath'],vrd['modulename'])) - - if options['dorestdoc']: - fn = os.path.join(options['buildpath'],vrd['modulename']+'module.rest') - f=open(fn,'w') - f.write('.. -*- rest -*-\n') - f.write(string.join(ar['restdoc'],'\n')) - f.close() - outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n'%(options['buildpath'],vrd['modulename'])) - if options['dolatexdoc']: - fn = os.path.join(options['buildpath'],vrd['modulename']+'module.tex') - ret['ltx'] = fn - f=open(fn,'w') - f.write('%% This file is auto-generated with f2py (version:%s)\n'%(f2py_version)) - if not options.has_key('shortlatex'): - f.write('\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n') - f.write(string.join(ar['latexdoc'],'\n')) - if not options.has_key('shortlatex'): - f.write('\\end{document}') - f.close() - outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n'%(options['buildpath'],vrd['modulename'])) - if funcwrappers: - wn = os.path.join(options['buildpath'],'%s-f2pywrappers.f'%(vrd['modulename'])) - ret['fsrc'] = wn - f=open(wn,'w') - f.write('C -*- fortran -*-\n') - f.write('C This file is autogenerated with f2py (version:%s)\n'%(f2py_version)) - f.write('C It contains Fortran 77 wrappers to fortran functions.\n') - lines = [] - for l in string.split(string.join(funcwrappers,'\n\n')+'\n','\n'): - if l and l[0]==' ': - while len(l)>=66: - lines.append(l[:66]+'\n &') - l = l[66:] - lines.append(l+'\n') - else: lines.append(l+'\n') - lines = string.join(lines,'').replace('\n &\n','\n') - f.write(lines) - f.close() - outmess('\tFortran 77 wrappers are saved to "%s"\n'%(wn)) - if funcwrappers2: - wn = os.path.join(options['buildpath'],'%s-f2pywrappers2.f90'%(vrd['modulename'])) - ret['fsrc'] = wn - f=open(wn,'w') - f.write('! -*- f90 -*-\n') - f.write('! This file is autogenerated with f2py (version:%s)\n'%(f2py_version)) - f.write('! It contains Fortran 90 wrappers to fortran functions.\n') - lines = [] - for l in string.split(string.join(funcwrappers2,'\n\n')+'\n','\n'): - if len(l)>72 and l[0]==' ': - lines.append(l[:72]+'&\n &') - l = l[72:] - while len(l)>66: - lines.append(l[:66]+'&\n &') - l = l[66:] - lines.append(l+'\n') - else: lines.append(l+'\n') - lines = string.join(lines,'').replace('\n &\n','\n') - f.write(lines) - f.close() - outmess('\tFortran 90 wrappers are saved to "%s"\n'%(wn)) - return ret - -################## Build C/API function ############# - -stnd={1:'st',2:'nd',3:'rd',4:'th',5:'th',6:'th',7:'th',8:'th',9:'th',0:'th'} -def buildapi(rout): - rout,wrap = func2subr.assubr(rout) - args,depargs=getargs2(rout) - capi_maps.depargs=depargs - var=rout['vars'] - auxvars = [a for a in var.keys() if isintent_aux(var[a])] - - if ismoduleroutine(rout): - outmess('\t\t\tConstructing wrapper function "%s.%s"...\n'%(rout['modulename'],rout['name'])) - else: - outmess('\t\tConstructing wrapper function "%s"...\n'%(rout['name'])) - # Routine - vrd=routsign2map(rout) - rd=dictappend({},vrd) - for r in rout_rules: - if (r.has_key('_check') and r['_check'](rout)) or (not r.has_key('_check')): - ar=applyrules(r,vrd,rout) - rd=dictappend(rd,ar) - - # Args - nth,nthk=0,0 - savevrd={} - for a in args: - vrd=sign2map(a,var[a]) - if isintent_aux(var[a]): - _rules = aux_rules - else: - _rules = arg_rules - if not isintent_hide(var[a]): - if not isoptional(var[a]): - nth=nth+1 - vrd['nth']=`nth`+stnd[nth%10]+' argument' - else: - nthk=nthk+1 - vrd['nth']=`nthk`+stnd[nthk%10]+' keyword' - else: vrd['nth']='hidden' - savevrd[a]=vrd - for r in _rules: - if r.has_key('_depend'): continue - if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): - ar=applyrules(r,vrd,var[a]) - rd=dictappend(rd,ar) - if r.has_key('_break'): break - for a in depargs: - if isintent_aux(var[a]): - _rules = aux_rules - else: - _rules = arg_rules - vrd=savevrd[a] - for r in _rules: - if not r.has_key('_depend'): continue - if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): - ar=applyrules(r,vrd,var[a]) - rd=dictappend(rd,ar) - if r.has_key('_break'): break - if var[a].has_key('check'): - for c in var[a]['check']: - vrd['check']=c - ar=applyrules(check_rules,vrd,var[a]) - rd=dictappend(rd,ar) - if type(rd['cleanupfrompyobj']) is types.ListType: - rd['cleanupfrompyobj'].reverse() - if type(rd['closepyobjfrom']) is types.ListType: - rd['closepyobjfrom'].reverse() - rd['docsignature']=stripcomma(replace('#docsign##docsignopt##docsignxa#', - {'docsign':rd['docsign'], - 'docsignopt':rd['docsignopt'], - 'docsignxa':rd['docsignxa']})) - optargs=stripcomma(replace('#docsignopt##docsignxa#', - {'docsignxa':rd['docsignxashort'], - 'docsignopt':rd['docsignoptshort']} - )) - if optargs=='': - rd['docsignatureshort']=stripcomma(replace('#docsign#',{'docsign':rd['docsign']})) - else: - rd['docsignatureshort']=replace('#docsign#[#docsignopt#]', - {'docsign':rd['docsign'], - 'docsignopt':optargs, - }) - rd['latexdocsignatureshort']=string.replace(rd['docsignatureshort'],'_','\\_') - rd['latexdocsignatureshort']=string.replace(rd['latexdocsignatureshort'],',',', ') - cfs=stripcomma(replace('#callfortran##callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']})) - if len(rd['callfortranappend'])>1: - rd['callcompaqfortran']=stripcomma(replace('#callfortran# 0,#callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']})) - else: - rd['callcompaqfortran']=cfs - rd['callfortran']=cfs - if type(rd['docreturn'])==types.ListType: - rd['docreturn']=stripcomma(replace('#docreturn#',{'docreturn':rd['docreturn']}))+' = ' - rd['docstrsigns']=[] - rd['latexdocstrsigns']=[] - for k in ['docstrreq','docstropt','docstrout','docstrcbs']: - if rd.has_key(k) and type(rd[k])==types.ListType: - rd['docstrsigns']=rd['docstrsigns']+rd[k] - k='latex'+k - if rd.has_key(k) and type(rd[k])==types.ListType: - rd['latexdocstrsigns']=rd['latexdocstrsigns']+rd[k][0:1]+\ - ['\\begin{description}']+rd[k][1:]+\ - ['\\end{description}'] - ar=applyrules(routine_rules,rd) - if ismoduleroutine(rout): - outmess('\t\t\t %s\n'%(ar['docshort'])) - else: - outmess('\t\t %s\n'%(ar['docshort'])) - return ar,wrap - - -#################### EOF rules.py ####################### diff --git a/numpy/f2py/setup.cfg b/numpy/f2py/setup.cfg deleted file mode 100644 index 14669544c..000000000 --- a/numpy/f2py/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[bdist_rpm] -doc_files = docs/ - tests/
\ No newline at end of file diff --git a/numpy/f2py/setup.py b/numpy/f2py/setup.py deleted file mode 100755 index 7906798bf..000000000 --- a/numpy/f2py/setup.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python -""" -setup.py for installing F2PY - -Usage: - python setup.py install - -Copyright 2001-2005 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@cens.ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Revision: 1.32 $ -$Date: 2005/01/30 17:22:14 $ -Pearu Peterson -""" - -__version__ = "$Id: setup.py,v 1.32 2005/01/30 17:22:14 pearu Exp $" - -import os -import sys -from distutils.dep_util import newer -from numpy.distutils.core import setup -from numpy.distutils.misc_util import Configuration - -from __version__ import version - -def configuration(parent_package='',top_path=None): - config = Configuration('f2py', parent_package, top_path) - - config.add_data_dir('docs') - - config.add_data_files('src/fortranobject.c', - 'src/fortranobject.h', - 'f2py.1' - ) - - config.make_svn_version_py() - - def generate_f2py_py(build_dir): - f2py_exe = 'f2py'+os.path.basename(sys.executable)[6:] - if f2py_exe[-4:]=='.exe': - f2py_exe = f2py_exe[:-4] + '.py' - if 'bdist_wininst' in sys.argv and f2py_exe[-3:] != '.py': - f2py_exe = f2py_exe + '.py' - target = os.path.join(build_dir,f2py_exe) - if newer(__file__,target): - print 'Creating',target - f = open(target,'w') - f.write('''\ -#!/usr/bin/env %s -# See http://cens.ioc.ee/projects/f2py2e/ -import os -os.environ["NO_SCIPY_IMPORT"]="f2py" -import numpy.f2py as f2py -f2py.main() -'''%(os.path.basename(sys.executable))) - f.close() - return target - - config.add_scripts(generate_f2py_py) - - print 'F2PY Version',config.get_version() - - return config - -if __name__ == "__main__": - - config = configuration(top_path='') - version = config.get_version() - print 'F2PY Version',version - config = config.todict() - - if sys.version[:3]>='2.3': - config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\ - "/F2PY-2-latest.tar.gz" - config['classifiers'] = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: NumPy License', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: C', - 'Programming Language :: Fortran', - 'Programming Language :: Python', - 'Topic :: Scientific/Engineering', - 'Topic :: Software Development :: Code Generators', - ] - setup(version=version, - description = "F2PY - Fortran to Python Interface Generaton", - author = "Pearu Peterson", - author_email = "pearu@cens.ioc.ee", - maintainer = "Pearu Peterson", - maintainer_email = "pearu@cens.ioc.ee", - license = "BSD", - platforms = "Unix, Windows (mingw|cygwin), Mac OSX", - long_description = """\ -The Fortran to Python Interface Generator, or F2PY for short, is a -command line tool (f2py) for generating Python C/API modules for -wrapping Fortran 77/90/95 subroutines, accessing common blocks from -Python, and calling Python functions from Fortran (call-backs). -Interfacing subroutines/data from Fortran 90/95 modules is supported.""", - url = "http://cens.ioc.ee/projects/f2py2e/", - keywords = ['Fortran','f2py'], - **config) diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c deleted file mode 100644 index 3e6ccb079..000000000 --- a/numpy/f2py/src/fortranobject.c +++ /dev/null @@ -1,806 +0,0 @@ -#define FORTRANOBJECT_C -#include "fortranobject.h" - -#ifdef __cplusplus -extern "C" { -#endif -/* - This file implements: FortranObject, array_from_pyobj, copy_ND_array - - Author: Pearu Peterson <pearu@cens.ioc.ee> - $Revision: 1.52 $ - $Date: 2005/07/11 07:44:20 $ -*/ - -int -F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj) -{ - if (obj==NULL) { - fprintf(stderr, "Error loading %s\n", name); - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - } - return -1; - } - return PyDict_SetItemString(dict, name, obj); -} - -/************************* FortranObject *******************************/ - -typedef PyObject *(*fortranfunc)(PyObject *,PyObject *,PyObject *,void *); - -PyObject * -PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) { - int i; - PyFortranObject *fp = NULL; - PyObject *v = NULL; - if (init!=NULL) /* Initialize F90 module objects */ - (*(init))(); - if ((fp = PyObject_New(PyFortranObject, &PyFortran_Type))==NULL) return NULL; - if ((fp->dict = PyDict_New())==NULL) return NULL; - fp->len = 0; - while (defs[fp->len].name != NULL) fp->len++; - if (fp->len == 0) goto fail; - fp->defs = defs; - for (i=0;i<fp->len;i++) - if (fp->defs[i].rank == -1) { /* Is Fortran routine */ - v = PyFortranObject_NewAsAttr(&(fp->defs[i])); - if (v==NULL) return NULL; - PyDict_SetItemString(fp->dict,fp->defs[i].name,v); - } else - if ((fp->defs[i].data)!=NULL) { /* Is Fortran variable or array (not allocatable) */ - if (fp->defs[i].type == PyArray_STRING) { - int n = fp->defs[i].rank-1; - v = PyArray_New(&PyArray_Type, n, fp->defs[i].dims.d, - PyArray_STRING, NULL, fp->defs[i].data, fp->defs[i].dims.d[n], - FARRAY_FLAGS, NULL); - } - else { - v = PyArray_New(&PyArray_Type, fp->defs[i].rank, fp->defs[i].dims.d, - fp->defs[i].type, NULL, fp->defs[i].data, 0, FARRAY_FLAGS, - NULL); - } - if (v==NULL) return NULL; - PyDict_SetItemString(fp->dict,fp->defs[i].name,v); - } - Py_XDECREF(v); - return (PyObject *)fp; - fail: - Py_XDECREF(v); - return NULL; -} - -PyObject * -PyFortranObject_NewAsAttr(FortranDataDef* defs) { /* used for calling F90 module routines */ - PyFortranObject *fp = NULL; - fp = PyObject_New(PyFortranObject, &PyFortran_Type); - if (fp == NULL) return NULL; - if ((fp->dict = PyDict_New())==NULL) return NULL; - fp->len = 1; - fp->defs = defs; - return (PyObject *)fp; -} - -/* Fortran methods */ - -static void -fortran_dealloc(PyFortranObject *fp) { - Py_XDECREF(fp->dict); - PyMem_Del(fp); -} - - -static PyMethodDef fortran_methods[] = { - {NULL, NULL} /* sentinel */ -}; - - -static PyObject * -fortran_doc (FortranDataDef def) { - char *p; - PyObject *s = NULL; - int i; - unsigned size=100; - if (def.doc!=NULL) - size += strlen(def.doc); - p = (char*)malloc (size); - if (sprintf(p,"%s - ",def.name)==0) goto fail; - if (def.rank==-1) { - if (def.doc==NULL) { - if (sprintf(p,"%sno docs available",p)==0) - goto fail; - } else { - if (sprintf(p,"%s%s",p,def.doc)==0) - goto fail; - } - } else { - PyArray_Descr *d = PyArray_DescrFromType(def.type); - if (sprintf(p,"%s'%c'-",p,d->type)==0) goto fail; - if (def.data==NULL) { - if (sprintf(p,"%sarray(%" INTP_FMT,p,def.dims.d[0])==0) goto fail; - for(i=1;i<def.rank;++i) - if (sprintf(p,"%s,%" INTP_FMT,p,def.dims.d[i])==0) goto fail; - if (sprintf(p,"%s), not allocated",p)==0) goto fail; - } else { - if (def.rank>0) { - if (sprintf(p,"%sarray(%"INTP_FMT,p,def.dims.d[0])==0) goto fail; - for(i=1;i<def.rank;i++) - if (sprintf(p,"%s,%" INTP_FMT,p,def.dims.d[i])==0) goto fail; - if (sprintf(p,"%s)",p)==0) goto fail; - } else { - if (sprintf(p,"%sscalar",p)==0) goto fail; - } - } - } - if (sprintf(p,"%s\n",p)==0) goto fail; - if (strlen(p)>size) { - fprintf(stderr,"fortranobject.c:fortran_doc:len(p)=%zd>%d(size): too long doc string required, increase size\n",strlen(p),size); - goto fail; - } - s = PyString_FromString(p); - fail: - free(p); - return s; -} - -static FortranDataDef *save_def; /* save pointer of an allocatable array */ -static void set_data(char *d,intp *f) { /* callback from Fortran */ - if (*f) /* In fortran f=allocated(d) */ - save_def->data = d; - else - save_def->data = NULL; - /* printf("set_data: d=%p,f=%d\n",d,*f); */ -} - -static PyObject * -fortran_getattr(PyFortranObject *fp, char *name) { - int i,j,k,flag; - if (fp->dict != NULL) { - PyObject *v = PyDict_GetItemString(fp->dict, name); - if (v != NULL) { - Py_INCREF(v); - return v; - } - } - for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++); - if (j==0) - if (fp->defs[i].rank!=-1) { /* F90 allocatable array */ - if (fp->defs[i].func==NULL) return NULL; - for(k=0;k<fp->defs[i].rank;++k) - fp->defs[i].dims.d[k]=-1; - save_def = &fp->defs[i]; - (*(fp->defs[i].func))(&fp->defs[i].rank,fp->defs[i].dims.d,set_data,&flag); - if (flag==2) - k = fp->defs[i].rank + 1; - else - k = fp->defs[i].rank; - if (fp->defs[i].data !=NULL) { /* array is allocated */ - PyObject *v = PyArray_New(&PyArray_Type, k, fp->defs[i].dims.d, - fp->defs[i].type, NULL, fp->defs[i].data, 0, FARRAY_FLAGS, - NULL); - if (v==NULL) return NULL; - /* Py_INCREF(v); */ - return v; - } else { /* array is not allocated */ - Py_INCREF(Py_None); - return Py_None; - } - } - if (strcmp(name,"__dict__")==0) { - Py_INCREF(fp->dict); - return fp->dict; - } - if (strcmp(name,"__doc__")==0) { - PyObject *s = PyString_FromString(""); - for (i=0;i<fp->len;i++) - PyString_ConcatAndDel(&s,fortran_doc(fp->defs[i])); - if (PyDict_SetItemString(fp->dict, name, s)) - return NULL; - return s; - } - if ((strcmp(name,"_cpointer")==0) && (fp->len==1)) { - PyObject *cobj = PyCObject_FromVoidPtr((void *)(fp->defs[0].data),NULL); - if (PyDict_SetItemString(fp->dict, name, cobj)) - return NULL; - return cobj; - } - return Py_FindMethod(fortran_methods, (PyObject *)fp, name); -} - -static int -fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) { - int i,j,flag; - PyArrayObject *arr = NULL; - for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++); - if (j==0) { - if (fp->defs[i].rank==-1) { - PyErr_SetString(PyExc_AttributeError,"over-writing fortran routine"); - return -1; - } - if (fp->defs[i].func!=NULL) { /* is allocatable array */ - intp dims[F2PY_MAX_DIMS]; - int k; - save_def = &fp->defs[i]; - if (v!=Py_None) { /* set new value (reallocate if needed -- - see f2py generated code for more - details ) */ - for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1; - if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) - return -1; - (*(fp->defs[i].func))(&fp->defs[i].rank,arr->dimensions,set_data,&flag); - } else { /* deallocate */ - for(k=0;k<fp->defs[i].rank;k++) dims[k]=0; - (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag); - for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1; - } - memcpy(fp->defs[i].dims.d,dims,fp->defs[i].rank*sizeof(intp)); - } else { /* not allocatable array */ - if ((arr = array_from_pyobj(fp->defs[i].type,fp->defs[i].dims.d,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) - return -1; - } - if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */ - intp s = PyArray_MultiplyList(fp->defs[i].dims.d,arr->nd); - if (s==-1) - s = PyArray_MultiplyList(arr->dimensions,arr->nd); - if (s<0 || - (memcpy(fp->defs[i].data,arr->data,s*PyArray_ITEMSIZE(arr)))==NULL) { - if ((PyObject*)arr!=v) { - Py_DECREF(arr); - } - return -1; - } - if ((PyObject*)arr!=v) { - Py_DECREF(arr); - } - } else return (fp->defs[i].func==NULL?-1:0); - return 0; /* succesful */ - } - if (fp->dict == NULL) { - fp->dict = PyDict_New(); - if (fp->dict == NULL) - return -1; - } - if (v == NULL) { - int rv = PyDict_DelItemString(fp->dict, name); - if (rv < 0) - PyErr_SetString(PyExc_AttributeError,"delete non-existing fortran attribute"); - return rv; - } - else - return PyDict_SetItemString(fp->dict, name, v); -} - -static PyObject* -fortran_call(PyFortranObject *fp, PyObject *arg, PyObject *kw) { - int i = 0; - /* printf("fortran call - name=%s,func=%p,data=%p,%p\n",fp->defs[i].name, - fp->defs[i].func,fp->defs[i].data,&fp->defs[i].data); */ - if (fp->defs[i].rank==-1) {/* is Fortran routine */ - if ((fp->defs[i].func==NULL)) { - PyErr_Format(PyExc_RuntimeError, "no function to call"); - return NULL; - } - else if (fp->defs[i].data==NULL) - /* dummy routine */ - return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,NULL); - else - return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw, - (void *)fp->defs[i].data); - } - PyErr_Format(PyExc_TypeError, "this fortran object is not callable"); - return NULL; -} - - -PyTypeObject PyFortran_Type = { - PyObject_HEAD_INIT(0) - 0, /*ob_size*/ - "fortran", /*tp_name*/ - sizeof(PyFortranObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)fortran_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)fortran_getattr, /*tp_getattr*/ - (setattrfunc)fortran_setattr, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)fortran_call, /*tp_call*/ -}; - -/************************* f2py_report_atexit *******************************/ - -#ifdef F2PY_REPORT_ATEXIT -static int passed_time = 0; -static int passed_counter = 0; -static int passed_call_time = 0; -static struct timeb start_time; -static struct timeb stop_time; -static struct timeb start_call_time; -static struct timeb stop_call_time; -static int cb_passed_time = 0; -static int cb_passed_counter = 0; -static int cb_passed_call_time = 0; -static struct timeb cb_start_time; -static struct timeb cb_stop_time; -static struct timeb cb_start_call_time; -static struct timeb cb_stop_call_time; - -extern void f2py_start_clock(void) { ftime(&start_time); } -extern -void f2py_start_call_clock(void) { - f2py_stop_clock(); - ftime(&start_call_time); -} -extern -void f2py_stop_clock(void) { - ftime(&stop_time); - passed_time += 1000*(stop_time.time - start_time.time); - passed_time += stop_time.millitm - start_time.millitm; -} -extern -void f2py_stop_call_clock(void) { - ftime(&stop_call_time); - passed_call_time += 1000*(stop_call_time.time - start_call_time.time); - passed_call_time += stop_call_time.millitm - start_call_time.millitm; - passed_counter += 1; - f2py_start_clock(); -} - -extern void f2py_cb_start_clock(void) { ftime(&cb_start_time); } -extern -void f2py_cb_start_call_clock(void) { - f2py_cb_stop_clock(); - ftime(&cb_start_call_time); -} -extern -void f2py_cb_stop_clock(void) { - ftime(&cb_stop_time); - cb_passed_time += 1000*(cb_stop_time.time - cb_start_time.time); - cb_passed_time += cb_stop_time.millitm - cb_start_time.millitm; -} -extern -void f2py_cb_stop_call_clock(void) { - ftime(&cb_stop_call_time); - cb_passed_call_time += 1000*(cb_stop_call_time.time - cb_start_call_time.time); - cb_passed_call_time += cb_stop_call_time.millitm - cb_start_call_time.millitm; - cb_passed_counter += 1; - f2py_cb_start_clock(); -} - -static int f2py_report_on_exit_been_here = 0; -extern -void f2py_report_on_exit(int exit_flag,void *name) { - if (f2py_report_on_exit_been_here) { - fprintf(stderr," %s\n",(char*)name); - return; - } - f2py_report_on_exit_been_here = 1; - fprintf(stderr," /-----------------------\\\n"); - fprintf(stderr," < F2PY performance report >\n"); - fprintf(stderr," \\-----------------------/\n"); - fprintf(stderr,"Overall time spent in ...\n"); - fprintf(stderr,"(a) wrapped (Fortran/C) functions : %8d msec\n", - passed_call_time); - fprintf(stderr,"(b) f2py interface, %6d calls : %8d msec\n", - passed_counter,passed_time); - fprintf(stderr,"(c) call-back (Python) functions : %8d msec\n", - cb_passed_call_time); - fprintf(stderr,"(d) f2py call-back interface, %6d calls : %8d msec\n", - cb_passed_counter,cb_passed_time); - - fprintf(stderr,"(e) wrapped (Fortran/C) functions (acctual) : %8d msec\n\n", - passed_call_time-cb_passed_call_time-cb_passed_time); - fprintf(stderr,"Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.\n"); - fprintf(stderr,"Exit status: %d\n",exit_flag); - fprintf(stderr,"Modules : %s\n",(char*)name); -} -#endif - -/********************** report on array copy ****************************/ - -#ifdef F2PY_REPORT_ON_ARRAY_COPY -static void f2py_report_on_array_copy(PyArrayObject* arr) { - const long arr_size = PyArray_Size((PyObject *)arr); - if (arr_size>F2PY_REPORT_ON_ARRAY_COPY) { - fprintf(stderr,"copied an array: size=%ld, elsize=%d\n", - arr_size, PyArray_ITEMSIZE(arr)); - } -} -static void f2py_report_on_array_copy_fromany(void) { - fprintf(stderr,"created an array from object\n"); -} - -#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR f2py_report_on_array_copy((PyArrayObject *)arr) -#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY f2py_report_on_array_copy_fromany() -#else -#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR -#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY -#endif - - -/************************* array_from_obj *******************************/ - -/* - * File: array_from_pyobj.c - * - * Description: - * ------------ - * Provides array_from_pyobj function that returns a contigious array - * object with the given dimensions and required storage order, either - * in row-major (C) or column-major (Fortran) order. The function - * array_from_pyobj is very flexible about its Python object argument - * that can be any number, list, tuple, or array. - * - * array_from_pyobj is used in f2py generated Python extension - * modules. - * - * Author: Pearu Peterson <pearu@cens.ioc.ee> - * Created: 13-16 January 2002 - * $Id: fortranobject.c,v 1.52 2005/07/11 07:44:20 pearu Exp $ - */ - -static int -count_nonpos(const int rank, - const intp *dims) { - int i=0,r=0; - while (i<rank) { - if (dims[i] <= 0) ++r; - ++i; - } - return r; -} - -static int check_and_fix_dimensions(const PyArrayObject* arr, - const int rank, - intp *dims); - -#ifdef DEBUG_COPY_ND_ARRAY -void dump_dims(int rank, intp* dims) { - int i; - printf("["); - for(i=0;i<rank;++i) { - printf("%3" INTP_FMT, dims[i]); - } - printf("]\n"); -} -void dump_attrs(const PyArrayObject* arr) { - int rank = arr->nd; - intp size = PyArray_Size((PyObject *)arr); - printf("\trank = %d, flags = %d, size = %" INTP_FMT "\n", - rank,arr->flags,size); - printf("\tstrides = "); - dump_dims(rank,arr->strides); - printf("\tdimensions = "); - dump_dims(rank,arr->dimensions); -} -#endif - -#define SWAPTYPE(a,b,t) {t c; c = (a); (a) = (b); (b) = c; } - -static int swap_arrays(PyArrayObject* arr1, PyArrayObject* arr2) { - SWAPTYPE(arr1->data,arr2->data,char*); - SWAPTYPE(arr1->nd,arr2->nd,int); - SWAPTYPE(arr1->dimensions,arr2->dimensions,intp*); - SWAPTYPE(arr1->strides,arr2->strides,intp*); - SWAPTYPE(arr1->base,arr2->base,PyObject*); - SWAPTYPE(arr1->descr,arr2->descr,PyArray_Descr*); - SWAPTYPE(arr1->flags,arr2->flags,int); - /* SWAPTYPE(arr1->weakreflist,arr2->weakreflist,PyObject*); */ - return 0; -} - -#define ARRAY_ISCOMPATIBLE(arr,type_num) \ -( (PyArray_ISINTEGER(arr) && PyTypeNum_ISINTEGER(type_num)) \ - ||(PyArray_ISFLOAT(arr) && PyTypeNum_ISFLOAT(type_num)) \ - ||(PyArray_ISCOMPLEX(arr) && PyTypeNum_ISCOMPLEX(type_num)) \ -) - -extern -PyArrayObject* array_from_pyobj(const int type_num, - intp *dims, - const int rank, - const int intent, - PyObject *obj) { - /* Note about reference counting - ----------------------------- - If the caller returns the array to Python, it must be done with - Py_BuildValue("N",arr). - Otherwise, if obj!=arr then the caller must call Py_DECREF(arr). - - Note on intent(cache,out,..) - --------------------- - Don't expect correct data when returning intent(cache) array. - - */ - char mess[200]; - PyArrayObject *arr = NULL; - PyArray_Descr *descr = PyArray_DescrFromType(type_num); - - if ((intent & F2PY_INTENT_HIDE) - || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None)) - || ((intent & F2PY_OPTIONAL) && (obj==Py_None)) - ) { - /* intent(cache), optional, intent(hide) */ - if (count_nonpos(rank,dims)) { - int i; - sprintf(mess,"failed to create intent(cache|hide)|optional array" - "-- must have defined dimensions but got ("); - for(i=0;i<rank;++i) - sprintf(mess+strlen(mess),"%" INTP_FMT ",",dims[i]); - sprintf(mess+strlen(mess),")"); - PyErr_SetString(PyExc_ValueError,mess); - return NULL; - } - arr = (PyArrayObject *) - PyArray_New(&PyArray_Type, rank, dims, type_num, - NULL,NULL,0, - !(intent&F2PY_INTENT_C), - NULL); - if (arr==NULL) return NULL; - if (!(intent & F2PY_INTENT_CACHE)) - PyArray_FILLWBYTE(arr, 0); - return arr; - } - - if (PyArray_Check(obj)) { - arr = (PyArrayObject *)obj; - - if (intent & F2PY_INTENT_CACHE) { - /* intent(cache) */ - if (PyArray_ISONESEGMENT(obj) - && PyArray_ITEMSIZE((PyArrayObject *)obj)>=descr->elsize) { - if (check_and_fix_dimensions((PyArrayObject *)obj,rank,dims)) - return NULL; /*XXX: set exception */ - if (intent & F2PY_INTENT_OUT) - Py_INCREF(obj); - return (PyArrayObject *)obj; - } - sprintf(mess,"failed to initialize intent(cache) array"); - if (!PyArray_ISONESEGMENT(obj)) - sprintf(mess+strlen(mess)," -- input must be in one segment"); - if (PyArray_ITEMSIZE(arr)<descr->elsize) - sprintf(mess+strlen(mess)," -- expected at least elsize=%d but got %d", - descr->elsize,PyArray_ITEMSIZE(arr) - ); - PyErr_SetString(PyExc_ValueError,mess); - return NULL; - } - - /* here we have always intent(in) or intent(inout) or intent(inplace) */ - - if (check_and_fix_dimensions(arr,rank,dims)) - return NULL; /*XXX: set exception */ - - if ((! (intent & F2PY_INTENT_COPY)) - && PyArray_ITEMSIZE(arr)==descr->elsize - && ARRAY_ISCOMPATIBLE(arr,type_num) - ) { - if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) { - if ((intent & F2PY_INTENT_OUT)) { - Py_INCREF(arr); - } - /* Returning input array */ - return arr; - } - } - - if (intent & F2PY_INTENT_INOUT) { - sprintf(mess,"failed to initialize intent(inout) array"); - if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr)) - sprintf(mess+strlen(mess)," -- input not contiguous"); - if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr)) - sprintf(mess+strlen(mess)," -- input not fortran contiguous"); - if (PyArray_ITEMSIZE(arr)!=descr->elsize) - sprintf(mess+strlen(mess)," -- expected elsize=%d but got %d", - descr->elsize, - PyArray_ITEMSIZE(arr) - ); - if (!(ARRAY_ISCOMPATIBLE(arr,type_num))) - sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'", - arr->descr->type,descr->type); - PyErr_SetString(PyExc_ValueError,mess); - return NULL; - } - - /* here we have always intent(in) or intent(inplace) */ - - { - PyArrayObject *retarr = (PyArrayObject *) \ - PyArray_New(&PyArray_Type, arr->nd, arr->dimensions, type_num, - NULL,NULL,0, - !(intent&F2PY_INTENT_C), - NULL); - if (retarr==NULL) - return NULL; - F2PY_REPORT_ON_ARRAY_COPY_FROMARR; - if (PyArray_CopyInto(retarr, arr)) { - Py_DECREF(retarr); - return NULL; - } - if (intent & F2PY_INTENT_INPLACE) { - if (swap_arrays(arr,retarr)) - return NULL; /* XXX: set exception */ - Py_XDECREF(retarr); - if (intent & F2PY_INTENT_OUT) - Py_INCREF(arr); - } else { - arr = retarr; - } - } - return arr; - } - - if ((intent & F2PY_INTENT_INOUT) - || (intent & F2PY_INTENT_INPLACE) - || (intent & F2PY_INTENT_CACHE)) { - sprintf(mess,"failed to initialize intent(inout|inplace|cache) array" - " -- input must be array but got %s", - PyString_AsString(PyObject_Str(PyObject_Type(obj))) - ); - PyErr_SetString(PyExc_TypeError,mess); - return NULL; - } - - { - F2PY_REPORT_ON_ARRAY_COPY_FROMANY; - arr = (PyArrayObject *) \ - PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0, - ((intent & F2PY_INTENT_C)?CARRAY_FLAGS:FARRAY_FLAGS) \ - | FORCECAST, NULL); - if (arr==NULL) - return NULL; - if (check_and_fix_dimensions(arr,rank,dims)) - return NULL; /*XXX: set exception */ - return arr; - } - -} - - /*****************************************/ - /* Helper functions for array_from_pyobj */ - /*****************************************/ - -static -int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,intp *dims) { - /* - This function fills in blanks (that are -1\'s) in dims list using - the dimensions from arr. It also checks that non-blank dims will - match with the corresponding values in arr dimensions. - */ - const intp arr_size = (arr->nd)?PyArray_Size((PyObject *)arr):1; -#ifdef DEBUG_COPY_ND_ARRAY - dump_attrs(arr); - printf("check_and_fix_dimensions:init: dims="); - dump_dims(rank,dims); -#endif - if (rank > arr->nd) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */ - intp new_size = 1; - int free_axe = -1; - int i; - /* Fill dims where -1 or 0; check dimensions; calc new_size; */ - for(i=0;i<arr->nd;++i) { - if (dims[i] >= 0) { - if (dims[i]!=arr->dimensions[i]) { - fprintf(stderr,"%d-th dimension must be fixed to %" INTP_FMT - " but got %" INTP_FMT "\n", - i,dims[i], arr->dimensions[i]); - return 1; - } - if (!dims[i]) dims[i] = 1; - } else { - dims[i] = arr->dimensions[i] ? arr->dimensions[i] : 1; - } - new_size *= dims[i]; - } - for(i=arr->nd;i<rank;++i) - if (dims[i]>1) { - fprintf(stderr,"%d-th dimension must be %" INTP_FMT - " but got 0 (not defined).\n", - i,dims[i]); - return 1; - } else if (free_axe<0) - free_axe = i; - else - dims[i] = 1; - if (free_axe>=0) { - dims[free_axe] = arr_size/new_size; - new_size *= dims[free_axe]; - } - if (new_size != arr_size) { - fprintf(stderr,"confused: new_size=%" INTP_FMT - ", arr_size=%" INTP_FMT " (maybe too many free" - " indices)\n", new_size,arr_size); - return 1; - } - } else if (rank==arr->nd) { - int i; - intp d; - for (i=0; i<rank; ++i) { - d = arr->dimensions[i]; - if (dims[i]>=0) { - if (d > 1 && d!=dims[i]) { - fprintf(stderr,"%d-th dimension must be fixed to %" INTP_FMT - " but got %" INTP_FMT "\n", - i,dims[i],d); - return 1; - } - if (!dims[i]) dims[i] = 1; - } else dims[i] = d; - } - } else { /* [[1,2]] -> [[1],[2]] */ - int i,j; - intp d; - int effrank; - intp size; - for (i=0,effrank=0;i<arr->nd;++i) - if (arr->dimensions[i]>1) ++effrank; - if (dims[rank-1]>=0) - if (effrank>rank) { - fprintf(stderr,"too many axes: %d (effrank=%d), expected rank=%d\n", - arr->nd,effrank,rank); - return 1; - } - - for (i=0,j=0;i<rank;++i) { - while (j<arr->nd && arr->dimensions[j]<2) ++j; - if (j>=arr->nd) d = 1; - else d = arr->dimensions[j++]; - if (dims[i]>=0) { - if (d>1 && d!=dims[i]) { - fprintf(stderr,"%d-th dimension must be fixed to %" INTP_FMT - " but got %" INTP_FMT " (real index=%d)\n", - i,dims[i],d,j-1); - return 1; - } - if (!dims[i]) dims[i] = 1; - } else - dims[i] = d; - } - - for (i=rank;i<arr->nd;++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */ - while (j<arr->nd && arr->dimensions[j]<2) ++j; - if (j>=arr->nd) d = 1; - else d = arr->dimensions[j++]; - dims[rank-1] *= d; - } - for (i=0,size=1;i<rank;++i) size *= dims[i]; - if (size != arr_size) { - fprintf(stderr,"confused: size=%" INTP_FMT ", arr_size=%" INTP_FMT - ", rank=%d, effrank=%d, arr.nd=%d, dims=[", - size,arr_size,rank,effrank,arr->nd); - for (i=0;i<rank;++i) fprintf(stderr," %" INTP_FMT,dims[i]); - fprintf(stderr," ], arr.dims=["); - for (i=0;i<arr->nd;++i) fprintf(stderr," %" INTP_FMT,arr->dimensions[i]); - fprintf(stderr," ]\n"); - return 1; - } - } -#ifdef DEBUG_COPY_ND_ARRAY - printf("check_and_fix_dimensions:end: dims="); - dump_dims(rank,dims); -#endif - return 0; -} - -/* End of file: array_from_pyobj.c */ - -/************************* copy_ND_array *******************************/ - -extern -int copy_ND_array(const PyArrayObject *arr, PyArrayObject *out) -{ - F2PY_REPORT_ON_ARRAY_COPY_FROMARR; - return PyArray_CopyInto(out, (PyArrayObject *)arr); -} - -#ifdef __cplusplus -} -#endif -/************************* EOF fortranobject.c *******************************/ diff --git a/numpy/f2py/src/fortranobject.h b/numpy/f2py/src/fortranobject.h deleted file mode 100644 index 353b2a64b..000000000 --- a/numpy/f2py/src/fortranobject.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef Py_FORTRANOBJECT_H -#define Py_FORTRANOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python.h" - -#ifdef FORTRANOBJECT_C -#define NO_IMPORT_ARRAY -#endif -#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API -#include "numpy/arrayobject.h" - - /* -#ifdef F2PY_REPORT_ATEXIT_DISABLE -#undef F2PY_REPORT_ATEXIT -#else - -#ifndef __FreeBSD__ -#ifndef __WIN32__ -#ifndef __APPLE__ -#define F2PY_REPORT_ATEXIT -#endif -#endif -#endif - -#endif - */ - -#ifdef F2PY_REPORT_ATEXIT -#include <sys/timeb.h> - extern void f2py_start_clock(void); - extern void f2py_stop_clock(void); - extern void f2py_start_call_clock(void); - extern void f2py_stop_call_clock(void); - extern void f2py_cb_start_clock(void); - extern void f2py_cb_stop_clock(void); - extern void f2py_cb_start_call_clock(void); - extern void f2py_cb_stop_call_clock(void); - extern void f2py_report_on_exit(int,void*); -#endif - -#ifdef DMALLOC -#include "dmalloc.h" -#endif - -/* Fortran object interface */ - -/* -123456789-123456789-123456789-123456789-123456789-123456789-123456789-12 - -PyFortranObject represents various Fortran objects: -Fortran (module) routines, COMMON blocks, module data. - -Author: Pearu Peterson <pearu@cens.ioc.ee> -*/ - -#define F2PY_MAX_DIMS 40 - -typedef void (*f2py_set_data_func)(char*,intp*); -typedef void (*f2py_void_func)(void); -typedef void (*f2py_init_func)(int*,intp*,f2py_set_data_func,int*); - - /*typedef void* (*f2py_c_func)(void*,...);*/ - -typedef void *(*f2pycfunc)(void); - -typedef struct { - char *name; /* attribute (array||routine) name */ - int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS, - || rank=-1 for Fortran routine */ - struct {intp d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */ - int type; /* PyArray_<type> || not used */ - char *data; /* pointer to array || Fortran routine */ - f2py_init_func func; /* initialization function for - allocatable arrays: - func(&rank,dims,set_ptr_func,name,len(name)) - || C/API wrapper for Fortran routine */ - char *doc; /* documentation string; only recommended - for routines. */ -} FortranDataDef; - -typedef struct { - PyObject_HEAD - int len; /* Number of attributes */ - FortranDataDef *defs; /* An array of FortranDataDef's */ - PyObject *dict; /* Fortran object attribute dictionary */ -} PyFortranObject; - -#define PyFortran_Check(op) ((op)->ob_type == &PyFortran_Type) -#define PyFortran_Check1(op) (0==strcmp((op)->ob_type->tp_name,"fortran")) - - extern PyTypeObject PyFortran_Type; - extern int F2PyDict_SetItemString(PyObject* dict, char *name, PyObject *obj); - extern PyObject * PyFortranObject_New(FortranDataDef* defs, f2py_void_func init); - extern PyObject * PyFortranObject_NewAsAttr(FortranDataDef* defs); - -#define ISCONTIGUOUS(m) ((m)->flags & CONTIGUOUS) -#define F2PY_INTENT_IN 1 -#define F2PY_INTENT_INOUT 2 -#define F2PY_INTENT_OUT 4 -#define F2PY_INTENT_HIDE 8 -#define F2PY_INTENT_CACHE 16 -#define F2PY_INTENT_COPY 32 -#define F2PY_INTENT_C 64 -#define F2PY_OPTIONAL 128 -#define F2PY_INTENT_INPLACE 256 - - extern PyArrayObject* array_from_pyobj(const int type_num, - intp *dims, - const int rank, - const int intent, - PyObject *obj); - extern int copy_ND_array(const PyArrayObject *in, PyArrayObject *out); - -#ifdef DEBUG_COPY_ND_ARRAY - extern void dump_attrs(const PyArrayObject* arr); -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FORTRANOBJECT_H */ diff --git a/numpy/f2py/src/test/Makefile b/numpy/f2py/src/test/Makefile deleted file mode 100644 index 0f8869f72..000000000 --- a/numpy/f2py/src/test/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -# -*- makefile -*- -# File: Makefile-foo -# Usage: -# make -f Makefile-foo [MODE=opt|debug] -# Notes: -# 1) You must use GNU make; try `gmake ..' if `make' fails. -# 2) This file is auto-generated with f2py (version 2.264). -# f2py is a Fortran to Python Interface Generator (FPIG), Second Edition, -# written by Pearu Peterson <pearu@ioc.ee>. -# See http://cens.ioc.ee/projects/f2py2e/ -# Generation date: Wed Sep 13 16:22:55 2000 -# $Revision: 1.2 $ -# $Date: 2000/09/17 16:10:27 $ - -# Recommendation notes produced by f2py2e/buildmakefile.py: -# *** - -PYINC = -I/numeric/include/python1.5/Numeric -I/numeric/include/python1.5 -INCLUDES = -I.. -LIBS = -L$(shell gcc -v 2>&1 | grep specs | sed -e 's/Reading specs from //g' | sed -e 's/\/specs//g') -lg2c -LIBS=-L$$ABSOFT/lib -lfio -lf77math -lf90math -LIBS=-L/numeric/bin -lvast90 -L/usr/lib/gcc-lib/i586-mandrake-linux/2.95.2 -lg2c - -# Wrapper generator: -F2PY = /home/pearu/bin/f2py-cvs - -# Fortran compiler: Absoft f95 -FC = f95 -FC = f90 -FOPT = -FDEBUG = -FFLAGS = -B108 -YCFRL=1 -YCOM_NAMES=LCS -YCOM_PFX -YCOM_SFX=_ -YEXT_PFX -YEXT_NAMES=LCS -FFLAGS = -# C compiler: cc ('gcc 2.x.x' 2.95.2) -CC = cc -COPT = -CDEBUG = -CFLAGS = -fpic - -# Linker: ld ('GNU ld' 2.9.5) -LD = ld -LDFLAGS = -shared -s -SO = .so - -ifeq '$(MODE)' 'debug' -FFLAGS += $(FDEBUG) -CFLAGS += $(CDEBUG) -endif -ifeq '$(MODE)' 'opt' -FFLAGS += $(FOPT) -CFLAGS += $(COPT) -endif -FFLAGS += $(INCLUDES) -CFLAGS += $(PYINC) $(INCLUDES) - -SRCC = ../fortranobject.c -SRCF = mod.f90 bar.f foo90.f90 wrap.f -SRCS = $(SRCC) $(SRCF) -OBJC = $(filter %.o,$(SRCC:.c=.o) $(SRCC:.cc=.o) $(SRCC:.C=.o)) -OBJF = $(filter %.o,$(SRCF:.f90=.o) $(SRCF:.f=.o) $(SRCF:.F=.o) $(SRCF:.for=.o)) -OBJS = $(OBJC) $(OBJF) - -INSTALLNAME = f2py2e-apps -INSTALLDIRECTORY = /numeric/lib/python1.5/site-packages/$(INSTALLNAME) -INSTALLDIR = install -d -c -INSTALLEXEC = install -m 755 -c - -all: foo - -foo: foomodule$(SO) -foomodule$(SO) : foomodule.o $(OBJS) - $(LD) $(LDFLAGS) -o $@ $< $(OBJS) $(LIBS) - -foomodule.o: foomodule.c - - -$(OBJS) : $(SRCS) -%.o : %.f ; $(FC) -c $(FFLAGS) $< -%.o : %.f90 ; $(FC) -c $(FFLAGS) $< - -test: foomodule$(SO) - python -c 'import foo;print foo.__doc__' -install: foomodule$(SO) - $(INSTALLDIR) $(INSTALLDIRECTORY) - $(INSTALLEXEC) foomodule$(SO) $(INSTALLDIRECTORY) - cd $(INSTALLDIRECTORY) && echo "$(INSTALLNAME)" > ../$(INSTALLNAME).pth - -.PHONY: clean distclean debug test install foo -debug: - echo "OBJS=$(OBJS)" - echo "SRCS=$(SRCS)" -clean: - $(RM) *.o *.mod core foomodule.{dvi,log} $(OBJS) -distclean: clean - $(RM) *.so *.sl foomodule.{tex,so} - $(RM) .f2py_get_compiler_* diff --git a/numpy/f2py/src/test/bar.f b/numpy/f2py/src/test/bar.f deleted file mode 100644 index 5354ceaf9..000000000 --- a/numpy/f2py/src/test/bar.f +++ /dev/null @@ -1,11 +0,0 @@ - subroutine bar() - integer a - real*8 b,c(3) - common /foodata/ a,b,c - a = 4 - b = 6.7 - c(2) = 3.0 - write(*,*) "bar:a=",a - write(*,*) "bar:b=",b - write(*,*) "bar:c=",c - end diff --git a/numpy/f2py/src/test/foo.f b/numpy/f2py/src/test/foo.f deleted file mode 100644 index 5354ceaf9..000000000 --- a/numpy/f2py/src/test/foo.f +++ /dev/null @@ -1,11 +0,0 @@ - subroutine bar() - integer a - real*8 b,c(3) - common /foodata/ a,b,c - a = 4 - b = 6.7 - c(2) = 3.0 - write(*,*) "bar:a=",a - write(*,*) "bar:b=",b - write(*,*) "bar:c=",c - end diff --git a/numpy/f2py/src/test/foo90.f90 b/numpy/f2py/src/test/foo90.f90 deleted file mode 100644 index dbca7e95b..000000000 --- a/numpy/f2py/src/test/foo90.f90 +++ /dev/null @@ -1,13 +0,0 @@ -subroutine foo() - integer a - real*8 b,c(3) - common /foodata/ a,b,c - print*, " F: in foo" - a = 5 - b = 6.3 - c(2) = 9.1 -end subroutine foo - - - - diff --git a/numpy/f2py/src/test/foomodule.c b/numpy/f2py/src/test/foomodule.c deleted file mode 100644 index 0a954676e..000000000 --- a/numpy/f2py/src/test/foomodule.c +++ /dev/null @@ -1,143 +0,0 @@ -/* File: foomodule.c - * Example of FortranObject usage. See also wrap.f foo.f foo90.f90. - * Author: Pearu Peterson <pearu@ioc.ee>. - * http://cens.ioc.ee/projects/f2py2e/ - * $Revision: 1.2 $ - * $Date: 2000/09/17 16:10:27 $ - */ -#ifdef __CPLUSPLUS__ -extern "C" { -#endif - -#include "Python.h" -#include "fortranobject.h" - -static PyObject *foo_error; - -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F -#else -#define F_FUNC(f,F) f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F##_ -#else -#define F_FUNC(f,F) f##_ -#endif -#endif - - /************* foo_bar *************/ - static char doc_foo_bar[] = "\ -Function signature:\n\ - bar()\n\ -"; - static PyObject *foo_bar(PyObject *capi_self, PyObject *capi_args, - PyObject *capi_keywds, void (*f2py_func)()) { - PyObject *capi_buildvalue = NULL; - static char *capi_kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\ - "|:foo.bar",\ - capi_kwlist)) - goto capi_fail; - (*f2py_func)(); - capi_buildvalue = Py_BuildValue(""); - capi_fail: - return capi_buildvalue; - } - /************ mod_init **************/ - static PyObject *mod_init(PyObject *capi_self, PyObject *capi_args, - PyObject *capi_keywds, void (*f2py_func)()) { - PyObject *capi_buildvalue = NULL; - static char *capi_kwlist[] = {NULL}; - if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\ - "|:mod.init",\ - capi_kwlist)) - goto capi_fail; - (*f2py_func)(); - capi_buildvalue = Py_BuildValue(""); - capi_fail: - return capi_buildvalue; - } - - /* F90 module */ - static FortranDataDef f2py_mod_def[] = { - {"a",0, {}, PyArray_INT}, - {"b",0, {}, PyArray_DOUBLE}, - {"c",1, {3}, PyArray_DOUBLE}, - {"d",1, {-1}, PyArray_DOUBLE}, - {"init",-1,{},0,NULL,(void *)mod_init}, - {NULL} - }; - static void f2py_setup_mod(char *a,char *b,char *c,void (*d)(),char *init) { - f2py_mod_def[0].data = a; - f2py_mod_def[1].data = b; - f2py_mod_def[2].data = c; - f2py_mod_def[3].func = d; - f2py_mod_def[4].data = init; - } - extern void F_FUNC(f2pyinitmod,F2PYINITMOD)(); - static void f2py_init_mod() { - F_FUNC(f2pyinitmod,F2PYINITMOD)(f2py_setup_mod); - } - - /* COMMON block */ - static FortranDataDef f2py_foodata_def[] = { - {"a",0, {}, PyArray_INT}, - {"b",0, {}, PyArray_DOUBLE}, - {"c",1, {3}, PyArray_DOUBLE}, - {NULL} - }; - static void f2py_setup_foodata(char *a,char *b,char *c) { - f2py_foodata_def[0].data = a; - f2py_foodata_def[1].data = b; - f2py_foodata_def[2].data = c; - } - extern void F_FUNC(f2pyinitfoodata,F2PYINITFOODATA)(); - static void f2py_init_foodata() { - F_FUNC(f2pyinitfoodata,F2PYINITFOODATA)(f2py_setup_foodata); - } - - /* Fortran routines (needs no initialization/setup function) */ - extern void F_FUNC(bar,BAR)(); - extern void F_FUNC(foo,FOO)(); - static FortranDataDef f2py_routines_def[] = { - {"bar",-1, {}, 0, (char *)F_FUNC(bar,BAR),(void *)foo_bar,doc_foo_bar}, - {"foo",-1, {}, 0, (char *)F_FUNC(foo,FOO),(void *)foo_bar,doc_foo_bar}, - {NULL} - }; - -static PyMethodDef foo_module_methods[] = { -/*eof method*/ - {NULL,NULL} -}; - -void initfoo() { - int i; - PyObject *m, *d, *s; - PyTypeObject *t; - PyObject *f; - import_array(); - - m = Py_InitModule("foo", foo_module_methods); - - d = PyModule_GetDict(m); - s = PyString_FromString("This module 'foo' demonstrates the usage of fortranobject."); - PyDict_SetItemString(d, "__doc__", s); - - /* Fortran objects: */ - PyDict_SetItemString(d, "mod", PyFortranObject_New(f2py_mod_def,f2py_init_mod)); - PyDict_SetItemString(d, "foodata", PyFortranObject_New(f2py_foodata_def,f2py_init_foodata)); - for(i=0;f2py_routines_def[i].name!=NULL;i++) - PyDict_SetItemString(d, f2py_routines_def[i].name, - PyFortranObject_NewAsAttr(&f2py_routines_def[i])); - - Py_DECREF(s); - - if (PyErr_Occurred()) - Py_FatalError("can't initialize module foo"); -} -#ifdef __CPLUSCPLUS__ -} -#endif diff --git a/numpy/f2py/src/test/wrap.f b/numpy/f2py/src/test/wrap.f deleted file mode 100644 index 9414eb9f6..000000000 --- a/numpy/f2py/src/test/wrap.f +++ /dev/null @@ -1,70 +0,0 @@ - subroutine f2py_mod_get_dims(f2py_r,f2py_s,f2py_set,f2py_n) - use mod - external f2py_set - logical f2py_ns - integer f2py_s(*),f2py_r,f2py_i,f2py_j - character*(*) f2py_n - if ("d".eq.f2py_n) then - f2py_ns = .FALSE. - if (allocated(d)) then - do f2py_i=1,f2py_r - if ((size(d,f2py_r-f2py_i+1).ne.f2py_s(f2py_i)).and. - c (f2py_s(f2py_i).ge.0)) then - f2py_ns = .TRUE. - end if - end do - if (f2py_ns) then - deallocate(d) - end if - end if - if (.not.allocated(d)) then - allocate(d(f2py_s(1))) - end if - if (allocated(d)) then - do f2py_i=1,f2py_r - f2py_s(f2py_i) = size(d,f2py_r-f2py_i+1) - end do - call f2py_set(d) - end if - end if - end subroutine f2py_mod_get_dims - subroutine f2py_mod_get_dims_d(r,s,set_data) - use mod, only: d => d - external set_data - logical ns - integer s(*),r,i,j - ns = .FALSE. - if (allocated(d)) then - do i=1,r - if ((size(d,r-i+1).ne.s(i)).and.(s(i).ge.0)) then - ns = .TRUE. - end if - end do - if (ns) then - deallocate(d) - end if - end if - if (.not.allocated(d).and.(s(1).ge.1)) then - allocate(d(s(1))) - end if - if (allocated(d)) then - do i=1,r - s(i) = size(d,r-i+1) - end do - end if - call set_data(d,allocated(d)) - end subroutine f2py_mod_get_dims_d - - subroutine f2pyinitmod(setupfunc) - use mod - external setupfunc,f2py_mod_get_dims_d,init - call setupfunc(a,b,c,f2py_mod_get_dims_d,init) - end subroutine f2pyinitmod - - subroutine f2pyinitfoodata(setupfunc) - external setupfunc - integer a - real*8 b,c(3) - common /foodata/ a,b,c - call setupfunc(a,b,c) - end subroutine f2pyinitfoodata diff --git a/numpy/f2py/tests/array_from_pyobj/__init__.py b/numpy/f2py/tests/array_from_pyobj/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/numpy/f2py/tests/array_from_pyobj/__init__.py +++ /dev/null diff --git a/numpy/f2py/tests/array_from_pyobj/setup.py b/numpy/f2py/tests/array_from_pyobj/setup.py deleted file mode 100644 index f449117a7..000000000 --- a/numpy/f2py/tests/array_from_pyobj/setup.py +++ /dev/null @@ -1,26 +0,0 @@ - -import os -def configuration(parent_name='',top_path=None): - from numpy.distutils.misc_util import Configuration - - config = Configuration('array_from_pyobj',parent_name,top_path) - #import numpy.f2py as f2py - #f2pydir=os.path.dirname(os.path.abspath(f2py.__file__)) - f2pydir=os.path.join(config.local_path,'..','..') - fobjhsrc = os.path.join(f2pydir,'src','fortranobject.h') - fobjcsrc = os.path.join(f2pydir,'src','fortranobject.c') - config.add_extension('wrap', - sources = ['wrapmodule.c',fobjcsrc], - include_dirs = [os.path.dirname(fobjhsrc)], - depends = [fobjhsrc,fobjcsrc], - define_macros = [('DEBUG_COPY_ND_ARRAY',1), - #('F2PY_REPORT_ON_ARRAY_COPY',1), - #('F2PY_REPORT_ATEXIT',1) - ] - ) - - return config - -if __name__ == "__main__": - from numpy.distutils.core import setup - setup(**configuration(top_path='').todict()) diff --git a/numpy/f2py/tests/array_from_pyobj/tests/test_array_from_pyobj.py b/numpy/f2py/tests/array_from_pyobj/tests/test_array_from_pyobj.py deleted file mode 100644 index 2a6ec85f7..000000000 --- a/numpy/f2py/tests/array_from_pyobj/tests/test_array_from_pyobj.py +++ /dev/null @@ -1,515 +0,0 @@ -import unittest -import sys -import copy - -from numpy.testing import * -from numpy import array, alltrue, ndarray, asarray, can_cast,zeros, dtype -from numpy.core.multiarray import typeinfo - -set_package_path() -from array_from_pyobj import wrap -del sys.path[0] - -def flags_info(arr): - flags = wrap.array_attrs(arr)[6] - return flags2names(flags) - -def flags2names(flags): - info = [] - for flagname in ['CONTIGUOUS','FORTRAN','OWNDATA','ENSURECOPY', - 'ENSUREARRAY','ALIGNED','NOTSWAPPED','WRITEABLE', - 'UPDATEIFCOPY','BEHAVED_FLAGS','BEHAVED_FLAGS_RO', - 'CARRAY_FLAGS','FARRAY_FLAGS' - ]: - if abs(flags) & getattr(wrap,flagname): - info.append(flagname) - return info - -class Intent: - def __init__(self,intent_list=[]): - self.intent_list = intent_list[:] - flags = 0 - for i in intent_list: - if i=='optional': - flags |= wrap.F2PY_OPTIONAL - else: - flags |= getattr(wrap,'F2PY_INTENT_'+i.upper()) - self.flags = flags - def __getattr__(self,name): - name = name.lower() - if name=='in_': name='in' - return self.__class__(self.intent_list+[name]) - def __str__(self): - return 'intent(%s)' % (','.join(self.intent_list)) - def __repr__(self): - return 'Intent(%r)' % (self.intent_list) - def is_intent(self,*names): - for name in names: - if name not in self.intent_list: - return False - return True - def is_intent_exact(self,*names): - return len(self.intent_list)==len(names) and self.is_intent(*names) - -intent = Intent() - -class Type(object): - - _type_names = ['BOOL','BYTE','UBYTE','SHORT','USHORT','INT','UINT', - 'LONG','ULONG','LONGLONG','ULONGLONG', - 'FLOAT','DOUBLE','LONGDOUBLE','CFLOAT','CDOUBLE', - 'CLONGDOUBLE'] - _type_cache = {} - - _cast_dict = {'BOOL':['BOOL']} - _cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE'] - _cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE'] - _cast_dict['BYTE'] = ['BYTE'] - _cast_dict['UBYTE'] = ['UBYTE'] - _cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE','SHORT'] - _cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE','USHORT'] - _cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT','INT'] - _cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT','UINT'] - - _cast_dict['LONG'] = _cast_dict['INT'] + ['LONG'] - _cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG'] - - _cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG'] - _cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG'] - - _cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT','FLOAT'] - _cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT','FLOAT','DOUBLE'] - _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + ['ULONG','FLOAT','DOUBLE','LONGDOUBLE'] - - _cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT'] - _cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT','CDOUBLE'] - _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + ['CFLOAT','CDOUBLE','CLONGDOUBLE'] - - - def __new__(cls,name): - if isinstance(name,dtype): - dtype0 = name - name = None - for n,i in typeinfo.items(): - if isinstance(i,tuple) and dtype0.type is i[-1]: - name = n - break - obj = cls._type_cache.get(name.upper(),None) - if obj is not None: - return obj - obj = object.__new__(cls) - obj._init(name) - cls._type_cache[name.upper()] = obj - return obj - - def _init(self,name): - self.NAME = name.upper() - self.type_num = getattr(wrap,'PyArray_'+self.NAME) - assert_equal(self.type_num,typeinfo[self.NAME][1]) - self.dtype = typeinfo[self.NAME][-1] - self.elsize = typeinfo[self.NAME][2] / 8 - self.dtypechar = typeinfo[self.NAME][0] - - def cast_types(self): - return map(self.__class__,self._cast_dict[self.NAME]) - - def all_types(self): - return map(self.__class__,self._type_names) - - def smaller_types(self): - bits = typeinfo[self.NAME][3] - types = [] - for name in self._type_names: - if typeinfo[name][3]<bits: - types.append(Type(name)) - return types - - def equal_types(self): - bits = typeinfo[self.NAME][3] - types = [] - for name in self._type_names: - if name==self.NAME: continue - if typeinfo[name][3]==bits: - types.append(Type(name)) - return types - - def larger_types(self): - bits = typeinfo[self.NAME][3] - types = [] - for name in self._type_names: - if typeinfo[name][3]>bits: - types.append(Type(name)) - return types - -class Array: - def __init__(self,typ,dims,intent,obj): - self.type = typ - self.dims = dims - self.intent = intent - self.obj_copy = copy.deepcopy(obj) - self.obj = obj - - # arr.dtypechar may be different from typ.dtypechar - self.arr = wrap.call(typ.type_num,dims,intent.flags,obj) - - self.arr_attr = wrap.array_attrs(self.arr) - - if len(dims)>1: - if self.intent.is_intent('c'): - assert intent.flags & wrap.F2PY_INTENT_C - assert not self.arr.flags['FORTRAN'],`self.arr.flags,obj.flags` - assert self.arr.flags['CONTIGUOUS'] - assert not self.arr_attr[6] & wrap.FORTRAN - else: - assert not intent.flags & wrap.F2PY_INTENT_C - assert self.arr.flags['FORTRAN'] - assert not self.arr.flags['CONTIGUOUS'] - assert self.arr_attr[6] & wrap.FORTRAN - - if obj is None: - self.pyarr = None - self.pyarr_attr = None - return - - if intent.is_intent('cache'): - assert isinstance(obj,ndarray),`type(obj)` - self.pyarr = array(obj).reshape(*dims) - - else: - self.pyarr = array(array(obj, - dtype = typ.dtypechar).reshape(*dims), - fortran=not self.intent.is_intent('c')) - assert self.pyarr.dtype.char==typ.dtypechar,\ - `self.pyarr.dtype.char,typ.dtypechar` - assert self.pyarr.flags['OWNDATA'] - self.pyarr_attr = wrap.array_attrs(self.pyarr) - - if len(dims)>1: - if self.intent.is_intent('c'): - assert not self.pyarr.flags['FORTRAN'] - assert self.pyarr.flags['CONTIGUOUS'] - assert not self.pyarr_attr[6] & wrap.FORTRAN - else: - assert self.pyarr.flags['FORTRAN'] - assert not self.pyarr.flags['CONTIGUOUS'] - assert self.pyarr_attr[6] & wrap.FORTRAN - - - assert self.arr_attr[1]==self.pyarr_attr[1] # nd - assert self.arr_attr[2]==self.pyarr_attr[2] # dimensions - if self.arr_attr[1]<=1: - assert self.arr_attr[3]==self.pyarr_attr[3],\ - `self.arr_attr[3],self.pyarr_attr[3],self.arr.tostring(),self.pyarr.tostring()` # strides - assert self.arr_attr[5][-2:]==self.pyarr_attr[5][-2:],\ - `self.arr_attr[5],self.pyarr_attr[5]` # descr - assert self.arr_attr[6]==self.pyarr_attr[6],\ - `self.arr_attr[6],self.pyarr_attr[6],flags2names(0*self.arr_attr[6]-self.pyarr_attr[6]),flags2names(self.arr_attr[6]),intent` # flags - - if intent.is_intent('cache'): - assert self.arr_attr[5][3]>=self.type.elsize,\ - `self.arr_attr[5][3],self.type.elsize` - else: - assert self.arr_attr[5][3]==self.type.elsize,\ - `self.arr_attr[5][3],self.type.elsize` - assert self.arr_equal(self.pyarr,self.arr) - - if isinstance(self.obj,ndarray): - if typ.elsize==Type(obj.dtype).elsize: - if not intent.is_intent('copy') and self.arr_attr[1]<=1: - assert self.has_shared_memory() - - def arr_equal(self,arr1,arr2): - if arr1.shape != arr2.shape: - return False - s = arr1==arr2 - return alltrue(s.flatten()) - - def __str__(self): - return str(self.arr) - - def has_shared_memory(self): - """Check that created array shares data with input array. - """ - if self.obj is self.arr: - return True - if not isinstance(self.obj,ndarray): - return False - obj_attr = wrap.array_attrs(self.obj) - return obj_attr[0]==self.arr_attr[0] - -################################################## - -class test_intent(unittest.TestCase): - def check_in_out(self): - assert_equal(str(intent.in_.out),'intent(in,out)') - assert intent.in_.c.is_intent('c') - assert not intent.in_.c.is_intent_exact('c') - assert intent.in_.c.is_intent_exact('c','in') - assert intent.in_.c.is_intent_exact('in','c') - assert not intent.in_.is_intent('c') - -class _test_shared_memory: - num2seq = [1,2] - num23seq = [[1,2,3],[4,5,6]] - def check_in_from_2seq(self): - a = self.array([2],intent.in_,self.num2seq) - assert not a.has_shared_memory() - - def check_in_from_2casttype(self): - for t in self.type.cast_types(): - obj = array(self.num2seq,dtype=t.dtype) - a = self.array([len(self.num2seq)],intent.in_,obj) - if t.elsize==self.type.elsize: - assert a.has_shared_memory(),`self.type.dtype,t.dtype` - else: - assert not a.has_shared_memory(),`t.dtype` - - def check_inout_2seq(self): - obj = array(self.num2seq,dtype=self.type.dtype) - a = self.array([len(self.num2seq)],intent.inout,obj) - assert a.has_shared_memory() - - try: - a = self.array([2],intent.in_.inout,self.num2seq) - except TypeError,msg: - if not str(msg).startswith('failed to initialize intent(inout|inplace|cache) array'): - raise - else: - raise SystemError,'intent(inout) should have failed on sequence' - - def check_f_inout_23seq(self): - obj = array(self.num23seq,dtype=self.type.dtype,fortran=1) - shape = (len(self.num23seq),len(self.num23seq[0])) - a = self.array(shape,intent.in_.inout,obj) - assert a.has_shared_memory() - - obj = array(self.num23seq,dtype=self.type.dtype,fortran=0) - shape = (len(self.num23seq),len(self.num23seq[0])) - try: - a = self.array(shape,intent.in_.inout,obj) - except ValueError,msg: - if not str(msg).startswith('failed to initialize intent(inout) array'): - raise - else: - raise SystemError,'intent(inout) should have failed on improper array' - - def check_c_inout_23seq(self): - obj = array(self.num23seq,dtype=self.type.dtype) - shape = (len(self.num23seq),len(self.num23seq[0])) - a = self.array(shape,intent.in_.c.inout,obj) - assert a.has_shared_memory() - - def check_in_copy_from_2casttype(self): - for t in self.type.cast_types(): - obj = array(self.num2seq,dtype=t.dtype) - a = self.array([len(self.num2seq)],intent.in_.copy,obj) - assert not a.has_shared_memory(),`t.dtype` - - def check_c_in_from_23seq(self): - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_,self.num23seq) - assert not a.has_shared_memory() - - def check_in_from_23casttype(self): - for t in self.type.cast_types(): - obj = array(self.num23seq,dtype=t.dtype) - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_,obj) - assert not a.has_shared_memory(),`t.dtype` - - def check_f_in_from_23casttype(self): - for t in self.type.cast_types(): - obj = array(self.num23seq,dtype=t.dtype,fortran=1) - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_,obj) - if t.elsize==self.type.elsize: - assert a.has_shared_memory(),`t.dtype` - else: - assert not a.has_shared_memory(),`t.dtype` - - def check_c_in_from_23casttype(self): - for t in self.type.cast_types(): - obj = array(self.num23seq,dtype=t.dtype) - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_.c,obj) - if t.elsize==self.type.elsize: - assert a.has_shared_memory(),`t.dtype` - else: - assert not a.has_shared_memory(),`t.dtype` - - def check_f_copy_in_from_23casttype(self): - for t in self.type.cast_types(): - obj = array(self.num23seq,dtype=t.dtype,fortran=1) - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_.copy,obj) - assert not a.has_shared_memory(),`t.dtype` - - def check_c_copy_in_from_23casttype(self): - for t in self.type.cast_types(): - obj = array(self.num23seq,dtype=t.dtype) - a = self.array([len(self.num23seq),len(self.num23seq[0])], - intent.in_.c.copy,obj) - assert not a.has_shared_memory(),`t.dtype` - - def check_in_cache_from_2casttype(self): - for t in self.type.all_types(): - if t.elsize != self.type.elsize: - continue - obj = array(self.num2seq,dtype=t.dtype) - shape = (len(self.num2seq),) - a = self.array(shape,intent.in_.c.cache,obj) - assert a.has_shared_memory(),`t.dtype` - - a = self.array(shape,intent.in_.cache,obj) - assert a.has_shared_memory(),`t.dtype` - - obj = array(self.num2seq,dtype=t.dtype,fortran=1) - a = self.array(shape,intent.in_.c.cache,obj) - assert a.has_shared_memory(),`t.dtype` - - a = self.array(shape,intent.in_.cache,obj) - assert a.has_shared_memory(),`t.dtype` - - try: - a = self.array(shape,intent.in_.cache,obj[::-1]) - except ValueError,msg: - if not str(msg).startswith('failed to initialize intent(cache) array'): - raise - else: - raise SystemError,'intent(cache) should have failed on multisegmented array' - def check_in_cache_from_2casttype_failure(self): - for t in self.type.all_types(): - if t.elsize >= self.type.elsize: - continue - obj = array(self.num2seq,dtype=t.dtype) - shape = (len(self.num2seq),) - try: - a = self.array(shape,intent.in_.cache,obj) - except ValueError,msg: - if not str(msg).startswith('failed to initialize intent(cache) array'): - raise - else: - raise SystemError,'intent(cache) should have failed on smaller array' - - def check_cache_hidden(self): - shape = (2,) - a = self.array(shape,intent.cache.hide,None) - assert a.arr.shape==shape - - shape = (2,3) - a = self.array(shape,intent.cache.hide,None) - assert a.arr.shape==shape - - shape = (-1,3) - try: - a = self.array(shape,intent.cache.hide,None) - except ValueError,msg: - if not str(msg).startswith('failed to create intent(cache|hide)|optional array'): - raise - else: - raise SystemError,'intent(cache) should have failed on undefined dimensions' - - def check_hidden(self): - shape = (2,) - a = self.array(shape,intent.hide,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - - shape = (2,3) - a = self.array(shape,intent.hide,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - assert a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'] - - shape = (2,3) - a = self.array(shape,intent.c.hide,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - assert not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'] - - shape = (-1,3) - try: - a = self.array(shape,intent.hide,None) - except ValueError,msg: - if not str(msg).startswith('failed to create intent(cache|hide)|optional array'): - raise - else: - raise SystemError,'intent(hide) should have failed on undefined dimensions' - - def check_optional_none(self): - shape = (2,) - a = self.array(shape,intent.optional,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - - shape = (2,3) - a = self.array(shape,intent.optional,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - assert a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'] - - shape = (2,3) - a = self.array(shape,intent.c.optional,None) - assert a.arr.shape==shape - assert a.arr_equal(a.arr,zeros(shape,dtype=self.type.dtype)) - assert not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'] - - def check_optional_from_2seq(self): - obj = self.num2seq - shape = (len(obj),) - a = self.array(shape,intent.optional,obj) - assert a.arr.shape==shape - assert not a.has_shared_memory() - - def check_optional_from_23seq(self): - obj = self.num23seq - shape = (len(obj),len(obj[0])) - a = self.array(shape,intent.optional,obj) - assert a.arr.shape==shape - assert not a.has_shared_memory() - - a = self.array(shape,intent.optional.c,obj) - assert a.arr.shape==shape - assert not a.has_shared_memory() - - def check_inplace(self): - obj = array(self.num23seq,dtype=self.type.dtype) - assert not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'] - shape = obj.shape - a = self.array(shape,intent.inplace,obj) - assert obj[1][2]==a.arr[1][2],`obj,a.arr` - a.arr[1][2]=54 - assert obj[1][2]==a.arr[1][2]==array(54,dtype=self.type.dtype),`obj,a.arr` - assert a.arr is obj - assert obj.flags['FORTRAN'] # obj attributes are changed inplace! - assert not obj.flags['CONTIGUOUS'] - - def check_inplace_from_casttype(self): - for t in self.type.cast_types(): - if t is self.type: - continue - obj = array(self.num23seq,dtype=t.dtype) - assert obj.dtype.type==t.dtype - assert obj.dtype.type is not self.type.dtype - assert not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'] - shape = obj.shape - a = self.array(shape,intent.inplace,obj) - assert obj[1][2]==a.arr[1][2],`obj,a.arr` - a.arr[1][2]=54 - assert obj[1][2]==a.arr[1][2]==array(54,dtype=self.type.dtype),`obj,a.arr` - assert a.arr is obj - assert obj.flags['FORTRAN'] # obj attributes are changed inplace! - assert not obj.flags['CONTIGUOUS'] - assert obj.dtype.type is self.type.dtype # obj type is changed inplace! - -for t in Type._type_names: - exec '''\ -class test_%s_gen(unittest.TestCase, - _test_shared_memory - ): - type = Type(%r) - array = lambda self,dims,intent,obj: Array(Type(%r),dims,intent,obj) -''' % (t,t,t) - -if __name__ == "__main__": - ScipyTest().run() diff --git a/numpy/f2py/tests/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/array_from_pyobj/wrapmodule.c deleted file mode 100644 index 58d7e6da4..000000000 --- a/numpy/f2py/tests/array_from_pyobj/wrapmodule.c +++ /dev/null @@ -1,196 +0,0 @@ -/* File: wrapmodule.c - * This file is auto-generated with f2py (version:2_1330). - * Hand edited by Pearu. - * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition, - * written by Pearu Peterson <pearu@cens.ioc.ee>. - * See http://cens.ioc.ee/projects/f2py2e/ - * Generation date: Fri Oct 21 22:41:12 2005 - * $Revision:$ - * $Date:$ - * Do not edit this file directly unless you know what you are doing!!! - */ -#ifdef __cplusplus -extern "C" { -#endif - -/*********************** See f2py2e/cfuncs.py: includes ***********************/ -#include "Python.h" -#include "fortranobject.h" -#include <math.h> - -static PyObject *wrap_error; -static PyObject *wrap_module; - -/************************************ call ************************************/ -static char doc_f2py_rout_wrap_call[] = "\ -Function signature:\n\ - arr = call(type_num,dims,intent,obj)\n\ -Required arguments:\n" -" type_num : input int\n" -" dims : input int-sequence\n" -" intent : input int\n" -" obj : input python object\n" -"Return objects:\n" -" arr : array"; -static PyObject *f2py_rout_wrap_call(PyObject *capi_self, - PyObject *capi_args) { - PyObject * volatile capi_buildvalue = NULL; - int type_num = 0; - intp *dims = NULL; - PyObject *dims_capi = Py_None; - int rank = 0; - int intent = 0; - PyArrayObject *capi_arr_tmp = NULL; - PyObject *arr_capi = Py_None; - int i; - - if (!PyArg_ParseTuple(capi_args,"iOiO|:wrap.call",\ - &type_num,&dims_capi,&intent,&arr_capi)) - return NULL; - rank = PySequence_Length(dims_capi); - dims = malloc(rank*sizeof(intp)); - for (i=0;i<rank;++i) - dims[i] = (intp)PyInt_AsLong(PySequence_GetItem(dims_capi,i)); - - capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi); - if (capi_arr_tmp == NULL) - return NULL; - capi_buildvalue = Py_BuildValue("N",capi_arr_tmp); - free(dims); - return capi_buildvalue; -} - -static char doc_f2py_rout_wrap_attrs[] = "\ -Function signature:\n\ - arr = array_attrs(arr)\n\ -Required arguments:\n" -" arr : input array object\n" -"Return objects:\n" -" data : data address in hex\n" -" nd : int\n" -" dimensions : tuple\n" -" strides : tuple\n" -" base : python object\n" -" (kind,type,type_num,elsize,alignment) : 4-tuple\n" -" flags : int\n" -" itemsize : int\n" -; -static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self, - PyObject *capi_args) { - PyObject *arr_capi = Py_None; - PyArrayObject *arr = NULL; - PyObject *dimensions = NULL; - PyObject *strides = NULL; - char s[100]; - int i; - memset(s,0,100*sizeof(char)); - if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs", - &PyArray_Type,&arr_capi)) - return NULL; - arr = (PyArrayObject *)arr_capi; - sprintf(s,"%p",arr->data); - dimensions = PyTuple_New(arr->nd); - strides = PyTuple_New(arr->nd); - for (i=0;i<arr->nd;++i) { - PyTuple_SetItem(dimensions,i,PyInt_FromLong(arr->dimensions[i])); - PyTuple_SetItem(strides,i,PyInt_FromLong(arr->strides[i])); - } - return Py_BuildValue("siOOO(cciii)ii",s,arr->nd, - dimensions,strides, - (arr->base==NULL?Py_None:arr->base), - arr->descr->kind, - arr->descr->type, - arr->descr->type_num, - arr->descr->elsize, - arr->descr->alignment, - arr->flags, - PyArray_ITEMSIZE(arr)); -} - -static PyMethodDef f2py_module_methods[] = { - - {"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call}, - {"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs}, - {NULL,NULL} -}; - -PyMODINIT_FUNC initwrap(void) { - PyObject *m,*d, *s; - m = wrap_module = Py_InitModule("wrap", f2py_module_methods); - PyFortran_Type.ob_type = &PyType_Type; - import_array(); - if (PyErr_Occurred()) - Py_FatalError("can't initialize module wrap (failed to import numpy)"); - d = PyModule_GetDict(m); - s = PyString_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n" -" arr = call(type_num,dims,intent,obj)\n" -"."); - PyDict_SetItemString(d, "__doc__", s); - wrap_error = PyErr_NewException ("wrap.error", NULL, NULL); - Py_DECREF(s); - PyDict_SetItemString(d, "F2PY_INTENT_IN", PyInt_FromLong(F2PY_INTENT_IN)); - PyDict_SetItemString(d, "F2PY_INTENT_INOUT", PyInt_FromLong(F2PY_INTENT_INOUT)); - PyDict_SetItemString(d, "F2PY_INTENT_OUT", PyInt_FromLong(F2PY_INTENT_OUT)); - PyDict_SetItemString(d, "F2PY_INTENT_HIDE", PyInt_FromLong(F2PY_INTENT_HIDE)); - PyDict_SetItemString(d, "F2PY_INTENT_CACHE", PyInt_FromLong(F2PY_INTENT_CACHE)); - PyDict_SetItemString(d, "F2PY_INTENT_COPY", PyInt_FromLong(F2PY_INTENT_COPY)); - PyDict_SetItemString(d, "F2PY_INTENT_C", PyInt_FromLong(F2PY_INTENT_C)); - PyDict_SetItemString(d, "F2PY_OPTIONAL", PyInt_FromLong(F2PY_OPTIONAL)); - PyDict_SetItemString(d, "F2PY_INTENT_INPLACE", PyInt_FromLong(F2PY_INTENT_INPLACE)); - PyDict_SetItemString(d, "PyArray_BOOL", PyInt_FromLong(PyArray_BOOL)); - PyDict_SetItemString(d, "PyArray_BYTE", PyInt_FromLong(PyArray_BYTE)); - PyDict_SetItemString(d, "PyArray_UBYTE", PyInt_FromLong(PyArray_UBYTE)); - PyDict_SetItemString(d, "PyArray_SHORT", PyInt_FromLong(PyArray_SHORT)); - PyDict_SetItemString(d, "PyArray_USHORT", PyInt_FromLong(PyArray_USHORT)); - PyDict_SetItemString(d, "PyArray_INT", PyInt_FromLong(PyArray_INT)); - PyDict_SetItemString(d, "PyArray_UINT", PyInt_FromLong(PyArray_UINT)); - PyDict_SetItemString(d, "PyArray_INTP", PyInt_FromLong(PyArray_INTP)); - PyDict_SetItemString(d, "PyArray_UINTP", PyInt_FromLong(PyArray_UINTP)); - PyDict_SetItemString(d, "PyArray_LONG", PyInt_FromLong(PyArray_LONG)); - PyDict_SetItemString(d, "PyArray_ULONG", PyInt_FromLong(PyArray_ULONG)); - PyDict_SetItemString(d, "PyArray_LONGLONG", PyInt_FromLong(PyArray_LONGLONG)); - PyDict_SetItemString(d, "PyArray_ULONGLONG", PyInt_FromLong(PyArray_ULONGLONG)); - PyDict_SetItemString(d, "PyArray_FLOAT", PyInt_FromLong(PyArray_FLOAT)); - PyDict_SetItemString(d, "PyArray_DOUBLE", PyInt_FromLong(PyArray_DOUBLE)); - PyDict_SetItemString(d, "PyArray_LONGDOUBLE", PyInt_FromLong(PyArray_LONGDOUBLE)); - PyDict_SetItemString(d, "PyArray_CFLOAT", PyInt_FromLong(PyArray_CFLOAT)); - PyDict_SetItemString(d, "PyArray_CDOUBLE", PyInt_FromLong(PyArray_CDOUBLE)); - PyDict_SetItemString(d, "PyArray_CLONGDOUBLE", PyInt_FromLong(PyArray_CLONGDOUBLE)); - PyDict_SetItemString(d, "PyArray_OBJECT", PyInt_FromLong(PyArray_OBJECT)); - PyDict_SetItemString(d, "PyArray_STRING", PyInt_FromLong(PyArray_STRING)); - PyDict_SetItemString(d, "PyArray_UNICODE", PyInt_FromLong(PyArray_UNICODE)); - PyDict_SetItemString(d, "PyArray_VOID", PyInt_FromLong(PyArray_VOID)); - PyDict_SetItemString(d, "PyArray_NTYPES", PyInt_FromLong(PyArray_NTYPES)); - PyDict_SetItemString(d, "PyArray_NOTYPE", PyInt_FromLong(PyArray_NOTYPE)); - PyDict_SetItemString(d, "PyArray_UDERDEF", PyInt_FromLong(PyArray_USERDEF)); - - PyDict_SetItemString(d, "CONTIGUOUS", PyInt_FromLong(CONTIGUOUS)); - PyDict_SetItemString(d, "FORTRAN", PyInt_FromLong(FORTRAN)); - PyDict_SetItemString(d, "OWNDATA", PyInt_FromLong(OWNDATA)); - PyDict_SetItemString(d, "FORCECAST", PyInt_FromLong(FORCECAST)); - PyDict_SetItemString(d, "ENSURECOPY", PyInt_FromLong(ENSURECOPY)); - PyDict_SetItemString(d, "ENSUREARRAY", PyInt_FromLong(ENSUREARRAY)); - PyDict_SetItemString(d, "ALIGNED", PyInt_FromLong(ALIGNED)); - PyDict_SetItemString(d, "WRITEABLE", PyInt_FromLong(WRITEABLE)); - PyDict_SetItemString(d, "UPDATEIFCOPY", PyInt_FromLong(UPDATEIFCOPY)); - - PyDict_SetItemString(d, "BEHAVED_FLAGS", PyInt_FromLong(BEHAVED_FLAGS)); - PyDict_SetItemString(d, "BEHAVED_NS_FLAGS", PyInt_FromLong(BEHAVED_NS_FLAGS)); - PyDict_SetItemString(d, "CARRAY_FLAGS", PyInt_FromLong(CARRAY_FLAGS)); - PyDict_SetItemString(d, "FARRAY_FLAGS", PyInt_FromLong(FARRAY_FLAGS)); - PyDict_SetItemString(d, "CARRAY_FLAGS_RO", PyInt_FromLong(CARRAY_FLAGS_RO)); - PyDict_SetItemString(d, "FARRAY_FLAGS_RO", PyInt_FromLong(FARRAY_FLAGS_RO)); - PyDict_SetItemString(d, "DEFAULT_FLAGS", PyInt_FromLong(DEFAULT_FLAGS)); - PyDict_SetItemString(d, "UPDATE_ALL_FLAGS", PyInt_FromLong(UPDATE_ALL_FLAGS)); - - if (PyErr_Occurred()) - Py_FatalError("can't initialize module wrap"); - -#ifdef F2PY_REPORT_ATEXIT - on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call"); -#endif - -} -#ifdef __cplusplus -} -#endif diff --git a/numpy/f2py/tests/c/return_real.py b/numpy/f2py/tests/c/return_real.py deleted file mode 100644 index 27e0843f1..000000000 --- a/numpy/f2py/tests/c/return_real.py +++ /dev/null @@ -1,108 +0,0 @@ -__usage__ = """ -Run: - python return_real.py [<f2py options>] -Examples: - python return_real.py --fcompiler=Gnu --no-wrap-functions - python return_real.py --quiet -""" - - -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import c_ext_return_real - except ImportError: - assert not f2py2e.compile('''\ -python module c_ext_return_real -usercode \'\'\' -float t4(float value) { return value; } -void s4(float *t4, float value) { *t4 = value; } -double t8(double value) { return value; } -void s8(double *t8, double value) { *t8 = value; } -\'\'\' -interface - function t4(value) - real*4 intent(c) :: t4,value - end - function t8(value) - real*8 intent(c) :: t8,value - end - subroutine s4(t4,value) - intent(c) s4 - real*4 intent(out) :: t4 - real*4 intent(c) :: value - end - subroutine s8(t8,value) - intent(c) s8 - real*8 intent(out) :: t8 - real*8 intent(c) :: value - end -end interface -end python module c_ext_return_real -''','c_ext_return_real',f2py_opts,source_fn='c_ret_real.pyf') - - from c_ext_return_real import t4,t8,s4,s8 - test_functions = [t4,t8,s4,s8] - return test_functions - -def runtest(t): - import sys - if t.__doc__.split()[0] in ['t0','t4','s0','s4']: - err = 1e-5 - else: - err = 0.0 - assert abs(t(234)-234.0)<=err - assert abs(t(234.6)-234.6)<=err - assert abs(t(234l)-234.0)<=err - if sys.version[:3]<'2.3': - assert abs(t(234.6+3j)-234.6)<=err - assert abs(t('234')-234)<=err - assert abs(t('234.6')-234.6)<=err - assert abs(t(-234)+234)<=err - assert abs(t([234])-234)<=err - assert abs(t((234,))-234.)<=err - assert abs(t(array(234))-234.)<=err - assert abs(t(array([234]))-234.)<=err - assert abs(t(array([[234]]))-234.)<=err - assert abs(t(array([234],'1'))+22)<=err - assert abs(t(array([234],'s'))-234.)<=err - assert abs(t(array([234],'i'))-234.)<=err - assert abs(t(array([234],'l'))-234.)<=err - assert abs(t(array([234],'b'))-234.)<=err - assert abs(t(array([234],'f'))-234.)<=err - assert abs(t(array([234],'d'))-234.)<=err - if sys.version[:3]<'2.3': - assert abs(t(array([234+3j],'F'))-234.)<=err - assert abs(t(array([234],'D'))-234.)<=err - if t.__doc__.split()[0] in ['t0','t4','s0','s4']: - assert t(1e200)==t(1e300) # inf - - try: raise RuntimeError,`t(array([234],'c'))` - except ValueError: pass - try: raise RuntimeError,`t('abc')` - except ValueError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - try: - try: raise RuntimeError,`t(10l**400)` - except OverflowError: pass - except RuntimeError: - r = t(10l**400); assert `r` in ['inf','Infinity'],`r` - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f77/callback.py b/numpy/f2py/tests/f77/callback.py deleted file mode 100644 index 672504bc7..000000000 --- a/numpy/f2py/tests/f77/callback.py +++ /dev/null @@ -1,99 +0,0 @@ - -__usage__ = """ -Run: - python callback.py [<f2py options>] -Examples: - python callback.py --fcompiler=Gnu --no-wrap-functions - python callback.py --quiet -""" - -import f2py2e -import math -import sys -from Numeric import array - -def build(f2py_opts): - try: - import f77_ext_callback - except ImportError: - assert not f2py2e.compile('''\ - subroutine t(fun,a) - integer a -cf2py intent(out) a - external fun - call fun(a) - end - - subroutine func(a) -cf2py intent(in,out) a - integer a - a = a + 11 - end - - subroutine func0(a) -cf2py intent(out) a - integer a - a = 11 - end - - subroutine t2(a) -cf2py intent(callback) fun - integer a -cf2py intent(out) a - external fun - call fun(a) - end - -''','f77_ext_callback',f2py_opts,source_fn='f77_callback.f') - - from f77_ext_callback import t,t2 - test_functions = [t,t2] - return test_functions - -def runtest(t): - r = t(lambda : 4) - assert r==4,`r` - r = t(lambda a:5,fun_extra_args=(6,)) - assert r==5,`r` - r = t(lambda a:a,fun_extra_args=(6,)) - assert r==6,`r` - r = t(lambda a:5+a,fun_extra_args=(7,)) - assert r==12,`r` - if sys.version[:3]>='2.3': - r = t(lambda a:math.degrees(a),fun_extra_args=(math.pi,)) - assert r==180,`r` - r = t(math.degrees,fun_extra_args=(math.pi,)) - assert r==180,`r` - from f77_ext_callback import func,func0 - r = t(func,fun_extra_args=(6,)) - assert r==17,`r` - r = t(func0) - assert r==11,`r` - r = t(func0._cpointer) - assert r==11,`r` - class A: - def __call__(self): - return 7 - def mth(self): - return 9 - a = A() - r = t(a) - assert r==7,`r` - r = t(a.mth) - assert r==9,`r` - -if __name__=='__main__': - #import libwadpy - status = 1 - try: - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' - status = 0 - finally: - if status: - print '*'*20 - print 'Running f2py2e.diagnose' - import f2py2e.diagnose - f2py2e.diagnose.run() diff --git a/numpy/f2py/tests/f77/return_character.py b/numpy/f2py/tests/f77/return_character.py deleted file mode 100644 index 3361c11f5..000000000 --- a/numpy/f2py/tests/f77/return_character.py +++ /dev/null @@ -1,100 +0,0 @@ - -__usage__ = """ -Run: - python return_character.py [<f2py options>] -Examples: - python return_character.py --fcompiler=Gnu --no-wrap-functions - python return_character.py --quiet -""" - -import sys -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f77_ext_return_character - except ImportError: - assert not f2py2e.compile('''\ - function t0(value) - character value - character t0 - t0 = value - end - function t1(value) - character*1 value - character*1 t1 - t1 = value - end - function t5(value) - character*5 value - character*5 t5 - t5 = value - end - function ts(value) - character*(*) value - character*(*) ts - ts = value - end - - subroutine s0(t0,value) - character value - character t0 -cf2py intent(out) t0 - t0 = value - end - subroutine s1(t1,value) - character*1 value - character*1 t1 -cf2py intent(out) t1 - t1 = value - end - subroutine s5(t5,value) - character*5 value - character*5 t5 -cf2py intent(out) t5 - t5 = value - end - subroutine ss(ts,value) - character*(*) value - character*10 ts -cf2py intent(out) ts - ts = value - end -''','f77_ext_return_character',f2py_opts,source_fn='f77_ret_char.f') - - from f77_ext_return_character import t0,t1,t5,s0,s1,s5,ss - test_functions = [t0,t1,t5,s0,s1,s5,ss] - if sys.platform!='win32': # this is acctually compiler dependent case - from f77_ext_return_character import ts - test_functions.append(ts) - - return test_functions - -def runtest(t): - tname = t.__doc__.split()[0] - if tname in ['t0','t1','s0','s1']: - assert t(23)=='2' - r = t('ab');assert r=='a',`r` - r = t(array('ab'));assert r=='a',`r` - r = t(array(77,'1'));assert r=='M',`r` - try: raise RuntimeError,`t(array([77,87]))` - except ValueError: pass - try: raise RuntimeError,`t(array(77))` - except ValueError: pass - elif tname in ['ts','ss']: - assert t(23)=='23 ',`t(23)` - assert t('123456789abcdef')=='123456789a' - elif tname in ['t5','s5']: - assert t(23)=='23 ',`t(23)` - assert t('ab')=='ab ',`t('ab')` - assert t('123456789abcdef')=='12345' - else: - raise NotImplementedError - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f77/return_complex.py b/numpy/f2py/tests/f77/return_complex.py deleted file mode 100644 index 9993bb6eb..000000000 --- a/numpy/f2py/tests/f77/return_complex.py +++ /dev/null @@ -1,125 +0,0 @@ -__usage__ = """ -Run: - python return_complex.py [<f2py options>] -Examples: - python return_complex.py --fcompiler=Gnu --no-wrap-functions - python return_complex.py --quiet -""" - - -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f77_ext_return_complex - except ImportError: - assert not f2py2e.compile('''\ - function t0(value) - complex value - complex t0 - t0 = value - end - function t8(value) - complex*8 value - complex*8 t8 - t8 = value - end - function t16(value) - complex*16 value - complex*16 t16 - t16 = value - end - function td(value) - double complex value - double complex td - td = value - end - - subroutine s0(t0,value) - complex value - complex t0 -cf2py intent(out) t0 - t0 = value - end - subroutine s8(t8,value) - complex*8 value - complex*8 t8 -cf2py intent(out) t8 - t8 = value - end - subroutine s16(t16,value) - complex*16 value - complex*16 t16 -cf2py intent(out) t16 - t16 = value - end - subroutine sd(td,value) - double complex value - double complex td -cf2py intent(out) td - td = value - end -''','f77_ext_return_complex',f2py_opts) - - from f77_ext_return_complex import t0,t8,t16,td,s0,s8,s16,sd - test_functions = [t0,t8,t16,td,s0,s8,s16,sd] - return test_functions - - -def runtest(t): - tname = t.__doc__.split()[0] - if tname in ['t0','t8','s0','s8']: - err = 1e-5 - else: - err = 0.0 - assert abs(t(234j)-234.0j)<=err - assert abs(t(234.6)-234.6)<=err - assert abs(t(234l)-234.0)<=err - assert abs(t(234.6+3j)-(234.6+3j))<=err - #assert abs(t('234')-234.)<=err - #assert abs(t('234.6')-234.6)<=err - assert abs(t(-234)+234.)<=err - assert abs(t([234])-234.)<=err - assert abs(t((234,))-234.)<=err - assert abs(t(array(234))-234.)<=err - assert abs(t(array(23+4j,'F'))-(23+4j))<=err - assert abs(t(array([234]))-234.)<=err - assert abs(t(array([[234]]))-234.)<=err - assert abs(t(array([234],'1'))+22.)<=err - assert abs(t(array([234],'s'))-234.)<=err - assert abs(t(array([234],'i'))-234.)<=err - assert abs(t(array([234],'l'))-234.)<=err - assert abs(t(array([234],'b'))-234.)<=err - assert abs(t(array([234],'f'))-234.)<=err - assert abs(t(array([234],'d'))-234.)<=err - assert abs(t(array([234+3j],'F'))-(234+3j))<=err - assert abs(t(array([234],'D'))-234.)<=err - - try: raise RuntimeError,`t(array([234],'c'))` - except TypeError: pass - try: raise RuntimeError,`t('abc')` - except TypeError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - try: - try: raise RuntimeError,`t(10l**400)` - except OverflowError: pass - except RuntimeError: - r = t(10l**400); assert `r` in ['(inf+0j)','(Infinity+0j)'],`r` - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f77/return_integer.py b/numpy/f2py/tests/f77/return_integer.py deleted file mode 100644 index 5bd7ae1ab..000000000 --- a/numpy/f2py/tests/f77/return_integer.py +++ /dev/null @@ -1,148 +0,0 @@ - -__usage__ = """ -Run: - python return_integer.py [<f2py options>] -Examples: - python return_integer.py --fcompiler=Gnu --no-wrap-functions - python return_integer.py --quiet -""" - -import numpy.f2py as f2py2e -from numpy import array - -def build(f2py_opts): - try: - import f77_ext_return_integer - except ImportError: - assert not f2py2e.compile('''\ - function t0(value) - integer value - integer t0 - t0 = value - end - function t1(value) - integer*1 value - integer*1 t1 - t1 = value - end - function t2(value) - integer*2 value - integer*2 t2 - t2 = value - end - function t4(value) - integer*4 value - integer*4 t4 - t4 = value - end - function t8(value) - integer*8 value - integer*8 t8 - t8 = value - end - - subroutine s0(t0,value) - integer value - integer t0 -cf2py intent(out) t0 - t0 = value - end - subroutine s1(t1,value) - integer*1 value - integer*1 t1 -cf2py intent(out) t1 - t1 = value - end - subroutine s2(t2,value) - integer*2 value - integer*2 t2 -cf2py intent(out) t2 - t2 = value - end - subroutine s4(t4,value) - integer*4 value - integer*4 t4 -cf2py intent(out) t4 - t4 = value - end - subroutine s8(t8,value) - integer*8 value - integer*8 t8 -cf2py intent(out) t8 - t8 = value - end - -''','f77_ext_return_integer',f2py_opts,source_fn='f77_ret_int.f') - - from f77_ext_return_integer import t0,t1,t2,t4,t8,s0,s1,s2,s4,s8 - test_functions = [t0,t1,t2,t4,t8,s0,s1,s2,s4,s8] - return test_functions - -def runtest(t): - import sys - assert t(123)==123,`t(123)` - assert t(123.6)==123 - assert t(123l)==123 - if sys.version[:3]<'2.3': - assert t(123.6+3j)==123 - assert t('123')==123 - assert t(-123)==-123 - assert t([123])==123 - assert t((123,))==123 - assert t(array(123))==123 - assert t(array([123]))==123 - assert t(array([[123]]))==123 - assert t(array([123],'b'))==123 - assert t(array([123],'h'))==123 - assert t(array([123],'i'))==123 - assert t(array([123],'l'))==123 - assert t(array([123],'B'))==123 - assert t(array([123],'f'))==123 - assert t(array([123],'d'))==123 - if sys.version[:3]<'2.3': - assert t(array([123+3j],'F'))==123 - assert t(array([123],'D'))==123 - - - try: raise RuntimeError,`t(array([123],'c'))` - except ValueError: pass - try: raise RuntimeError,`t('abc')` - except ValueError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - if t.__doc__.split()[0] in ['t8','s8']: - try: raise RuntimeError,`t(100000000000000000000000l)` - except OverflowError: pass - try: raise RuntimeError,`t(10000000011111111111111.23)` - except OverflowError: pass - else: - if sys.version[:3]<'2.3': - try: raise RuntimeError,`t(10000000000000l)` - except OverflowError: pass - try: raise RuntimeError,`t(10000000000.23)` - except OverflowError: pass - -if __name__=='__main__': - #import libwadpy - status = 1 - try: - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' - status = 0 - finally: - if status: - print '*'*20 - print 'Running f2py2e.diagnose' - import numpy.f2py.diagnose as diagnose - #diagnose.run() diff --git a/numpy/f2py/tests/f77/return_logical.py b/numpy/f2py/tests/f77/return_logical.py deleted file mode 100644 index ac807b5be..000000000 --- a/numpy/f2py/tests/f77/return_logical.py +++ /dev/null @@ -1,134 +0,0 @@ - -__usage__ = """ -Run: - python return_logical.py [<f2py options>] -Examples: - python return_logical.py --fcompiler=Gnu --no-wrap-functions - python return_logical.py --quiet -""" - -import f2py2e -from Numeric import array -try: True -except NameError: - True = 1 - False = 0 - -def build(f2py_opts): - try: - import f77_ext_return_logical - except ImportError: - assert not f2py2e.compile('''\ - function t0(value) - logical value - logical t0 - t0 = value - end - function t1(value) - logical*1 value - logical*1 t1 - t1 = value - end - function t2(value) - logical*2 value - logical*2 t2 - t2 = value - end - function t4(value) - logical*4 value - logical*4 t4 - t4 = value - end -c function t8(value) -c logical*8 value -c logical*8 t8 -c t8 = value -c end - - subroutine s0(t0,value) - logical value - logical t0 -cf2py intent(out) t0 - t0 = value - end - subroutine s1(t1,value) - logical*1 value - logical*1 t1 -cf2py intent(out) t1 - t1 = value - end - subroutine s2(t2,value) - logical*2 value - logical*2 t2 -cf2py intent(out) t2 - t2 = value - end - subroutine s4(t4,value) - logical*4 value - logical*4 t4 -cf2py intent(out) t4 - t4 = value - end -c subroutine s8(t8,value) -c logical*8 value -c logical*8 t8 -cf2py intent(out) t8 -c t8 = value -c end -''','f77_ext_return_logical',f2py_opts) - - #from f77_ext_return_logical import t0,t1,t2,t4,t8,s0,s1,s2,s4,s8 - #test_functions = [t0,t1,t2,t4,t8,s0,s1,s2,s4,s8] - from f77_ext_return_logical import t0,t1,t2,t4,s0,s1,s2,s4 - test_functions = [t0,t1,t2,t4,s0,s1,s2,s4] - return test_functions - -def runtest(t): - assert t(True)==1,`t(True)` - assert t(False)==0,`t(False)` - assert t(0)==0 - assert t(None)==0 - assert t(0.0)==0 - assert t(0j)==0 - assert t(1j)==1 - assert t(234)==1 - assert t(234.6)==1 - assert t(234l)==1 - assert t(234.6+3j)==1 - assert t('234')==1 - assert t('aaa')==1 - assert t('')==0 - assert t([])==0 - assert t(())==0 - assert t({})==0 - assert t(t)==1 - assert t(-234)==1 - assert t(10l**100)==1 - assert t([234])==1 - assert t((234,))==1 - assert t(array(234))==1 - assert t(array([234]))==1 - assert t(array([[234]]))==1 - assert t(array([234],'1'))==1 - assert t(array([234],'s'))==1 - assert t(array([234],'i'))==1 - assert t(array([234],'l'))==1 - assert t(array([234],'b'))==1 - assert t(array([234],'f'))==1 - assert t(array([234],'d'))==1 - assert t(array([234+3j],'F'))==1 - assert t(array([234],'D'))==1 - assert t(array(0))==0 - assert t(array([0]))==0 - assert t(array([[0]]))==0 - assert t(array([0j]))==0 - assert t(array([1]))==1 - assert t(array([0,0]))==0 - assert t(array([0,1]))==1 #XXX: is this expected? - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f77/return_real.py b/numpy/f2py/tests/f77/return_real.py deleted file mode 100644 index 29e720a85..000000000 --- a/numpy/f2py/tests/f77/return_real.py +++ /dev/null @@ -1,127 +0,0 @@ -__usage__ = """ -Run: - python return_real.py [<f2py options>] -Examples: - python return_real.py --fcompiler=Gnu --no-wrap-functions - python return_real.py --quiet -""" - - -import numpy.f2py as f2py2e -from numpy import array - -def build(f2py_opts): - try: - import f77_ext_return_real - except ImportError: - assert not f2py2e.compile('''\ - function t0(value) - real value - real t0 - t0 = value - end - function t4(value) - real*4 value - real*4 t4 - t4 = value - end - function t8(value) - real*8 value - real*8 t8 - t8 = value - end - function td(value) - double precision value - double precision td - td = value - end - - subroutine s0(t0,value) - real value - real t0 -cf2py intent(out) t0 - t0 = value - end - subroutine s4(t4,value) - real*4 value - real*4 t4 -cf2py intent(out) t4 - t4 = value - end - subroutine s8(t8,value) - real*8 value - real*8 t8 -cf2py intent(out) t8 - t8 = value - end - subroutine sd(td,value) - double precision value - double precision td -cf2py intent(out) td - td = value - end -''','f77_ext_return_real',f2py_opts,source_fn='f77_ret_real.f') - - from f77_ext_return_real import t0,t4,t8,td,s0,s4,s8,sd - test_functions = [t0,t4,t8,td,s0,s4,s8,sd] - return test_functions - -def runtest(t): - import sys - if t.__doc__.split()[0] in ['t0','t4','s0','s4']: - err = 1e-5 - else: - err = 0.0 - assert abs(t(234)-234.0)<=err - assert abs(t(234.6)-234.6)<=err - assert abs(t(234l)-234.0)<=err - if sys.version[:3]<'2.3': - assert abs(t(234.6+3j)-234.6)<=err - assert abs(t('234')-234)<=err - assert abs(t('234.6')-234.6)<=err - assert abs(t(-234)+234)<=err - assert abs(t([234])-234)<=err - assert abs(t((234,))-234.)<=err - assert abs(t(array(234))-234.)<=err - assert abs(t(array([234]))-234.)<=err - assert abs(t(array([[234]]))-234.)<=err - assert abs(t(array([234],'b'))+22)<=err - assert abs(t(array([234],'h'))-234.)<=err - assert abs(t(array([234],'i'))-234.)<=err - assert abs(t(array([234],'l'))-234.)<=err - assert abs(t(array([234],'B'))-234.)<=err - assert abs(t(array([234],'f'))-234.)<=err - assert abs(t(array([234],'d'))-234.)<=err - if sys.version[:3]<'2.3': - assert abs(t(array([234+3j],'F'))-234.)<=err - assert abs(t(array([234],'D'))-234.)<=err - if t.__doc__.split()[0] in ['t0','t4','s0','s4']: - assert t(1e200)==t(1e300) # inf - - try: raise RuntimeError,`t(array([234],'c'))` - except ValueError: pass - try: raise RuntimeError,`t('abc')` - except ValueError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - try: - try: raise RuntimeError,`t(10l**400)` - except OverflowError: pass - except RuntimeError: - r = t(10l**400); assert `r` in ['inf','Infinity'],`r` - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f90/return_character.py b/numpy/f2py/tests/f90/return_character.py deleted file mode 100644 index 45174630a..000000000 --- a/numpy/f2py/tests/f90/return_character.py +++ /dev/null @@ -1,99 +0,0 @@ - -__usage__ = """ -Run: - python return_character.py [<f2py options>] -Examples: - python return_character.py --fcompiler=Gnu --no-wrap-functions - python return_character.py --quiet -""" - -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f90_ext_return_character - except ImportError: - assert not f2py2e.compile('''\ -module f90_return_char - contains - function t0(value) - character :: value - character :: t0 - t0 = value - end function t0 - function t1(value) - character(len=1) :: value - character(len=1) :: t1 - t1 = value - end function t1 - function t5(value) - character(len=5) :: value - character(len=5) :: t5 - t5 = value - end function t5 - function ts(value) - character(len=*) :: value - character(len=10) :: ts - ts = value - end function ts - - subroutine s0(t0,value) - character :: value - character :: t0 -!f2py intent(out) t0 - t0 = value - end subroutine s0 - subroutine s1(t1,value) - character(len=1) :: value - character(len=1) :: t1 -!f2py intent(out) t1 - t1 = value - end subroutine s1 - subroutine s5(t5,value) - character(len=5) :: value - character(len=5) :: t5 -!f2py intent(out) t5 - t5 = value - end subroutine s5 - subroutine ss(ts,value) - character(len=*) :: value - character(len=10) :: ts -!f2py intent(out) ts - ts = value - end subroutine ss -end module f90_return_char -''','f90_ext_return_character',f2py_opts,source_fn='f90_ret_char.f90') - - from f90_ext_return_character import f90_return_char as m - test_functions = [m.t0,m.t1,m.t5,m.ts,m.s0,m.s1,m.s5,m.ss] - return test_functions - - -def runtest(t): - tname = t.__doc__.split()[0] - if tname in ['t0','t1','s0','s1']: - assert t(23)=='2' - r = t('ab');assert r=='a',`r` - r = t(array('ab'));assert r=='a',`r` - r = t(array(77,'1'));assert r=='M',`r` - try: raise RuntimeError,`t(array([77,87]))` - except ValueError: pass - try: raise RuntimeError,`t(array(77))` - except ValueError: pass - elif tname in ['ts','ss']: - assert t(23)=='23 ',`t(23)` - assert t('123456789abcdef')=='123456789a',`t('123456789abcdef')` - elif tname in ['t5','s5']: - assert t(23)=='23 ' - assert t('ab')=='ab ' - assert t('123456789abcdef')=='12345' - else: - raise NotImplementedError - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f90/return_complex.py b/numpy/f2py/tests/f90/return_complex.py deleted file mode 100644 index 71179e1f2..000000000 --- a/numpy/f2py/tests/f90/return_complex.py +++ /dev/null @@ -1,127 +0,0 @@ -__usage__ = """ -Run: - python return_complex.py [<f2py options>] -Examples: - python return_complex.py --quiet -""" - - -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f90_ext_return_complex - except ImportError: - assert not f2py2e.compile('''\ -module f90_return_complex - contains - function t0(value) - complex :: value - complex :: t0 - t0 = value - end function t0 - function t8(value) - complex(kind=4) :: value - complex(kind=4) :: t8 - t8 = value - end function t8 - function t16(value) - complex(kind=8) :: value - complex(kind=8) :: t16 - t16 = value - end function t16 - function td(value) - double complex :: value - double complex :: td - td = value - end function td - - subroutine s0(t0,value) - complex :: value - complex :: t0 -!f2py intent(out) t0 - t0 = value - end subroutine s0 - subroutine s8(t8,value) - complex(kind=4) :: value - complex(kind=4) :: t8 -!f2py intent(out) t8 - t8 = value - end subroutine s8 - subroutine s16(t16,value) - complex(kind=8) :: value - complex(kind=8) :: t16 -!f2py intent(out) t16 - t16 = value - end subroutine s16 - subroutine sd(td,value) - double complex :: value - double complex :: td -!f2py intent(out) td - td = value - end subroutine sd -end module f90_return_complex -''','f90_ext_return_complex',f2py_opts,source_fn='f90_ret_cmlx.f90') - - from f90_ext_return_complex import f90_return_complex as m - test_functions = [m.t0,m.t8,m.t16,m.td,m.s0,m.s8,m.s16,m.sd] - return test_functions - - -def runtest(t): - tname = t.__doc__.split()[0] - if tname in ['t0','t8','s0','s8']: - err = 1e-5 - else: - err = 0.0 - #assert abs(t(234j)-234.0j)<=err - assert abs(t(234.6)-234.6)<=err - assert abs(t(234l)-234.0)<=err - assert abs(t(234.6+3j)-(234.6+3j))<=err - #assert abs(t('234')-234.)<=err - #assert abs(t('234.6')-234.6)<=err - assert abs(t(-234)+234.)<=err - assert abs(t([234])-234.)<=err - assert abs(t((234,))-234.)<=err - assert abs(t(array(234))-234.)<=err - assert abs(t(array(23+4j,'F'))-(23+4j))<=err - assert abs(t(array([234]))-234.)<=err - assert abs(t(array([[234]]))-234.)<=err - assert abs(t(array([234],'1'))+22.)<=err - assert abs(t(array([234],'s'))-234.)<=err - assert abs(t(array([234],'i'))-234.)<=err - assert abs(t(array([234],'l'))-234.)<=err - assert abs(t(array([234],'b'))-234.)<=err - assert abs(t(array([234],'f'))-234.)<=err - assert abs(t(array([234],'d'))-234.)<=err - assert abs(t(array([234+3j],'F'))-(234+3j))<=err - assert abs(t(array([234],'D'))-234.)<=err - - try: raise RuntimeError,`t(array([234],'c'))` - except TypeError: pass - try: raise RuntimeError,`t('abc')` - except TypeError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - try: - try: raise RuntimeError,`t(10l**400)` - except OverflowError: pass - except RuntimeError: - r = t(10l**400); assert `r` in ['(inf+0j)','(Infinity+0j)'],`r` - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f90/return_integer.py b/numpy/f2py/tests/f90/return_integer.py deleted file mode 100644 index 3e96dfd5f..000000000 --- a/numpy/f2py/tests/f90/return_integer.py +++ /dev/null @@ -1,152 +0,0 @@ - -# XXX: investigate cases that are disabled under win32 -# - -__usage__ = """ -Run: - python return_integer.py [<f2py options>] -Examples: - python return_integer.py --quiet -""" - -import sys -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f90_ext_return_integer - except ImportError: - assert not f2py2e.compile('''\ -module f90_return_integer - contains - function t0(value) - integer :: value - integer :: t0 - t0 = value - end function t0 - function t1(value) - integer(kind=1) :: value - integer(kind=1) :: t1 - t1 = value - end function t1 - function t2(value) - integer(kind=2) :: value - integer(kind=2) :: t2 - t2 = value - end function t2 - function t4(value) - integer(kind=4) :: value - integer(kind=4) :: t4 - t4 = value - end function t4 - function t8(value) - integer(kind=8) :: value - integer(kind=8) :: t8 - t8 = value - end function t8 - - subroutine s0(t0,value) - integer :: value - integer :: t0 -!f2py intent(out) t0 - t0 = value - end subroutine s0 - subroutine s1(t1,value) - integer(kind=1) :: value - integer(kind=1) :: t1 -!f2py intent(out) t1 - t1 = value - end subroutine s1 - subroutine s2(t2,value) - integer(kind=2) :: value - integer(kind=2) :: t2 -!f2py intent(out) t2 - t2 = value - end subroutine s2 - subroutine s4(t4,value) - integer(kind=4) :: value - integer(kind=4) :: t4 -!f2py intent(out) t4 - t4 = value - end subroutine s4 - subroutine s8(t8,value) - integer(kind=8) :: value - integer(kind=8) :: t8 -!f2py intent(out) t8 - t8 = value - end subroutine s8 -end module f90_return_integer -''','f90_ext_return_integer',f2py_opts,source_fn='f90_ret_int.f90') - - from f90_ext_return_integer import f90_return_integer as m - test_functions = [m.t0,m.t1,m.t2,m.t4,m.t8,m.s0,m.s1,m.s2,m.s4,m.s8] - return test_functions - -def runtest(t): - tname = t.__doc__.split()[0] - assert t(123)==123 - assert t(123.6)==123 - assert t(123l)==123 - if sys.version[:3]<='2.2': - assert t(123.6+3j)==123 - assert t('123')==123 - assert t(-123)==-123 - assert t([123])==123 - assert t((123,))==123 - assert t(array(123))==123 - assert t(array([123]))==123 - assert t(array([[123]]))==123 - assert t(array([123],'1'))==123 - assert t(array([123],'s'))==123 - assert t(array([123],'i'))==123 - assert t(array([123],'l'))==123 - assert t(array([123],'b'))==123 - assert t(array([123],'f'))==123 - assert t(array([123],'d'))==123 - if sys.version[:3]<='2.2': - assert t(array([123+3j],'F'))==123 - assert t(array([123],'D'))==123 - - try: raise RuntimeError,`t(array([123],'c'))` - except ValueError: pass - try: raise RuntimeError,`t('abc')` - except ValueError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - if tname in ['t8','s8']: - try: raise RuntimeError,`t(100000000000000000000000l)` - except OverflowError: pass - try: raise RuntimeError,`t(10000000011111111111111.23)` - except OverflowError: pass - else: - if sys.version[:3]<='2.2': - try: raise RuntimeError,`t(10000000000000l)` - except OverflowError: pass - try: raise RuntimeError,`t(10000000000.23)` - except OverflowError: pass - -if __name__=='__main__': - #import libwadpy - status = 1 - try: - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' - status = 0 - finally: - if status: - print '*'*20 - print 'Running f2py2e.diagnose' - import f2py2e.diagnose - f2py2e.diagnose.run() diff --git a/numpy/f2py/tests/f90/return_logical.py b/numpy/f2py/tests/f90/return_logical.py deleted file mode 100644 index c9479edaf..000000000 --- a/numpy/f2py/tests/f90/return_logical.py +++ /dev/null @@ -1,138 +0,0 @@ - -__usage__ = """ -Run: - python return_logical.py [<f2py options>] -Examples: - python return_logical.py --quiet -""" - -import f2py2e -from Numeric import array - -try: True -except NameError: - True = 1 - False = 0 - -def build(f2py_opts): - try: - import f90_ext_return_logical - except ImportError: - assert not f2py2e.compile('''\ -module f90_return_logical - contains - function t0(value) - logical :: value - logical :: t0 - t0 = value - end function t0 - function t1(value) - logical(kind=1) :: value - logical(kind=1) :: t1 - t1 = value - end function t1 - function t2(value) - logical(kind=2) :: value - logical(kind=2) :: t2 - t2 = value - end function t2 - function t4(value) - logical(kind=4) :: value - logical(kind=4) :: t4 - t4 = value - end function t4 - function t8(value) - logical(kind=8) :: value - logical(kind=8) :: t8 - t8 = value - end function t8 - - subroutine s0(t0,value) - logical :: value - logical :: t0 -!f2py intent(out) t0 - t0 = value - end subroutine s0 - subroutine s1(t1,value) - logical(kind=1) :: value - logical(kind=1) :: t1 -!f2py intent(out) t1 - t1 = value - end subroutine s1 - subroutine s2(t2,value) - logical(kind=2) :: value - logical(kind=2) :: t2 -!f2py intent(out) t2 - t2 = value - end subroutine s2 - subroutine s4(t4,value) - logical(kind=4) :: value - logical(kind=4) :: t4 -!f2py intent(out) t4 - t4 = value - end subroutine s4 - subroutine s8(t8,value) - logical(kind=8) :: value - logical(kind=8) :: t8 -!f2py intent(out) t8 - t8 = value - end subroutine s8 -end module f90_return_logical -''','f90_ext_return_logical',f2py_opts,source_fn='f90_ret_log.f90') - - from f90_ext_return_logical import f90_return_logical as m - test_functions = [m.t0,m.t1,m.t2,m.t4,m.t8,m.s0,m.s1,m.s2,m.s4,m.s8] - return test_functions - - - - -def runtest(t): - assert t(True)==1,`t(True)` - assert t(False)==0,`t(False)` - assert t(0)==0 - assert t(None)==0 - assert t(0.0)==0 - assert t(0j)==0 - assert t(1j)==1 - assert t(234)==1 - assert t(234.6)==1 - assert t(234l)==1 - assert t(234.6+3j)==1 - assert t('234')==1 - assert t('aaa')==1 - assert t('')==0 - assert t([])==0 - assert t(())==0 - assert t({})==0 - assert t(t)==1 - assert t(-234)==1 - assert t(10l**100)==1 - assert t([234])==1 - assert t((234,))==1 - assert t(array(234))==1 - assert t(array([234]))==1 - assert t(array([[234]]))==1 - assert t(array([234],'1'))==1 - assert t(array([234],'s'))==1 - assert t(array([234],'i'))==1 - assert t(array([234],'l'))==1 - assert t(array([234],'b'))==1 - assert t(array([234],'f'))==1 - assert t(array([234],'d'))==1 - assert t(array([234+3j],'F'))==1 - assert t(array([234],'D'))==1 - assert t(array(0))==0 - assert t(array([0]))==0 - assert t(array([[0]]))==0 - assert t(array([0j]))==0 - assert t(array([1]))==1 - assert t(array([0,0]))==0 - assert t(array([0,1]))==1 #XXX: is this expected? - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/f90/return_real.py b/numpy/f2py/tests/f90/return_real.py deleted file mode 100644 index 42d40cb95..000000000 --- a/numpy/f2py/tests/f90/return_real.py +++ /dev/null @@ -1,129 +0,0 @@ -__usage__ = """ -Run: - python return_real.py [<f2py options>] -Examples: - python return_real.py --quiet -""" - -import sys -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import f90_ext_return_real - except ImportError: - assert not f2py2e.compile('''\ -module f90_return_real - contains - function t0(value) - real :: value - real :: t0 - t0 = value - end function t0 - function t4(value) - real(kind=4) :: value - real(kind=4) :: t4 - t4 = value - end function t4 - function t8(value) - real(kind=8) :: value - real(kind=8) :: t8 - t8 = value - end function t8 - function td(value) - double precision :: value - double precision :: td - td = value - end function td - - subroutine s0(t0,value) - real :: value - real :: t0 -!f2py intent(out) t0 - t0 = value - end subroutine s0 - subroutine s4(t4,value) - real(kind=4) :: value - real(kind=4) :: t4 -!f2py intent(out) t4 - t4 = value - end subroutine s4 - subroutine s8(t8,value) - real(kind=8) :: value - real(kind=8) :: t8 -!f2py intent(out) t8 - t8 = value - end subroutine s8 - subroutine sd(td,value) - double precision :: value - double precision :: td -!f2py intent(out) td - td = value - end subroutine sd -end module f90_return_real -''','f90_ext_return_real',f2py_opts,source_fn='f90_ret_real.f90') - - from f90_ext_return_real import f90_return_real as m - test_functions = [m.t0,m.t4,m.t8,m.td,m.s0,m.s4,m.s8,m.sd] - return test_functions - -def runtest(t): - tname = t.__doc__.split()[0] - if tname in ['t0','t4','s0','s4']: - err = 1e-5 - else: - err = 0.0 - assert abs(t(234)-234.0)<=err - assert abs(t(234.6)-234.6)<=err - assert abs(t(234l)-234.0)<=err - if sys.version[:3]<='2.2': - assert abs(t(234.6+3j)-234.6)<=err,`t(234.6+3j)` - assert abs(t('234')-234)<=err - assert abs(t('234.6')-234.6)<=err - assert abs(t(-234)+234)<=err - assert abs(t([234])-234)<=err - assert abs(t((234,))-234.)<=err - assert abs(t(array(234))-234.)<=err - assert abs(t(array([234]))-234.)<=err - assert abs(t(array([[234]]))-234.)<=err - assert abs(t(array([234],'1'))+22)<=err - assert abs(t(array([234],'s'))-234.)<=err - assert abs(t(array([234],'i'))-234.)<=err - assert abs(t(array([234],'l'))-234.)<=err - assert abs(t(array([234],'b'))-234.)<=err - assert abs(t(array([234],'f'))-234.)<=err - assert abs(t(array([234],'d'))-234.)<=err - if sys.version[:3]<='2.2': - assert abs(t(array([234+3j],'F'))-234.)<=err,`t(array([234+3j],'F'))` - assert abs(t(array([234],'D'))-234.)<=err,`t(array([234],'D'))` - if tname in ['t0','t4','s0','s4']: - assert t(1e200)==t(1e300) # inf - - try: raise RuntimeError,`t(array([234],'c'))` - except ValueError: pass - try: raise RuntimeError,`t('abc')` - except ValueError: pass - - try: raise RuntimeError,`t([])` - except IndexError: pass - try: raise RuntimeError,`t(())` - except IndexError: pass - - try: raise RuntimeError,`t(t)` - except TypeError: pass - try: raise RuntimeError,`t({})` - except TypeError: pass - - try: - try: raise RuntimeError,`t(10l**400)` - except OverflowError: pass - except RuntimeError: - r = t(10l**400); assert `r` in ['inf','Infinity'],`r` - -if __name__=='__main__': - #import libwadpy - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/mixed/foo.f b/numpy/f2py/tests/mixed/foo.f deleted file mode 100644 index c34742578..000000000 --- a/numpy/f2py/tests/mixed/foo.f +++ /dev/null @@ -1,5 +0,0 @@ - subroutine bar11(a) -cf2py intent(out) a - integer a - a = 11 - end diff --git a/numpy/f2py/tests/mixed/foo_fixed.f90 b/numpy/f2py/tests/mixed/foo_fixed.f90 deleted file mode 100644 index 7543a6acb..000000000 --- a/numpy/f2py/tests/mixed/foo_fixed.f90 +++ /dev/null @@ -1,8 +0,0 @@ - module foo_fixed - contains - subroutine bar12(a) -!f2py intent(out) a - integer a - a = 12 - end subroutine bar12 - end module foo_fixed diff --git a/numpy/f2py/tests/mixed/foo_free.f90 b/numpy/f2py/tests/mixed/foo_free.f90 deleted file mode 100644 index c1b641f13..000000000 --- a/numpy/f2py/tests/mixed/foo_free.f90 +++ /dev/null @@ -1,8 +0,0 @@ -module foo_free -contains - subroutine bar13(a) - !f2py intent(out) a - integer a - a = 13 - end subroutine bar13 -end module foo_free diff --git a/numpy/f2py/tests/mixed/run.py b/numpy/f2py/tests/mixed/run.py deleted file mode 100644 index 6f4b7d444..000000000 --- a/numpy/f2py/tests/mixed/run.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -__usage__ = """ -Run: - python run.py [<f2py options>] -Examples: - python run.py --quiet -""" - -import os -import sys -import string -import f2py2e -from Numeric import array - -def build(f2py_opts): - try: - import mixed_f77_f90 - except: - d,b=os.path.split(sys.argv[0]) - files = ['foo.f','foo_fixed.f90','foo_free.f90'] - files = [os.path.join(d,f) for f in files] - files = string.join(files) - args = ' -c -m mixed_f77_f90 %s %s'%(files,f2py_opts) - c = '%s -c "import f2py2e;f2py2e.main()" %s' %(sys.executable,args) - s = os.system(c) - assert not s - from mixed_f77_f90 import bar11 - test_functions = [bar11] - from mixed_f77_f90 import foo_fixed as m - test_functions.append(m.bar12) - from mixed_f77_f90 import foo_free as m - test_functions.append(m.bar13) - return test_functions - -def runtest(t): - tname = t.__doc__.split()[0] - if tname=='bar11': - assert t()==11 - elif tname=='bar12': - assert t()==12 - elif tname=='bar13': - assert t()==13 - else: - raise NotImplementedError - -if __name__=='__main__': - repeat,f2py_opts = f2py2e.f2py_testing.cmdline() - test_functions = build(f2py_opts) - f2py2e.f2py_testing.run(runtest,test_functions,repeat) - print 'ok' diff --git a/numpy/f2py/tests/run_all.py b/numpy/f2py/tests/run_all.py deleted file mode 100755 index 016e68c29..000000000 --- a/numpy/f2py/tests/run_all.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python - -import os,sys - -opts = sys.argv[1:] -if not opts: - opts = ['10','--quiet'] - -NUMARRAY = "-DNUMARRAY" in sys.argv - -test_f77_files = [\ - 'f77/return_integer.py', - 'f77/return_logical.py', - 'f77/return_real.py', - 'f77/return_complex.py', - 'f77/callback.py', - ] - -if not NUMARRAY: # no support for character yet in numarray - test_f77_files.append('f77/return_character.py') - -test_f90_files = [\ - 'f90/return_integer.py', - 'f90/return_logical.py', - 'f90/return_real.py', - 'f90/return_complex.py', - 'f90/return_character.py', - 'mixed/run.py', - ] - -test_files = test_f77_files - -if NUMARRAY: - print >>sys.stderr,"NOTE: f2py for numarray does not support"\ - " f90 or character arrays." -else: - test_files += test_f90_files - -py_path = os.environ.get('PYTHONPATH') -if py_path is None: - py_path = '.' -else: - py_path = os.pathsep.join(['.',py_path]) -os.environ['PYTHONPATH'] = py_path - -for f in test_files: - print "**********************************************" - ff = os.path.join(sys.path[0],f) - args = [sys.executable,ff]+opts - print "Running",' '.join(args) - status = os.spawnve(os.P_WAIT,sys.executable,args,os.environ) - if status: - print 'TEST FAILURE (status=%s)' % (status) - if f=='f90/return_integer.py': - sys.exit() diff --git a/numpy/f2py/use_rules.py b/numpy/f2py/use_rules.py deleted file mode 100644 index 43c223a7d..000000000 --- a/numpy/f2py/use_rules.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -""" - -Build 'use others module data' mechanism for f2py2e. - -Unfinished. - -Copyright 2000 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@ioc.ee> -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -$Date: 2000/09/10 12:35:43 $ -Pearu Peterson -""" - -__version__ = "$Revision: 1.3 $"[10:-1] - -f2py_version='See `f2py -v`' - -import pprint -import sys,string,time,types,copy -errmess=sys.stderr.write -outmess=sys.stdout.write -show=pprint.pprint - -from auxfuncs import * -import capi_maps -import cfuncs -############## - -usemodule_rules={ - 'body':""" -#begintitle# -static char doc_#apiname#[] = \"\\\nVariable wrapper signature:\\n\\ -\t #name# = get_#name#()\\n\\ -Arguments:\\n\\ -#docstr#\"; -extern F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#); -static PyObject *#apiname#(PyObject *capi_self, PyObject *capi_args) { -/*#decl#*/ -\tif (!PyArg_ParseTuple(capi_args, \"\")) goto capi_fail; -printf(\"c: %d\\n\",F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#)); -\treturn Py_BuildValue(\"\"); -capi_fail: -\treturn NULL; -} -""", - 'method':'\t{\"get_#name#\",#apiname#,METH_VARARGS|METH_KEYWORDS,doc_#apiname#},', - 'need':['F_MODFUNC'] - } - -################ - -def buildusevars(m,r): - ret={} - outmess('\t\tBuilding use variable hooks for module "%s" (feature only for F90/F95)...\n'%(m['name'])) - varsmap={} - revmap={} - if r.has_key('map'): - for k in r['map'].keys(): - if revmap.has_key(r['map'][k]): - outmess('\t\t\tVariable "%s<=%s" is already mapped by "%s". Skipping.\n'%(r['map'][k],k,revmap[r['map'][k]])) - else: - revmap[r['map'][k]]=k - if r.has_key('only') and r['only']: - for v in r['map'].keys(): - if m['vars'].has_key(r['map'][v]): - - if revmap[r['map'][v]]==v: - varsmap[v]=r['map'][v] - else: - outmess('\t\t\tIgnoring map "%s=>%s". See above.\n'%(v,r['map'][v])) - else: - outmess('\t\t\tNo definition for variable "%s=>%s". Skipping.\n'%(v,r['map'][v])) - else: - for v in m['vars'].keys(): - if revmap.has_key(v): - varsmap[v]=revmap[v] - else: - varsmap[v]=v - for v in varsmap.keys(): - ret=dictappend(ret,buildusevar(v,varsmap[v],m['vars'],m['name'])) - return ret -def buildusevar(name,realname,vars,usemodulename): - outmess('\t\t\tConstructing wrapper function for variable "%s=>%s"...\n'%(name,realname)) - ret={} - vrd={'name':name, - 'realname':realname, - 'REALNAME':string.upper(realname), - 'usemodulename':usemodulename, - 'USEMODULENAME':string.upper(usemodulename), - 'texname':string.replace(name,'_','\\_'), - 'begintitle':gentitle('%s=>%s'%(name,realname)), - 'endtitle':gentitle('end of %s=>%s'%(name,realname)), - 'apiname':'#modulename#_use_%s_from_%s'%(realname,usemodulename) - } - nummap={0:'Ro',1:'Ri',2:'Rii',3:'Riii',4:'Riv',5:'Rv',6:'Rvi',7:'Rvii',8:'Rviii',9:'Rix'} - vrd['texnamename']=name - for i in nummap.keys(): - vrd['texnamename']=string.replace(vrd['texnamename'],`i`,nummap[i]) - if hasnote(vars[realname]): vrd['note']=vars[realname]['note'] - rd=dictappend({},vrd) - var=vars[realname] - - print name,realname,vars[realname] - ret=applyrules(usemodule_rules,rd) - return ret |