a ;jg7B @s dZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z z ddl Z Wne yrdZ Yn0ddl mZddlTddl mZejadadadadad ad ad adadadagad ad ada ia!d a"da#da$da%t%gia&d a'ga(d a)ga*da+d a,ga-ga.ga/d d Z0dddZ1de_2iZ3dD]Z4ddie3e4<q4dD]Z4ddie3e4<qLiZ5iZ6dD]Z7e7de5e7<e7e6e7d<qlddZ8ddZ9ddZ:ddZ;eZ?eZ@eZAeej=d?fZZe -m ,--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: f2py is read as 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'][]['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':,'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: {:{['only':<0|1>],['map':{:,...}]}} B['note'] --- list of LaTeX comments on the block B['f2pyenhancements'] --- optional dictionary {'threadsafe':'','fortranname':, 'callstatement':|, 'callprotoargument':, 'usercode':|, 'pymethoddef:' } 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'][] = {'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()', '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 = [[]::] = byte | character[] | complex[] | double complex | double precision | integer[] | logical[] | real[] | type() = * | ([len=][,[kind=]]) | (kind=[,len=]) = * | ([kind=]) = 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. = in | out | inout = comma separated list of dimension bounds. = [[*][()] | [()]*] [// | =] [,] 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. N)Path) __version__)*)symbolicfix cCspdadadadadadadadadada ga da t gia da dadagaiadadadagagagagadadS)Nrrrrr r ) strictf77sourcecodeformquietverbosetabchar pyffilename f77modulename skipemptyendsignorecontains dolowercasedebug groupcounter grouplist neededmodule expectbeginskipblocksuntil usermodules f90modulevars gotnextfilefilepositiontextcurrentfilename skipfunctions skipfuncs onlyfuncs include_pathsprevious_contextr%r%A/usr/local/lib/python3.9/site-packages/numpy/f2py/crackfortran.pyreset_global_f2py_varss4 r'cCs,tsdSts(|rtjttj|dSN)rr sysstdoutwriter)lineflagr%r%r&outmesss  r.2zabcdefghopqrstuvwxyz$_typespecrealZijklmninteger)3intdoublefloatcharshortlongvoidcasewhilereturnsignedZunsignedifforZtypedefZsizeofunionstructstaticregisternewbreakdoZgotoswitchcontinueelseinlineZexterndeleteconstautolenZrankshapeindexslensizeZ_imaxminZflenZfshapestringZcomplex_doubleZ float_doublestdinstderrr*typedefaultZ_bncCs(|tvr$td|t|ft|S|S)Nz&rmbadname1: Replacing "%s" with "%s". )badnameserrmessnamer%r%r& rmbadname1 s  r^cCsdd|DS)NcSsg|] }t|qSr%)r^.0_mr%r%r& zrmbadname..r%namesr%r%r& rmbadnamesrfcCs(|tvr$td|t|ft|S|S)Nz+undo_rmbadname1: Replacing "%s" with "%s". ) invbadnamesr[r\r%r%r&undo_rmbadname1s  rhcCsdd|DS)NcSsg|] }t|qSr%)rhr_r%r%r&rb rcz"undo_rmbadname..r%rdr%r%r&undo_rmbadnamesriz-\*-\s*fortran\s*-\*-z-\*-\s*f90\s*-\*-z-\*-\s*fix\s*-\*-z[^c*]\s*[^\s\d\t])z.f90z.f95z.f03z.f08)z.forz.ftnz.f77z.fcCstdurt|j}ntdtj|}t|d`}| |}| t j rTd}n4| t j t jfrld}n| t jt jfrd}nd}Wdn1s0Yt|||dS) aNEnsures 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. N rbz UTF-8-SIGzUTF-32zUTF-16ascii)encoding)charset_normalizer from_pathbestrmrTospathgetsizeopenread startswithcodecsBOM_UTF8 BOM_UTF32_LE BOM_UTF32_BEBOM_LEBOM_BE)filenamemodermnbytesfhandlerawr%r%r&openhook-s    "rcCsd}t|jtvrd}t|d}|}d}t|r@d}nt|rPd}d}|dkr|r|ddkr|r|d8}|ddkrt |d d s|d d d krd}q|}qPWd n1s0Y|S)z(Check if file is in free format Fortran.FTrr!r Nr &) rsuffixlowerCOMMON_FREE_EXTENSIONSrreadline _has_f_header_has_f90_headerstrip_free_f90_start)fnameresultrr,nr%r%r&is_free_formatLs&  ,(rc Cs`|stttttttttf }|gkr&dSt}d}d}d}t dt j }t d} t d} t d} |rp|ddd \}} d gd d t d D} dat j|td}z |}WnHty}z0td|d|d|dWYd}~n d}~00|sq@|rda|ada|} dadatjtd}ttjtvrft|sft|sfdanttr~t|s~datrt ant!at"dt#tttrdpdf|$%dd }|dks|ddvrܐq|dd}qt&|d\}}|d 7}|dddkr6t&|d|ddd\}}|'dkrVtdkrPqd}qtdkr|ddvr|ddd krd!|dd}nd}qn trt(|d"kr|dd"}|d| vrtd#t#||rtrt(|dkr|dd ks||d$d}d}d}nj| )|}|r8|*d%}|r\|| )|*d%}d}d}n,d!|dd}|r||}n|}|}|}ntdkrZ|s|d&kr| )|r|d'}|}|st+d(q||}| )|rqq|,}| )|}|r|*d%}|r4|| )|*d%}d}d}n|rD|}n|}|}|}|du}nt-d)t#td*|.dt| fa|)|}|r2|*d+}tj/|rt0||dd,nxtj1tgt2}d}|D]:}tj3||}tj/|rd}t0||dd,qq|s:t"d-t#|tj43|fn|||} q|rP|}n|}|}d*|.dt| fa|)|}|r |*d+}tj/|rt0||dd,nxtj1tgt2}d}|D]:}tj3||}tj/|rd}t0||dd,qq|s(t"d-t#|tj43|fn||da|5|rF|ddn|\ aaaaaaaaadS).z 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 ''" is met. NFr z*\s*include\s*(\'|")(?P[^\'"]*)(\'|")z(?P.*)&\s*\Zz(\s*&|)(?P.*)z.*?'''r )r r  cSsg|] }t|qSr%)strr_r%r%r&rbrcz#readfortrancode.. )rzreadfortrancode: reading #z failed with zu. It is likely that installing charset_normalizer package will help f2py determine the input file encoding correctly.rrrfreez Reading file %s (format:%s%s) z,strict z rrz!f2pyr)rcrCrZf2pyz Hzxreadfortrancode: Found non-(space,digit) char in the first column. Are you sure that this code is in fix form? line=%sr,.pyf z.Unexpected end of file when reading multiline z6Flag sourcecodeform must be either 'fix' or 'free': %szLine #%d in %s:"%s" r]) dowithlineistopzAreadfortrancode: could not find include file %s in %s. Ignoring. )6rrrr r beginpatternr rrrecompileIrange fileinputZ FileInputrrUnicodeDecodeError Exceptionr}linenoZ isfirstlinerqrrsplitextrrrCOMMON_FIXED_EXTENSIONSr_has_fix_headerrbeginpattern77beginpattern90r.repr expandtabsreplacesplit_by_unquotedrrNmatchgroupr[rstrip ValueErrorZ filelinenoisfilereadfortrancodedirnamer#joinpathsepclose)ZffilerrZ saveglobalsZlocaldolowercasecontZ finallinellZ includelineZcont1Zcont2Z mline_markl1Z spacedigitsZfinlmsgextrl_Z origfinallinerlcmfn include_dirsZ foundfileinc_dirZfn1r%r%r&rfsv            (                      rzN\s*(?P%s(?=\s*(\b(%s)\b)))\s*(?P(\b(%s)\b))\s*(?P%s)\s*\Zzqcharacter|logical|integer|real|complex|double\s*(precision\s*(complex|)|complex)|type(?=\s*\([\w\s,=(*)]*\))|byte.*rXz|static|automatic|undefined)z([a-z]+[\w\s(=*+-/)]*?|)functionrrbegin)z [a-z\s]*? subroutinerrzprogram|block\s*dataz@|module(?!\s*procedure)|python\s*module|(abstract|)\s*interface|z type(?!\s*\()z\end|endprogram|endblockdata|endmodule|endpythonmodule|endinterface|endsubroutine|endfunctionendzDend\s*(if|do|where|select|while|forall|associate|critical|enum|team)z[\w]*?endifzmodule\s*proceduremoduleprocedure)r implicitrrr)r dimension|virtualrr dimension)r externalrrr)r optionalrrr)r requiredrrr)r publicrrr)r privaterrr)r intrinsicrrr)r intent|depend|note|checkrz \s*\(.*?\).*intent)r parameterrz\s*\(.*r)r datarrr)r callrrr)r entryrrr)r callfunrrr)r commonrrr)r userrr)r containsrr r)r formatrrr)r Kthreadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddefrrf2pyenhancementsz2\s*(?P''')(?P.*?)(?P''')\s*\Z multilinec Csvtdt|@rJdtdjdt|dt|ddd}||}|rn|}|d |d fS|d fS) z 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 z"'zcannot split by unquoted quoteszR\A(?P({single_quoted}|{double_quoted}|{not_quoted})*)(?P{char}.*)\Zz[^"'{}]z[{}]z('([^'\\]|(\\.))*')z("([^"\\]|(\\.))*"))Z not_quotedr6 single_quotedZ double_quotedbeforeafterr )setrrrescaper groupdict)r, charactersrrdr%r%r&rs rcCsBg}t|dD]$}dD]}||d}q||qd|S)N@,@z(),r,)markoutercommasplitrappendr)Zargslinearrr%r%r& _simplifyargss  rz"\s*(?P\b[a-z]+\w*\b)\s*=.*z \s*(?P\b[a-z]+\w*\b)\s*=.*zH\s*bind\(\s*(?P[^,]+)\s*,\s*name\s*=\s*"(?P[^"]+)"\s*\)cCst|d\}}|rtd|std|s|dksBJt|t|d\}}|rvt||t|ddd\}}qPt||dS|dkrdatdiatiiatgia gttd<ittd<dttd<dttd <d a d a dS|dkrd}t rt tkrd }t|krpt d ttttft d t tdttt tt tdd d<t t=tdaqt rt tkrt tdttt tt tdd d<t t=tdat tdttt tt tdd d<t t=tdad a dS|dkrdSd}tttttttttttttttttt t!t"t#t$t%ttt&fD](}|d|}|rhqt|d}qJ|st'} dt krtkrnndSdttvrttdD]} | t(vrt(| } dttvr| ttdvrqt)d| t*|t)j+} | r| | ,d} t-| ,d} | rJd| | | ,df}n d| | f}t.d|}|st dt|dSt/|d|dSqt0dkst0dkrt123drda4t dtdS|ddkrdt krtkrnntdat tkrdStdkr$t5dttd|} | rp| ,dttkspt5dt| ,dtttt6ft tkr~d a t tdttt tt tdd d<t t=tdat7sda8n|ddkrdt krtkrnn tdadSda9t/||d|da8n|ddkr&n|dd krFt/||d|nn|dd!krt:r^dSdt krvtkr~nndSta n0dt krtkrnndSt/||d|dS)"z reset=-1 --- initialize reset=0 --- crack the line reset=1 --- final check if mismatch of blocks occurred Cracked data is saved in grouplist[0]. ;rrNr bodyvarsblockr]r z(crackline: groupcounter=%s groupname=%s zYcrackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement. externals interfacedz5(?P[^"]*)\b%s\b\s*@\(@(?P[^@]*)@\)@.*\Zrargszcallfun %s(%s) result (%s)rzcallfun %s(%s)z8crackline: could not resolve function call for line=%s. rrz"crackline:%d: No pattern for line rz>crackline: groupcounter(=%s) is nonpositive. Check the blocks.thiszGcrackline: End group %s does not match with previous Begin group %s %srrrr);rf2pyenhancementspatternrmultilinepatternr crackliner groupname groupcacherrrrr.rdimensionpatternexternalpattern intentpatternoptionalpatternrequiredpatternparameterpattern datapattern publicpatternprivatepatternintrinsicpattern endifpattern endpattern formatpatternrfunctionpatternsubroutinepatternimplicitpattern typespattern commonpattern callpattern usepatterncontainspattern entrypatternmoduleprocedurepatterncrackline_re_1rgrmarkouterparenrrrcallfunpattern analyzelinerrrendswithr$rrrrrr)r,resetrZ has_semicolonZsemicolon_lineflr-patrre_1r]m1m2rr%r%r&rs&                    $    rcCsdd}d}|D]R}|dkr4|d}|dkrV|d}q n"|dkrV|d}|dkrV|d}q ||}q |S)Nr r(r@(@)@)@r%)r,rfrr%r%r&r Os r rcCsd}d}t||d\}}||7}|r|d|krL|dkrL|d|d7}n6||d7}|ddkrn|d7}n|ddkr|d8}t|dd|d\}}||7}q"|rJt|||f|S)Nr r()@r*rr,)rr)r,commarr.rrr%r%r&ras      rcCs|dddd}|S)Nr+r*r-r,)r)r,rr%r%r&unmarkouterparentsr2cCs|si}|s|S||ur|St|D]}|dkrN|s@||vr||||<q(|dkrr||D]}t|||}q^q(|dkrt||||}q(|dkrt||||}q(|dvr|s||vr||||<q(|dkrq(|dvrtd|q(td t|q(|S) Nr0attrspec kindselector charselector)=typenamenote)rcheckrrrdependz"appenddecl: "%s" not implemented. z-appenddecl: Unknown variable definition key: )listkeys setattrspecsetkindselectorsetcharselectorr[rr)declZdecl2forcekrr%r%r& appenddeclys8   rCzD\s*(?P(@\(@.*?@\)@|\*[\d*]+|\*\s*@\(@.*?@\)@|))(?P.*)\Zz[(?:,(?P[\w(),]+))?(::)?(?P\b[a-z$_][\w$]*\b)(?:\((?P[\w,]*)\))?\Zz\s*(?P\b[\w$]+\b)\s*(@\(@\s*(?P[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P(?:(?!@\)@).)*)\s*@\)@))*\s*\ZzF\s*(?P(operator|assignment))@\(@\s*(?P[^)]+)\s*@\)@\s*\Zz9\s*(?P\b[\w$]+\b)\s*@\(@\s*(?P.*)\s*@\)@\s*\Zz4([-+]?(?:\d+(?:\.\d*)?|\d*\.\d+))[dD]((?:[-+]?\d+)?)zA([-+]?((?:\d+(?:\.\d*)?|\d*\.\d+))[eE]((?:[-+]?\d+)?)|(\d+\.\d*))zintent\s*\(.*?\bcallback\bcCs&|dgD]}t|r dSq dS)Nr3rr)get_intentcallbackpatternr)Zvdeclrr%r%r&_is_intent_callbacks rFcCsld|}t|}t|||rb|d}|rHdd|dDng}|d||dfSdgdfS)Nr attributescSsg|] }|qSr%)r)r`rr%r%r&rbrcz*_resolvetypedefpattern..rr]params)rrtypedefpatternrprintr)r,r(attrsr%r%r&_resolvetypedefpatterns   rLcCsRtdtj}||}d}|rJ|d}|d|||d}||fS)NzObind\(\s*(?P[^,]+)(?:\s*,\s*name\s*=\s*["\'](?P[^"\']+)["\']\s*)?\)r)rrrsearchrstartr)r,patternrZbind_statementr%r%r&parse_name_for_binds   rPcCst|\}}t|}t|}|r@|d|d|d|fSt|}|rv|dd|dd}|gddfSt|}|r|d|dddfSdgddfS)Nr]rrschemer*r,)rPr nameargspatternrroperatorpatterncallnameargspattern)r,Z bind_cnamer(r]r%r%r&_resolvenameargspatterns     rUcGCs|d}|dkrdatr|dvrtstdkrtjt dd}t d|da tdad t t<it t<gtt<gt td <it td <d t td <|t td <dt td<da|dvr|}td|tjrd}n,td|tjrd}ntd|tjrd}|dkrFt|d\}}}t|dt td |<g}d} nt|d\}}} } |dur|dkrvd}nd}|dvrt d||tfa|rtddt| d D}ng}d|vrd|vr|dqt d!d} d} |d"vrnd} d#t tvrdS|t td#vr&dSttD]} | d |kr.dSq.|t td$vr`dSd%d&d"|}trtd'krtdkrtd(ad} |d)vrd} tdait t<gtt<| rPtdkrt d*ttdd+t t<dt td <tt td <dt td<gt td <gt td,<gt td$<it td <tdait t<gtt<| rtdkrnt d-tdd.t t<d.t td <d/t td <d0t tddt tdd ft td<gt td <gt td,<gt td$<it td <tdait t<gtt<|t t<|t td <|s,d1|d2d3}|d4t td5<t|t td <| t td6<tdkrrtt td<n^trtd7krd0t tddtft td<n,d0t tddt tdd ft td<tt t D]}t t|st t|=q|t td#<gt td <gt td,<gt td$<it td <it td8<|dkr^gt td9<|d"vr|t td(d,vrt td(d,!|t"#t td(d t td <z,t td |t td |d:$d;=Wnt%yYn0|dt td=|d><|d?rf|d?t td=|d <z6t(t td |t td(d dt td |<Wnt%yYn0|d@kr | r | t td vr || ks t(t td |t td | t td |<zt td(d$!|Wnt%y:Yn0|d&krt)d|d4d2|}|rt*|d|d\}}}}t+|||||d"vrttd!t tttttdd'd <tt=tdattd!t tttttdd'd <tt=tdan|d8krt|d\}}} }|dur|rhtdAdt| d D}ng}| dusJt| |t td8|<d8|tfan8|dkrt*||d\}}}}t+||||}|durdB|tfan|dCv rt td }|d,}|-dD}|dk r|dEk rt.|-dFd(}|d|ddD||dd}|-dD}||ddDk rd#t tv rt dG|d|d|f|dH/t td#}|dk rd}d}n |d|,}||d(d}t| d }t0|dk r0|d}t dIdH/|ddd}dJdt| d DD]}t1|}| s|dKv rrd}n$t2|3t dL|t|f qLnt|d }|dKv r|dMk s|dNk r||d7}||v ri||<|dOk r||d}|dEk r|d|}t4| r|t td#v rtdk rdPt td(d v rZt dQ|t td k rt dR|t td ft td#!|n t5dS|n t5dT||dUv r|}d:||v r||d:!|n|g||d:<|d;k rZt td d k rt dV qL|t td#v r. qLd,t tv rHgt td,<t td,!||} qL|t td <|durdB|tfa nR|dWk rdXd|d dHDt tdY< n"|dZkrt td }|d,dd'}d}t| d D]}zd[d| d\D\}}Wn*t% y@t d]||fY qYn0t6|}t|}||v rdi||<d\||v r||d\|k st d^|||d\|ft7||}|rH|8d_d`krt|}t9:|D]:}t||;|<dadb||;|<< qd/|}n0|8d_dckrH|dddadbdHdd}zt=|i|} WnJt>t?t@fy}!z*t5de||!fWYd}!~! qWYd}!~!n d}!~!00t| ||d\<d:||vr||d:!dZndZg||d:<|} q|t td <|durdB|tfa n|dfkrH|d,dgkrBdt tdf<q|drdft tvrjt tdf}"ni}"|"durt dhi}"t|d d D]}i}#tdi|tj}|st dj|qtA|d}$|$st dk|qt*|$d|$d\}}}}tB||\}%}&}'||#d_<|%|#dl<|&|#dm<|'|#dn<t|# D]}|#|sH|#|=qHt|d d D]}(do|(vrzdpd|( doD\})}*Wn&t%yt dq|(YqtYn0n |(,})}*t0|)t0|*krdksnt dr|(qttCtD|)tD|*dD]}+|#|"tE|+<qqtq|"t tdf<n|dskrg}d},d}-d}.d}/d}0|dD]}1|0s|1dtkr|/ }/|1dukr|/r|.d}.qt|1dvkr|0d}0n|1dwkr|0d}0|.dkr|,|1},n\|.dkr|-|1}-nH|.d(krt|,,},|,FdHr&|,dd,},|!|,|-g|1},d}-d}.qt|.d(kr|,,},|,FdHrr|,dd,},|!|,|-gt t8d i}2d}|D]T}3|3d,|3d,|3d<|3d<|3dFdHr|3ddd|3d<|3dFdvrt dx|3dqtGtdydt|3d d DD]\}4} | FdvrRt dx| q,dz|3dvrtt d{|3dq,|2H| i|2| 8d_}5tI|2| }6|5dckrtJd||3dn |3d dH}7z"|6rd}Kd~/|7n|7|4}8WntLytMdd|7Drg}9|7D]n}:d|:vrnz*|: d\};}<|9N|<,gtO|;Wn"tPyj|9!|:,Yn0n|9!|:,q|9}7|6rd}Kd~/|7n|7|4}8Yn0|2| 8d\}=|=r|=|8krt d| |=|8f|8|2| d\<| }q,q|2t td <|rdB|tfan|dkr|d,}|dduks>d|}g}>d}.d}?d}@|D]r}1|1dukrl|.d}.qR|.d7kr|?,}?|?sd}?|>!|?|@g|.d(}.d}?d}@|.d(r|?|1}?n|@|1}@qR|?,}?|?sd}?|>!|?|@gi}Adt tvrt td}A|>D]\}1|1d|Avr&g|A|1d<ddt|1d d DD]}|rB|A|1d!|qBq|At td<d|?tfanX|dkrtd|dtj}|r|3}Bdt tvrit td<|d }it td|<d}Cd|Bvr|Bddurd|Bvr|Bddurd}C|Ct td|d<dd|Bd dHD}i}D|D]r}3d\|3vrtd|3tj}$|$r|$d,|D|$d,<nt dt|3n|3|D|3<|Dt td|d<qNnnt2|3t dn|dvrpdt tvrit td<t td}E|ddkrZd|EvrZtQ|EdtRrD|Edg|Ed<|Ed!|dn|d|E|d<nh|dkrtdurtrt ddSt}FtSt |Ftdd(|dntdkrt2|3t ddS)a Reads each line in the input file in sequence and updates global vars. Effectively reads and collects information from the input file to the global variable groupcache, a dictionary containing info about each part of the fortran module. At the end of analyzeline, information is filtered into the correct dict keys, but parameter values and dimensions are not yet interpreted. rrN)rrrrXr.rzBanalyzeline: no group yet. Creating program group with name "%s". programrrrr]Zfromskyfrom)rrrz block\s*data block datazpython\s*module python modulezabstract\s*interfaceabstract interfacerXr)r3 _BLOCK_DATA_r ) interfacerYr[z2analyzeline: No name/args pattern found for line. cSsg|] }|qSr%rr`xr%r%r&rbszanalyzeline..rz.*?)\s*(\(\s*(?P[a-z-, ]+)\s*\)\s*|)\ZzDanalyzeline: could not extract info of implicit statement part "%s" zManalyzeline: could not extract types pattern of implicit statement part "%s" r4r5r7-cSsg|] }|qSr%r^r_r%r%r&rb_rczZanalyzeline: expected "-" instead of "%s" in range list of implicit statement z^analyzeline: expected "-" instead of "%s" in range list of implicit statement (2) r'/r*r,z>analyzeline: implied-DO list "%s" is not supported. Skipping. cSsg|] }|qSr%r^r_r%r%r&rbrcrz=Comment line in declaration "%s" is not supported. Skipping. z\(.*?\)z(/{}/), css|]}d|vVqdS)rNr%)r`rr%r%r& rczanalyzeline..rz=analyzeline: changing init expression of "%s" ("%s") to "%s" rz//_BLNK_cSsg|] }|qSr%r^r_r%r%r&rbrcrzR\A\s*(?P\b\w+\b)\s*((,(\s*\bonly\b\s*:|(?P))\s*(?P.*))|)\s*\Zr;ZnotonlyonlycSsg|] }|qSr%r^r_r%r%r&rbrcz7\A\s*(?P\b\w+\b)\s*=\s*>\s*(?P\b\w+\b)\s*\Zlocalz0analyzeline: Not local=>use pattern found in %s mapz0analyzeline: Could not crack the use statement. )rrZusercodez-analyzeline: No context for multiline block. z+analyzeline: No code implemented for line. )Trr$rrrrqrrbasenamerrr.rrrrrrrrrLdictrUrfrremoverrrrrr^r;r<rcopydeepcopyrPrrMcrackline_bindlangrCrcracktypespec0 updatevarsrfindr rrN namepatternrJrrEr[get_parametersdetermineexprtyperD real16patternfinditerrNreval SyntaxError NameError TypeErrortypespattern4implicit cracktypespecrordchrrv enumerate setdefaultZ getdimensionfindallr IndexErroranyextendr3r isinstancerappendmultiline)Grr:r,rZnewnamer]rKrrrZ bindclineZ needmoduleZ needinterfaceitrBZbindcdattr0selectorattredecl last_nameriplchror(ZapZinitexprrHttvrimplr@r) kindselect charselectr7rZbegcZendcodlilr.fcinprrridxZvtypeZvdimmatchesnew_valZ expanded_listrZ multipliervalueZ current_valclZbnolZ commonkeymmZisonlyrrgcr%r%r&r"s                                                                   $                          $           "              ".    (" $                            r"cCs:d|vri|d<|d}||vr(g||<|||dS)NZf2pymultilinesr)rZ context_namemlrr%r%r&r*srcCsd}d}td|tjrd}n"td|tjr4d}n |}tt|}|s^tddS|}t | D]}t ||||<qr|dvr|d}|d}| d }|d kr|d|}||d d}||||fS) Nzdouble\s*complexdouble complexzdouble\s*precisionzdouble precisionz>cracktypespec0: no kind/char_selector pattern found for line. )rpr2logicalr1 characterrXrrrjrr) rrrrr selectpatternr r.rr;r<r2r)r0rrrr(rrBrr%r%r&r4s0  rz)\s*(?P\b\w+\b)\s*(?P.*)\s*\ZzB\s*(\(\s*(kind\s*=)?\s*(?P.*)\s*\)|\*\s*(?P.*?))\s*\Zz2\s*(\((?P.*)\)|\*\s*(?P.*))\s*\Zz\s*(kind\s*=\s*(?P.*?)\s*(@,@\s*len\s*=\s*(?P.*)|)|(len\s*=\s*|)(?P.*?)\s*(@,@\s*(kind\s*=\s*|)(?P.*)|(f2py_len\s*=\s*(?P.*))|))\s*\Zz\s*(@\(@\s*(?!/)\s*(?P.*?)\s*@\)@\s*\*\s*(?P.*?)|(\*\s*(?P.*?)|)\s*(@\(@\s*(?!/)\s*(?P.*?)\s*@\)@|))\s*(=\s*(?P.*?)|(@\(@|)/\s*(?P.*?)\s*/(@\)@|)|)\s*\ZcCs|}t|dkr|S|d}tdt|dD]>}||dkrd||ddvs2||ddvrdq2|||}q2||d}|S)Nrrrz ()[]{}=+-/* r )rrNr)exprZexpr2rr%r%r& removespaces[s   rcCs~d}d}d}d}|D]d}|dkr6|dvr6||7}|}q|sF|dvrF|}||krV| }n|dkrl|rl|d7}q||7}|}q|S) a( 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 ------- str r FN\)rrs")rsrr@_@r%)r,fragmentZinsideZ current_quoteescapedrr%r%r&markinnerspacesjs&  rc CsBd}t||\}}}|rddt|dD}g}td} |D]D} | sLqB| | } | r|| d} | | t| d} | | qB|}ddt|dD} g}| D]D}ddtt t |d d d DD]}|r| | d d qq|D]D}t |} | std t|qt| d}i}|ttdvrXttd|}d|v}|rn||d<n*|r||dkstd||d|fd|vrt||d<nv|r(t|D]b}||dvr|||d|kstd|||d|||fnt|||d|<qd|vrZ|rZ|rH||d<ntd||fnv|rt|D]b}||dvr|||d|kstd|||d|||fnt|||d|<qld|vr||d<n*|r|d|kstd||d|fd|vr(t||d<n.|r|D]"} | |dvr2|d | q2n@t||d<t||d<t||d<||d<t||d<d|dpgvr|ttdvrdttvrgttd<ttd || drtt| d}|r|}dD]2}||ddur||d||<||d=qt|D],}||durt||||<n||=q^d |vrPd!|vrP|d d"kr|d!|d <|d!=n|d#krd|vs|dsi|d<d |dvr|dd =|d |dd$<|d =n8|d!d%|d |d!<|d =td&|||||d!fd |vr|d'vrd|vsx|dsi|d<|d |dd$<|d =nT|d#krd|vs|dsi|d<d |dvr|dd =|d |dd$<|d =d(|vr:d)|vr.|d)|d(ks.td*||d)|d(fn |d(|d)<d!|vrd+|d!}d|vsd|dsp|g|d<n\|d ||dD]D}|dd,d-kr||kr|dd.=td/|||fqqntd0|| dt|D]}||s||=q|ttd|<d1ttvr8ttd1 ||}q|S)2z Returns last_name, the variable name without special chars, parenthesis or dimension specifiers. Alters groupcache to add the name, typespec, attrspec (and possibly value) of current variable. NcSsg|] }|qSr%r^r_r%r%r&rbrczupdatevars..rz(?P[a-zA-Z]+)rNcSsg|] }|qSr%r^r_r%r%r&rbrccSsg|] }|qSr%r^r_r%r%r&rbrcrr1z@ @rz;updatevars: no name pattern found for entity=%s. Skipping. r]rr0zIupdatevars: attempt to change the type of "%s" ("%s") to "%s". Ignoring. r4zVupdatevars: attempt to change the kindselector "%s" of "%s" ("%s") to "%s". Ignoring. r5zEupdatevars:%s: attempt to change empty charselector to %r. Ignoring. zVupdatevars: attempt to change the charselector "%s" of "%s" ("%s") to "%s". Ignoring. r7zMupdatevars: attempt to change the typename of "%s" ("%s") to "%s". Ignoring. r3rrrr)rNarrayinit2rNrr rrrz-updatevars: "%s %s" is mapped to "%s %s(%s)" rpr2rr1rr6zTupdatevars: attempt to change the init expression of "%s" ("%s") to "%s". Ignoring. dimension(%s) rr z5updatevars:%s: attempt to change %r to %r. Ignoring. z?updatevars: could not crack entity declaration "%s". Ignoring. rf)rrrrrrrrrNrrrrrr.rr^rrr~r;r<r[rDlenarraypatternr rr2)r0rr3Z entitydeclrrrr7rrrrselZel1roe1ZenamerZnot_has_typespecrBr(d1lkdmZdm1r%r%r&rs0    (      $  $     (                      rc Cs d}d}d}|r|dvrt|}|s\w+)\s*\)r]z'cracktypespec: no typename found in %s z'cracktypespec: no selector used for %s )r4rr.rrr;r<itemsr^r5lenkindpatternrrrr) r0rrrr7rBrrrr%r%r&r8st                rcCs|si}|s|Sd|vr&|g|d<|S|r8|d|||dvrH|S|dkrld|dvrl|d|nz|dkrd|dvr|d|nV|dkrd|dvr|d|n2|dkrd|dvr|d|n|d||S)Nr3rB automaticrrr)r@rrAr%r%r&r=ts.    r=cCsZ|si}|s|Sd|vr$||d<|St|D]$}|sD||dvr0|||d|<q0|S)Nr4r;r<r@selrArBr%r%r&r>sr>cCsZ|si}|s|Sd|vr$||d<|St|D]$}|sD||dvr0|||d|<q0|S)Nr5rrr%r%r&r?sr?unknowncCsd|vr|dS|S)Nr]r%)rrr%r%r& getblocknamesrcCs0zd|d|dfaWnty*Yn0dS)Nz In: %s:%s rXr])rr)rr%r%r& setmesstexts rcCs2i}d|vrt|d}d|vr.||d|S)N parent_blockr) get_usedictupdate)rusedictr%r%r&rs  rc Cs|dur i}t|}|s|St|D]\}}|}|tvrXtd||dfq(t|}t|}|snq(|r~td|t|D]0\}}||vrtdt |t |f|||<qq(|S)Nz0get_useparameters: no module %s info used by %s r]z,get_useparameters: mapping for %s not impl. zEget_useparameters: overriding parameter %s with value from module %s ) rr;rrrr.rDrr[r) r param_maprZusenamemappingmvarsrHrBrr%r%r&get_useparameterss2   rc sts|St|tr*fdd|D}|St|td|dfddurXt|durd|vr|d}t|D]@}||}d|vr||d}d|vr||d}|vr|||d<q|fd d|d D} | |d <|S) Ncsg|]}t|ddqSr)tabr postcrack2)r`grrr%r&rbszpostcrack2.. %sBlock: %s r]rrr4rcsg|]}t|ddqSrrr`brr%r&rbsr)rrr;rr.rr<) rrrretrrvarrvalZnew_bodyr%rr&rs4   rcCsPt|trfg}g}|D]F}t|t||dd}d|vrRd|dvrR||q||q||St|t|tsd|vrtdt|d|vr|ddkstd||dfd t |}t |}t ||d <t |d |d <d |vr|d r|d }t |||d|d <g}d|vrP|d}t|D]}d|vr2||q2ni}d} d|vrj|d} d|vr>|dr>g} d|vr|d} t|d } | r| d} nd} | |vrd} d| | f|vr| d} qd| | f} dgi| dd}|dD]}|| vrg}d}|d D]}|d}|ddkr&d} |d D]@}| d} d|vrL|d|krLt|}|d | =qqL|r&|d s|d |=| | |=qq&|d |n(|| vrt| |s| ||d |<q|d s|d r>| |d<d|gi| |dd}i|| <t||rL||d<|S)zi TODO: function return values determine expression types if in argument list rrr]rmrz0postcrack: Expected block dictionary instead of rcrrrZsortvarsrrrr rrZ__user__routinesZunknown__user__routinesrz%s_%ir]Z_user_interface)rrrr]r rZ)rrrr]r)rr;r postcrackrr|rrr. analyzeargs analyzecommon analyzevars sortvarnames analyzebodyr<r~rPZ isexternalr)rrrZgretZuretrZ userisdefinedZuseblockrBr]rrZmnamerr]roZedefjrZbbZmblockr%r%r&rs                         rcCsg}g}t|D]2}d||vr<||dr<||q||qt|}d}|r|d}d}|ddD]}|||dvrpd}qqp|r|dd|g}|d}||krtdd|d||}qqT|||dd}t|}d}qT|S)Nr:rrzTsortvarnames: failed to compute dependencies because of cyclic dependencies between rur)r;r<rrNr[r)rZindepdeprrrr%wr%r%r&rds>    rcCst|s |Sg}t|dD]<}g}|d|D]}td|tj}|r2g}|dr~ddt|ddD}t |d }||dvrd |d|vr|d|d  d d |nd d |g|d|d <n0|rd d d |gi|d|<n i|d|<||vrF| |n|}t d ||f| |q6||d|<q d |vrt||d <n|d ||d <|S)Nrz2\A\s*\b(?P.*?)\b\s*(\((?P.*?)\)|)\s*\ZdimscSsg|] }|qSr%r^r_r%r%r&rbsz!analyzecommon..rr]rr3rrzNanalyzecommon: failed to extract "[()]" from "%s" in common /%s/. commonvars)Z hascommonr;r<rrrrrrr^rrrr[)rrrBZcomvarsrorrrr%r%r&rsN           rcCsDt|dd|dD}g}|dD]}||d<|ddvr|dur\|d|vr\q*n|d }|d|vrt|d|dtvrq*tr|dtvrq*t|d d d |d <n|}t|||dd}|ddvr|ds|dsd|vrq*|d dddkrt |q*|ddkr4|dt |d<||q*|S)NcSs*i|]"\}}d|vs d|dvr||qS)r3rr%)r`keyrr%r%r& szanalyzebody..rrrrrgr]rz T as_interfaceZsaved_interfacerrrarnrrr pythonmodulerb) rrr<r!rr"crack2fortrangenrrDrrr)rrrZ maybe_privaterrZas_r%r%r&rsF       rcCst|t}i}d|vr|ddurFd}tdkrtdt|dnRt|dD]@}|d|ddvr|d|||<qV|d|d||<qV||fS)Nrrz6buildimplicitrules: no implicit rules for routine %s. r]r0)rBr)rdefaultimplicitrulesrr.rr;r<rD)r implicitrules attrrulesrBr%r%r&buildimplicitruless rcCs0t|||}t|ttfvr |Std|dS)z2 Like `eval` but returns only integers and floats zr=%rN)rrXr3r5r)rorrrr%r%r&myevals rz \A\b\w+\b\Zc Csztt|ii}d|dfWSty.Yn0t|rDdd|fSt|}|D]}t||krdqPtd|d|rzqPtd|dtj }||}|rPzF||}|rd| d d| d f}||}qt|ii} ||}|rd| d d| d f}||}qt|ii| } ||}|r`d| d d | d f}||}q2t|ii}||}|rd| d d | d f}||}qvt|ii} | d | |kr| d | | kr| | |fWSWntyYn0qqPd S)a 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') rNrz\w\s*\([^)]*\b\b(?P.*?)\b\b(?P.*)z%s(%s)%srrg?g?)NNN) r3rrgetlincoef_re_1rrNrrMrrr) roZxsetrZlen_er`r'rr(eerrc2r%r%r& getlincoefsf                $r z\b[a-z][\w$]*\bcCs||vr||dg}d||vrjt||sjt||dD]&}||vrB||vrB||krB||qB|ddD]4}||gpt|||D]}||vr||qqvntdt|g}|||<|S)Nr:r6z,_get_depend_dict: no dependence info for %s )rDisstring word_patternrr_get_depend_dictr.r)r]rdepswordswordrr%r%r&rF s    rcCs*t|}i}|D]}t|||q|Sr()r;r<r)rre depend_dictrr%r%r&_calc_depend_dict\ s  rcstg}tD]}|s|||=qrtD]8\}}fdd|D}|sv|||=qF||<qFq6fdd|DS)Ncsg|]}|vr|qSr%r%)r`r)rr%r&rbm rcz$get_sorted_names..csg|]}|vr|qSr%r%)r`r]rr%r&rbs rc)rr;r<rr)rrer]lstZnew_lstr%)rrr&get_sorted_namesd s   rcCs@|ddvr|dd}t|r&dSt|r4dSd|dS) Nr'"rr zkind(r,)rr real8pattern)rUr%r%r& _kind_funcv s    rcCsLd|}|dkrdS|dkr dS|dkr,dS|dkr8d S|dd krHd Sd S) Nrrirlrlrr r%)rrr%r%r&_selected_int_kind_func s r cCsX|dkr dS|dkrdSt}|dr<|dkrTdSn|dkrHdS|dkrTdSd S) Nrrr) aarch64alphaarm64Z loongarchmipspowerppcZriscvs390xZsparc!rr )platformmachinerrv)prradixr,r%r%r&_selected_real_kind_func s  r/c CsFt|}t|}dtfdtfdtffD]\}}||vr*|||<q*g}t|D]*}d||vrPd||dvrP||qPtdtj}tdtj} tdtj} |D]}d ||vr$||d } t ||r| } d D]} | j | } q| d | } | d | } d } d||vr^d||dvr^t | }| d||ddd} t | |k} | s| | s| d}t |dkrd|dd |d d} t||rt| }t| D]:}t| || dd|||<qd|} nt||r4td| ddd||dDpPdgd}t| rhd} nt| rxd} zt| |||d||<WnDty}z*| ||<td|d|dWYd}~n d}~00t||rt||trt ||||<| }||kr@||||<qt!||td|d q|S)!NrZselected_int_kindZselected_real_kindr3rz \bkind\s*\(\s*(?P.*)\s*\)z-\bselected_int_kind\s*\(\s*(?P.*)\s*\)z4\bselected_(int|real)_kind\s*\(\s*(?P.*)\s*\)r6))z.false.False)z.true.Truez kind("\1")zselected_int_kind(\1)Fr4rr rr rrozAget_parameters[TODO]: implement evaluation of complex expression rcSs$g|]}|dr|dqS)r)rvlstriprr`rr%r%r&rb s z"get_parameters..rrr)dimspeczget_parameters: got "" on zget_parameters:parameter z does not have value?! )"r~rr r/rrrrrZ islogicalrrsubrNrrrZisdoubler;rrrNrZ iscomplexr.rMr param_evalrr rr3rrJ)rZ global_paramsrHg_paramsr]funcZ param_namesrZkind_reZselected_int_kind_reZselected_kind_rerreplZ is_replacedZ orig_v_lenZv_rrr4rnlr%r%r&r s               &      ,  rcCs|dvr dSt||S)N)z(:)(*)rr<) _eval_scalar)lengthrHr%r%r& _eval_length sr?z\d+_c Cst|r|dd}z&t|i|}t|tr2tnt|}WnXtttfyX|YSt y}z&t d||t | fWYd}~n d}~00|S)Nrrz,"%s" in evaluating %r (available names: %s) ) _is_kind_numberrrrrrrrrrr[r;r<)rrHrr%r%r&r= s r=c> st|t|\}}t|d|ddkrF|dvrFi|d<d|dvrĈd=d|ddvr|ddd}ttdd|d DBD],}d D]"}||vrt|i||<qqg}|d }|D]0}z|||WqtyYq0qt D]}||vr||qt t |} i} t d j} t D]b} | | } | rX| | | }z | |Wn,tyt d | t jj| |<Yn0qX|D ]}|dt| vrt|||d|<d|vrd|vr$d|dvs|r|d}t|| D]z}|dkrj|||dkrjqF||vr|||||<n0|dkrF|||D]}t|||<qqFn&||d vrtdt||dfd|vrTd|dvrT|dd}ztt|i| }WntyBYn0||dd<d|vrd|dvr|dd}ztt|i| }WntyYn0||dd<i}d|vr|d}|g|d<d\}}}}}|D]}|dddkr4|dddd}n|dddkr`|dddd}n|dddkr|dddd}nj|dd d!kr|d ddd}n>|dd"d#kr|d"ddd}nt|||<|rjd|vrg|d<d$d%t|d&DD]6}|d'd}||dvr.|d|q.d}|r|d(d)}|d*d+}d#|vr|g|d#<n|d#|d}|dur,d|vrg|d<td,d%t|d&DD]*}||dvr|d|qd}|durd!|vrPg|d!<d-d%t|d&DD]*}||d!vrh|d!|qhd}q|rd|vrg|d<td.d%t|d&DD]}zt|| }Wn*tt tfytd/|d+Yn0|d0kr&d0nd1}||kr<|g}nt|d0d2}t!|d3krnd1|vrnd1g}d1}t!|dkr|d|krd4|dg}t!|d3krt"t#j$j%|\}}||d}|j&t#j'j(d5}i}|dD]} t#)| } |*| rz:|+| \}}!||!fd6d7}"t|,}#|#-|!,Wn6t.yh}$zd}"t|,}#WYd}$~$n d}$~$00tfd8d|#D}%|"t|%f|| <q|||<|d|qd!|v rdd |v rd||d v rd|dg}&g}'t/t0t1t2|}(t3| rt4|dD]x\})}||du r@n|( r5D]\} \}*}+fd9d:t},| |,| |&v sNd;| v sNd| v r qN|*du r6| |,v r6d<}-|*t#)d=|d>|)d?}.|.j&t#j'j(d5}.|.| d;<|g|+| d<d!| v rd=|d>|)d@|g| d!<nhdA}-d| v rTg| d<dB| dv rx| ddB|&| |'d=|d>|)d@|| dg}/dC|/v sdD|/v s|/|- rdDndC|/ rN|/| d< qNdu r5D]\} \}*}+| dg}%| dgD]8}0|06d r*d7|0}0|%8|0dEddF q*|% r~tt|%| d<||%v r|&|  q qnt9| r8d|v r8d1|dv rt:|dd1| }1|1|dd1<nFd|dv r8t:|dd| }1|dd=|1|dd1<|' rJ|'|d!<|& rdtt|&|d<d;|vrd|v rg|d<dC|dv rdD|dv rˆ|ddCd|v r0g|d<t| 5D].\} } | |d; r|d|  q|d s0|d=t;|rt<|d;| |d;<qt D]}||dk rhd#|v r|d#|d#<|ddk rhdG|v r|dGv rt=||dG|<dH|v rh|dH}2|2dId}3|2|3k }4|3dJd}2|2|3k }5t>d|2} | r:t?| @dK| @dL\}6}7}}8tA|6|7\}9}:};|6|d<z|dGr|6|dGd<WntyYn0|9rd|9vrzt|9di| |9d<WntyYn0|9|d<|:r|:|d<|;r|;|dM<|4r t|dI|<|5rNt|dJ|<ntdNt|dH qh|ddOvrdP|vrt|d |dP}.rrkrz[A-Za-z][\w$]*z.*\b%s\brr0rZ undefinedzCanalyzevars: typespec of variable %s is not defined in routine %s. r5rNr4r)NNNNNNrrrr rrr:rr9rr8cSsg|] }|qSr%r^r_r%r%r&rb rczanalyzevars..rrz\n\nz z\n rcSsg|] }|qSr%r^r_r%r%r&rb rccSsg|] }|qSr%r^r_r%r%r&rb rccSsg|] }|qSr%r^r_r%r%r&rb rcz4analyzevars: could not parse dimension for variable :rz@:@r1)languagecSs |||Sr(r%)rrrr%r%r&solve_v szanalyzevars..solve_vc3s|]}|jvr|jVqdSr()rr3rr%r&rv s cs:|dggdD] }||vr||||qdS)Nr)rDadd)rrZv1)coeffs_and_deps compute_depsr%r&rG s z!analyzevars..compute_depsr6Fzshape(rur,z) == Tinrrr!rrrdZpure recursiverrr7z'analyzevars: prefix (%s) were not used )rbrrZrYrr)rrrX)Drrr~rr=rDrKeyErrorr;r<rrrrrrNrrrr.rrrrreverserrrrrf param_parserrrNrzrExprparseZtostringZLanguagerZ as_symbolrZ linear_solvesymbolsr RuntimeErrorZl_orZ isintent_inZisintent_inoutZisintent_inplaceZisarrayrrrvrrr r?Zisscalarr=rCrrrrisintent_callbackZ isintent_aux)>rrrgenrrBZsvarsrrrHZ dep_matchesZ name_matchrrZln0rZdimension_exprsrdimrr:r9r8rtmprZdim_charrrZd2ZdsizeZsolver_and_depsrrrDZ all_symbolsrZv_depsZn_depsZn_checksZ n_is_inputrZsolverrZall_depsZ is_requiredrZv_attrZaar>prZpr1ZispureZisrecr0rrrrr7Z neededvarsr]r%)rFrGrr&r" s   "   "                           " &                                      rz\A[a-z]+[\w$]*\Zc Cs|dur\zt|||}Wn>tyV}z&|}td|d|dWYd}~n d}~00|St|dks|ddt|ddkrtd|d |dd d }t|dkr"|d d }t|dkrt|d |}tdt|d}n2t|d |}t|d|} tt|t| d}ntd| drB|ddn|d }g} |D]^} zt| ||} Wn<ty}z"td|d| dWYd}~n d}~00| | qTt t || }|S)a Creates a dictionary of indices and values for each parameter in a parameter array to be evaluated later. WARNING: It is not possible to initialize multidimensional array parameters e.g. dimension(-3:1, 4, 3:5) at this point. This is because in Fortran initialization through array constructor requires the RESHAPE intrinsic function. Since the right-hand side of the parameter declaration is not executed in f2py, but rather at the compiled c/fortran extension, later, it is not possible to execute a reshape of a parameter array. One issue remains: if the user wants to access the array parameter from python, we should either 1) allow them to access the parameter array using python standard indexing (which is often incompatible with the original fortran indexing) 2) allow the parameter array to be accessed in python as a dictionary with fortran indices as keys We are choosing 2 for now. Nzparam_eval: got "r5rrrr/zparam_eval: dimension z can't be parsedr rrrAzEparam_eval: multidimensional array parameters {dimspec} not supportedz(/r) rrr.rNrrrLrr3rvrr|zip) rr8rHr4r-rZdimrangeboundZlboundZuboundZv_evalitemr%r%r&r7 s:,& ",r7cCsd|vrT|d|d}||dd|d}tt||}t|||S||vrht||S|D]T}td|dtj}||}|rl| dt||| d}||}qql|SdS) aRecursively parse array dimensions. Parses the declaration of an array variable or parameter `dimension` keyword, and is called recursively if the dimension for this array is a previously defined parameter (found in `params`). Parameters ---------- d : str Fortran expression describing the dimension of an array. params : dict Previously parsed parameters declared in the Fortran source file. Returns ------- out : str Parsed dimension expression. Examples -------- * If the line being analyzed is `integer, parameter, dimension(2) :: pa = (/ 3, 5 /)` then `d = 2` and we return immediately, with >>> d = '2' >>> param_parse(d, params) 2 * If the line being analyzed is `integer, parameter, dimension(pa) :: pb = (/1, 2, 3/)` then `d = 'pa'`; since `pa` is a previously parsed parameter, and `pa = 3`, we call `param_parse` recursively, to obtain >>> d = 'pa' >>> params = {'pa': 3} >>> param_parse(d, params) 3 * If the line being analyzed is `integer, parameter, dimension(pa(1)) :: pb = (/1, 2, 3/)` then `d = 'pa(1)'`; since `pa` is a previously parsed parameter, and `pa(1) = 3`, we call `param_parse` recursively, to obtain >>> d = 'pa(1)' >>> params = dict(pa={1: 3, 2: 5}) >>> param_parse(d, params) 3 r*Nrr,rrrr) rrfindr3rLrrrrrr)rrHZdnameZddimsrPr-r'rr%r%r&rL s(9   rLc Csf|}t| }|rt|\}}t||d|}d}|D](} | } | tjtjvrXd} || }q8|ddkrx|d}n|d}|}||dvs||dvr|d}q||vrd } |t| |vr| d } q|t| }|r||d|<nx||dvr(||dvr|d||d|<n i|d|<d |vrb||d |d vrbt |d|d |d|<|S) NrZe_rr ro_errrrrr) analyzeargs_re_1rrrrrUascii_lowercasedigitsrr=) rrrZorig_aZ a_is_exprrratnarrBr%r%r& expr2name: s>          r`cCst|t|\}}d|vr$g|d<g}|dD]}t|||}||q0||d<d|vrt|dD]*\}}|D]}||dvrxi|d|<qxql|dD]B}|d|vrd|vrg|d<|d|dvr|d|dqd|vr|d|dvri|d|d<|S)Nrrrrr]rr)rrr`rr;r)rrrrrrBZargs1rr%r%r&r_ s.       rz\A\(.+?,.+?\)\Zz\A[+-]?\d+(_(?P\w+)|)\Zz*\A[+-]?[\d.]+[-\d+de.]*(_(?P\w+)|)\Zz \A\(.*\)\Zz\A(?P\w+)\s*\(.*?\)\s*\ZcCsTt|trddiSt|tr$ddiSt|tr6ddiSt|trD|Stt|dS)Nr0r2r1rp)rr3r5rpr|AssertionErrorr)rr%r%r&_ensure_exprdict s    rbcCs||vrt||S|}t|r.ddiSt|}|rjd|vrb|drbtdt|ddiSt |}|rd|vr|drtdt|ddiSdD]J}dd t ||d  d |d DD] }||vrt||Sqqi}t |rt |d d ||}nft|}|r|d}t |d||}|r^d|vr^|d=|s|d|vrt||dS|ddvrdddidS|stdt||S)Nr0rpr]z:determineexprtype: selected kind types not supported (%s) r2r1)+rrrrtcSsg|] }|qSr%r^r_r%r%r&rb rcz%determineexprtype..rr0rr r3rrrr)r0r5z>determineexprtype: could not determine expressions (%s) type. )rbrdetermineexprtype_re_1rdetermineexprtype_re_2rrr.rdetermineexprtype_re_3rrdetermineexprtype_re_4rdetermineexprtype_re_5)rrrulesroprorZrnr%r%r&r sT      (    rrFcCst|d}t|trf|D]F}|rN|ddvrN|dtvr%sr)rrrrrrBr%r%r&rl s(  rlc CsR|d}g}|D]<}ztd|}Wnty8Yq0||r||q|S)Nrz isintent_%s)globalsrJr)rrrrr.r%r%r&true_intent_list' s  rqc Cs,t|d}g}|D]}||dvr||qd|vrn|dD],}||vr`||vrl||q@td|q@d|vr||d|st|D]}||vr||q|D]t}d||vr ||dD]8}||vrd||vr|||dvrtd||fqd|vr||dvrt||r>d |||f}d |||f}t||rhd |||f}||vrd ||vrqd } |dD],} || dkr| ddkrd} qq| rq||vrt|t d|q||dkr |ddks| dr qd ||vrld||vrRd||dvrR||vrd |||f}qt||t d|q||d } | dkrd||vrd| ||df} i} d||vr||d} nd||vr||d} d| vr| ddvrd| | df} nd | | df} nZd!| vrZd"| | d!f} d#| vrPd$| | d#f} nd%| } nd#| vrtd&| | d#f} d'} d||vrd(d)||dD}|rd*|vrd+|vr| d+|rd,| d- |f} d-} d.||vr d/| | d- ||d.f} d-} d0||vrBt ||}|r>d1| | d- |f} d-} d2||vrpd3| | d- ||d2f} d-} d||vrd4| | d- ||df} d-} d5||vr ||d5}||d d6vrzt|}d7|j|jf}WntyYn0d8| ||f} n d9| |f} d:||| f}q|S);Nr rrz7vars2fortran: Confused?!: "%s" is not defined in vars. rfr:zHvars2fortran: Warning: cross-dependence between variables "%s" and "%s" rz%s%sintent(callback) %sz%s%sexternal %sz%s%soptional %sr0rrr]rrrz/vars2fortran: No definition for argument "%s". rr3rz-vars2fortran: No typespec for argument "%s". rXr7z%s(%s)r4r5r)rrAz%s*(%s)z%s*%srNz %s(len=%srz %s,kind=%s)z%s)z %s(kind=%s)rcSsg|]}|dvr|qS))rr%)r`rr%r%r&rb sz vars2fortran..z intent(in)z intent(out)z%s, %srrz%s%sdimension(%s)rz%s%sintent(%s)r9z %s%scheck(%s)z%s%sdepend(%s)r6)rprz(%s,%s)z %s :: %s=%sz%s :: %sro)rrr[rr;r<rQZ isoptionalshowr.rDr}rrqrr1imagr)rrrrrrZnoutrrrrZvardefrrrrrr%r%r&rn5 s      $                   rncCsztddt|ttddgattd}tddtD]"}td|jddt||}q|d\}}|\}}dd} |dvrF|dddks8J|dd} n.|d krp|d ddksbJ|d d} nd } d } | d ur|} | D]\} } t| r| | | } qnP|d kr|d dd} |} | D]*\} } t| rtd | dd| | } q| d ur:| |kr2td|d|d|d| d d|| fSd S)aPreviously, 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. r cSs0td|d||}td|d||}|S)Nz[*]\s*\brz\b\s*[\[]\s*0\s*[\]])rr6)varnamerr%r%r& fix_usage5s z8character_backward_compatibility_hook..fix_usage)rr9rrrr6rNZ callstatementz (? `z` )rZ ischaracterrr6r.)rXrrrrZ parent_keyZ parent_valuerrrZ vars_dictrrZvdr%r%r&%character_backward_compatibility_hook#sD   r__main__rAz-quietz-verboserz-fixz?Use option -f90 before -fix if Fortran 90 code is in fix form. z-skipemptyendsz--ignore-containsz-f77z-f90rz-hz-showz-mrrzUnknown option %s z OSError: a Warning: You have specified 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). z Writing fortran code to file %s r)r)r)r)r)r)r)r)r)N)r N)Nr )r )NN)rr)N)rF)r )r )r F)__doc__r)rUrrrqr~r+rwpathlibrrn ImportErrorr rZauxfuncsrversionr{r r r rrrrrrrrrrrrrrrrrrr#rr"r$rr!r rr'r. _MAXCACHErrrZrgrr^rfrhrirrrMrrrrrrrrrrrrZbeforethisafterZ fortrantypesrrrrZ groupbegins77rZ groupbegins90rZ groupendsrZendifsrZmoduleproceduresrrrr r r rrrr r rrrr!rrrrSrrrrrZcrackline_bind_1rrr rr2rCrrIrRrSrTrrrErFrLrPrUr"rrrr4r5rrrrrrr=r>r?rrrrrrrrrrrr r rrrrrr r/rr?r@r=rr[r7rLr`rrdrerfrgrhrbrrrmrlrqrnrtrzrrrvrrrurwfuncsr.f2Zf3Z showblocklistargvrr[rrtrOSErrordetailrxr|r+r%r%r%r&sL       &  Z                            W %*<       `"+ - H   e   >P % - K  B<              **