module documentation

crackfortran --- read fortran (77,90) code and extract declaration information.

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

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) 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' | 'abstract interface'

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.

B['saved_interface'] --- a string of scanned routine signature, defines explicit interface

*** 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|aligned4|aligned8|aligned16)', 'optional','required', etc)
K = D['kindselector'] = {['*','kind']} (only if D['typespec'] =
'complex' | 'integer' | 'logical' | 'real' )
C = D['charselector'] = {['*','len','kind','f2py_len']}
(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'], f2py_len=C['f2py_len']) (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.

Function analyzeargs Undocumented
Function analyzebody Undocumented
Function analyzecommon Undocumented
Function analyzeline Undocumented
Function analyzevars Undocumented
Function appenddecl Undocumented
Function appendmultiline Undocumented
Function buildimplicitrules Undocumented
Function character_backward_compatibility_hook Previously, Fortran character was incorrectly treated as character*1. This hook fixes the usage of the corresponding variables in check, dimension, =, and callstatement expressions.
Function common2fortran Undocumented
Function crack2fortran Undocumented
Function crack2fortrangen Undocumented
Function crackfortran Undocumented
Function crackline reset=-1 --- initialize reset=0 --- crack the line reset=1 --- final check if mismatch of blocks occurred
Function cracktypespec Undocumented
Function cracktypespec0 Undocumented
Function determineexprtype Undocumented
Function expr2name Undocumented
Function get_parameters Undocumented
Function get_sorted_names No summary
Function get_usedict Undocumented
Function get_useparameters Undocumented
Function getblockname Undocumented
Function getextension Undocumented
Function getlincoef Obtain a and b when e == "a*x+b", where x is a symbol in xset.
Function is_free_format Check if file is in free format Fortran.
Function markinnerspaces The function replace all spaces in the input variable line which are surrounded with quotation marks, with the triplet "@_@".
Function markoutercomma Undocumented
Function markouterparen Undocumented
Function myeval Like eval but returns only integers and floats
Function openhook Ensures that filename is opened with correct encoding parameter.
Function outmess Undocumented
Function postcrack function return values determine expression types if in argument list
Function postcrack2 Undocumented
Function readfortrancode Get rid of comments, line continuations, and empty lines; lower cases.
Function removespaces Undocumented
Function reset_global_f2py_vars Undocumented
Function rmbadname Undocumented
Function rmbadname1 Undocumented
Function setattrspec Undocumented
Function setcharselector Undocumented
Function setkindselector Undocumented
Function setmesstext Undocumented
Function sortvarnames Undocumented
Function split_by_unquoted Splits the line into (line[:i], line[i:]), where i is the index of first occurrence of one of the characters not within quotes, or len(line) if no such index exists
Function traverse Traverse f2py data structure with the following visit function:
Function true_intent_list Undocumented
Function undo_rmbadname Undocumented
Function undo_rmbadname1 Undocumented
Function unmarkouterparen Undocumented
Function updatevars Undocumented
Function use2fortran Undocumented
Function vars2fortran TODO: public sub ...
Variable analyzeargs_re_1 Undocumented
Variable badnames Undocumented
Variable beforethisafter Undocumented
Variable beginpattern Undocumented
Variable beginpattern77 Undocumented
Variable beginpattern90 Undocumented
Variable callfunpattern Undocumented
Variable callnameargspattern Undocumented
Variable callpattern Undocumented
Variable charselector Undocumented
Variable commonpattern Undocumented
Variable containspattern Undocumented
Variable crackline_re_1 Undocumented
Variable currentfilename Undocumented
Variable datapattern Undocumented
Variable debug Undocumented
Variable defaultimplicitrules Undocumented
Variable determineexprtype_re_1 Undocumented
Variable determineexprtype_re_2 Undocumented
Variable determineexprtype_re_3 Undocumented
Variable determineexprtype_re_4 Undocumented
Variable determineexprtype_re_5 Undocumented
Variable dimensionpattern Undocumented
Variable dolowercase Undocumented
Variable endifpattern Undocumented
Variable endifs Undocumented
Variable endpattern Undocumented
Variable entrypattern Undocumented
Variable expectbegin Undocumented
Variable externalpattern Undocumented
Variable f2pyenhancementspattern Undocumented
Variable f77modulename Undocumented
Variable f90modulevars Undocumented
Variable filepositiontext Undocumented
Variable formatpattern Undocumented
Variable fortrantypes Undocumented
Variable functionpattern Undocumented
Variable getlincoef_re_1 Undocumented
Variable gotnextfile Undocumented
Variable groupbegins77 Undocumented
Variable groupbegins90 Undocumented
Variable groupcache Undocumented
Variable groupcounter Undocumented
Variable groupends Undocumented
Variable grouplist Undocumented
Variable groupname Undocumented
Variable ignorecontains Undocumented
Variable implicitpattern Undocumented
Variable include_paths Undocumented
Variable intentpattern Undocumented
Variable intrinsicpattern Undocumented
Variable invbadnames Undocumented
Variable is_f_file Undocumented
Variable kindselector Undocumented
Variable lenarraypattern Undocumented
Variable lenkindpattern Undocumented
Variable moduleprocedurepattern Undocumented
Variable moduleprocedures Undocumented
Variable multilinepattern Undocumented
Variable nameargspattern Undocumented
Variable namepattern Undocumented
Variable neededmodule Undocumented
Variable onlyfuncs Undocumented
Variable operatorpattern Undocumented
Variable optionalpattern Undocumented
Variable parameterpattern Undocumented
Variable post_processing_hooks Undocumented
Variable previous_context Undocumented
Variable privatepattern Undocumented
Variable publicpattern Undocumented
Variable pyffilename Undocumented
Variable quiet Undocumented
Variable real16pattern Undocumented
Variable real8pattern Undocumented
Variable requiredpattern Undocumented
Variable selectpattern Undocumented
Variable skipblocksuntil Undocumented
Variable skipemptyends Undocumented
Variable skipfuncs Undocumented
Variable skipfunctions Undocumented
Variable sourcecodeform Undocumented
Variable strictf77 Undocumented
Variable subroutinepattern Undocumented
Variable tabchar Undocumented
Variable typedefpattern Undocumented
Variable typespattern Undocumented
Variable typespattern4implicit Undocumented
Variable usepattern Undocumented
Variable usermodules Undocumented
Variable verbose Undocumented
Variable word_pattern Undocumented
Function _calc_depend_dict Undocumented
Function _ensure_exprdict Undocumented
Function _eval_length Undocumented
Function _eval_scalar Undocumented
Function _get_depend_dict Undocumented
Function _is_intent_callback Undocumented
Function _is_visit_pair Undocumented
Function _kind_func Undocumented
Function _resolvenameargspattern Undocumented
Function _resolvetypedefpattern Undocumented
Function _selected_int_kind_func Undocumented
Function _selected_real_kind_func Undocumented
Function _simplifyargs Undocumented
Variable _free_f90_start Undocumented
Variable _has_f90_header Undocumented
Variable _has_f_header Undocumented
Variable _has_fix_header Undocumented
Variable _intentcallbackpattern Undocumented
Variable _is_kind_number Undocumented
def analyzeargs(block): (source)

Undocumented

def analyzebody(block, args, tab=''): (source)

Undocumented

def analyzecommon(block): (source)

Undocumented

def analyzeline(m, case, line): (source)

Undocumented

def analyzevars(block): (source)

Undocumented

def appenddecl(decl, decl2, force=1): (source)

Undocumented

def appendmultiline(group, context_name, ml): (source)

Undocumented

def buildimplicitrules(block): (source)

Undocumented

def character_backward_compatibility_hook(item, parents, result, *args, **kwargs): (source)

Previously, Fortran character was incorrectly treated as character*1. This hook fixes the usage of the corresponding variables in check, dimension, =, and callstatement expressions.

The usage of char* in callprotoargument expression can be left unchanged because C character is C typedef of char, although, new implementations should use character* in the corresponding expressions.

See https://github.com/numpy/numpy/pull/19388 for more information.

def common2fortran(common, tab=''): (source)

Undocumented

def crack2fortran(block): (source)

Undocumented

def crack2fortrangen(block, tab='\n', as_interface=False): (source)

Undocumented

def crackfortran(files): (source)

Undocumented

def crackline(line, reset=0): (source)

reset=-1 --- initialize reset=0 --- crack the line reset=1 --- final check if mismatch of blocks occurred

Cracked data is saved in grouplist[0].

def cracktypespec(typespec, selector): (source)

Undocumented

def cracktypespec0(typespec, ll): (source)

Undocumented

def determineexprtype(expr, vars, rules={}): (source)

Undocumented

def expr2name(a, block, args=[]): (source)

Undocumented

def get_parameters(vars, global_params={}): (source)

Undocumented

def get_sorted_names(vars): (source)
def get_usedict(block): (source)

Undocumented

def get_useparameters(block, param_map=None): (source)

Undocumented

def getblockname(block, unknown='unknown'): (source)

Undocumented

def getextension(name): (source)

Undocumented

def getlincoef(e, xset): (source)

Obtain a and b when e == "a*x+b", where x is a symbol in xset.

>>> getlincoef('2*x + 1', {'x'})
(2, 1, 'x')
>>> getlincoef('3*x + x*2 + 2 + 1', {'x'})
(5, 3, 'x')
>>> getlincoef('0', {'x'})
(0, 0, None)
>>> getlincoef('0*x', {'x'})
(0, 0, 'x')
>>> getlincoef('x*x', {'x'})
(None, None, None)

This can be tricked by sufficiently complex expressions

>>> getlincoef('(x - 0.5)*(x - 1.5)*(x - 1)*x + 2*x + 3', {'x'})
(2.0, 3.0, 'x')
def is_free_format(file): (source)

Check if file is in free format Fortran.

def markinnerspaces(line): (source)

The function replace all spaces in the input variable line which are surrounded with quotation marks, with the triplet "@_@".

For instance, for the input "a 'b c'" the function returns "a 'b@_@c'"

Parameters
line:str
Returns
strUndocumented
def markoutercomma(line, comma=','): (source)

Undocumented

def markouterparen(line): (source)

Undocumented

def myeval(e, g=None, l=None): (source)

Like eval but returns only integers and floats

def openhook(filename, mode): (source)

Ensures that filename is opened with correct encoding parameter.

This function uses charset_normalizer package, when available, for determining the encoding of the file to be opened. When charset_normalizer is not available, the function detects only UTF encodings, otherwise, ASCII encoding is used as fallback.

def outmess(line, flag=1): (source)

Undocumented

def postcrack(block, args=None, tab=''): (source)

TODO:
function return values determine expression types if in argument list

def postcrack2(block, tab='', param_map=None): (source)

Undocumented

def readfortrancode(ffile, dowithline=show, istop=1): (source)

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.

def removespaces(expr): (source)

Undocumented

def reset_global_f2py_vars(): (source)

Undocumented

def rmbadname(names): (source)

Undocumented

def rmbadname1(name): (source)

Undocumented

def setattrspec(decl, attr, force=0): (source)

Undocumented

def setcharselector(decl, sel, force=0): (source)

Undocumented

def setkindselector(decl, sel, force=0): (source)

Undocumented

def setmesstext(block): (source)

Undocumented

def sortvarnames(vars): (source)

Undocumented

def split_by_unquoted(line, characters): (source)

Splits the line into (line[:i], line[i:]), where i is the index of first occurrence of one of the characters not within quotes, or len(line) if no such index exists

def traverse(obj, visit, parents=[], result=None, *args, **kwargs): (source)

Traverse f2py data structure with the following visit function:

def visit(item, parents, result, *args, **kwargs):

"""

parents is a list of key-"f2py data structure" pairs from which items are taken from.

result is a f2py data structure that is filled with the return value of the visit function.

item is 2-tuple (index, value) if parents[-1][1] is a list item is 2-tuple (key, value) if parents[-1][1] is a dict

The return value of visit must be None, or of the same kind as item, that is, if parents[-1] is a list, the return value must be 2-tuple (new_index, new_value), or if parents[-1] is a dict, the return value must be 2-tuple (new_key, new_value).

If new_index or new_value is None, the return value of visit is ignored, that is, it will not be added to the result.

If the return value is None, the content of obj will be traversed, otherwise not. """

def true_intent_list(var): (source)

Undocumented

def undo_rmbadname(names): (source)

Undocumented

def undo_rmbadname1(name): (source)

Undocumented

def unmarkouterparen(line): (source)

Undocumented

def updatevars(typespec, selector, attrspec, entitydecl): (source)

Undocumented

def use2fortran(use, tab=''): (source)

Undocumented

def vars2fortran(block, vars, args, tab='', as_interface=False): (source)

TODO: public sub ...

analyzeargs_re_1 = (source)

Undocumented

badnames: dict = (source)

Undocumented

beforethisafter = (source)

Undocumented

beginpattern: str = (source)

Undocumented

beginpattern77 = (source)

Undocumented

beginpattern90 = (source)

Undocumented

callfunpattern = (source)

Undocumented

callnameargspattern = (source)

Undocumented

callpattern = (source)

Undocumented

charselector = (source)

Undocumented

commonpattern = (source)

Undocumented

containspattern = (source)

Undocumented

crackline_re_1 = (source)

Undocumented

currentfilename: str = (source)

Undocumented

datapattern = (source)

Undocumented

Undocumented

defaultimplicitrules: dict = (source)

Undocumented

determineexprtype_re_1 = (source)

Undocumented

determineexprtype_re_2 = (source)

Undocumented

determineexprtype_re_3 = (source)

Undocumented

determineexprtype_re_4 = (source)

Undocumented

determineexprtype_re_5 = (source)

Undocumented

dimensionpattern = (source)

Undocumented

dolowercase: int = (source)

Undocumented

endifpattern = (source)

Undocumented

Undocumented

endpattern = (source)

Undocumented

entrypattern = (source)

Undocumented

expectbegin: int = (source)

Undocumented

externalpattern = (source)

Undocumented

f2pyenhancementspattern = (source)

Undocumented

f77modulename: str = (source)

Undocumented

f90modulevars: dict = (source)

Undocumented

filepositiontext: str = (source)

Undocumented

formatpattern = (source)

Undocumented

fortrantypes: str = (source)

Undocumented

functionpattern = (source)

Undocumented

getlincoef_re_1 = (source)

Undocumented

gotnextfile: int = (source)

Undocumented

groupbegins77: str = (source)

Undocumented

groupbegins90 = (source)

Undocumented

groupcache = (source)

Undocumented

groupcounter: int = (source)

Undocumented

groupends: str = (source)

Undocumented

grouplist = (source)

Undocumented

groupname: str = (source)

Undocumented

ignorecontains: int = (source)

Undocumented

implicitpattern = (source)

Undocumented

include_paths: list = (source)

Undocumented

intentpattern = (source)

Undocumented

intrinsicpattern = (source)

Undocumented

invbadnames: dict = (source)

Undocumented

is_f_file = (source)

Undocumented

kindselector = (source)

Undocumented

lenarraypattern = (source)

Undocumented

lenkindpattern = (source)

Undocumented

moduleprocedurepattern = (source)

Undocumented

moduleprocedures: str = (source)

Undocumented

multilinepattern = (source)

Undocumented

nameargspattern = (source)

Undocumented

namepattern = (source)

Undocumented

neededmodule: int = (source)

Undocumented

onlyfuncs: list = (source)

Undocumented

operatorpattern = (source)

Undocumented

optionalpattern = (source)

Undocumented

parameterpattern = (source)

Undocumented

post_processing_hooks: list = (source)

Undocumented

previous_context = (source)

Undocumented

privatepattern = (source)

Undocumented

publicpattern = (source)

Undocumented

pyffilename: str = (source)

Undocumented

Undocumented

real16pattern = (source)

Undocumented

real8pattern = (source)

Undocumented

requiredpattern = (source)

Undocumented

selectpattern = (source)

Undocumented

skipblocksuntil: int = (source)

Undocumented

skipemptyends: int = (source)

Undocumented

skipfuncs: list = (source)

Undocumented

skipfunctions: list = (source)

Undocumented

sourcecodeform: str = (source)

Undocumented

strictf77: int = (source)

Undocumented

subroutinepattern = (source)

Undocumented

Undocumented

typedefpattern = (source)

Undocumented

typespattern = (source)

Undocumented

typespattern4implicit = (source)

Undocumented

usepattern = (source)

Undocumented

usermodules: list = (source)

Undocumented

Undocumented

word_pattern = (source)

Undocumented

def _calc_depend_dict(vars): (source)

Undocumented

def _ensure_exprdict(r): (source)

Undocumented

def _eval_length(length, params): (source)

Undocumented

def _eval_scalar(value, params): (source)

Undocumented

def _get_depend_dict(name, vars, deps): (source)

Undocumented

def _is_intent_callback(vdecl): (source)

Undocumented

def _is_visit_pair(obj): (source)

Undocumented

def _kind_func(string): (source)

Undocumented

def _resolvenameargspattern(line): (source)

Undocumented

def _resolvetypedefpattern(line): (source)

Undocumented

def _selected_int_kind_func(r): (source)

Undocumented

def _selected_real_kind_func(p, r=0, radix=0): (source)

Undocumented

def _simplifyargs(argsline): (source)

Undocumented

_free_f90_start = (source)

Undocumented

_has_f90_header = (source)

Undocumented

_has_f_header = (source)

Undocumented

_has_fix_header = (source)

Undocumented

_intentcallbackpattern = (source)

Undocumented

_is_kind_number = (source)

Undocumented