2020-01-27 18:22:35 +01:00
#!/usr/bin/env python3
2009-09-23 12:51:27 +02:00
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Anthony Scemama
# LCPQ - IRSAMC - CNRS
# Universite Paul Sabatier
# 118, route de Narbonne
# 31062 Toulouse Cedex 4
2009-09-25 00:04:49 +02:00
# scemama@irsamc.ups-tlse.fr
2009-09-23 12:51:27 +02:00
2009-09-02 20:45:53 +02:00
import getopt , sys
2020-01-27 18:43:22 +01:00
from version import version
2011-09-22 19:56:55 +02:00
import re
2009-09-02 20:45:53 +02:00
description = " IRPF90 Fortran preprocessor. "
options = { }
2013-07-08 23:40:40 +02:00
options [ ' a ' ] = [ ' assert ' , ' Activates ASSERT statements. If absent, remove ASSERT statements. ' , 0 ]
2014-10-02 09:42:04 +02:00
options [ ' c ' ] = [ ' codelet ' , ' entity:NMAX or entity:precondition:NMAX : Generate a codelet to profile a provider running NMAX times ' , 1 ]
options [ ' C ' ] = [ ' coarray ' , ' All providers are coarrays ' , 0 ]
options [ ' d ' ] = [ ' debug ' , ' Activates debug. The name of the current subroutine/function/provider will be printed on the standard output when entering or exiting a routine, as well as the CPU time passed inside the routine. ' , 0 ]
options [ ' D ' ] = [ ' define ' , ' Defines a variable identified by the IRP_IF statements. ' , 1 ]
options [ ' g ' ] = [ ' profile ' , ' Activates profiling of the code. ' , 0 ]
2009-09-02 20:45:53 +02:00
options [ ' h ' ] = [ ' help ' , ' Print this help ' , 0 ]
2014-10-02 09:42:04 +02:00
options [ ' I ' ] = [ ' include ' , ' Include directory ' , 1 ]
2015-05-28 00:28:17 +02:00
options [ ' j ' ] = [ ' ninja ' , ' Use Ninja instead of make ' , 0 ]
2013-07-08 23:40:40 +02:00
options [ ' i ' ] = [ ' init ' , ' Initialize current directory. Creates a default Makefile and the temporary working directories. ' , 0 ]
2014-10-02 09:42:04 +02:00
options [ ' l ' ] = [ ' align ' , ' Align arrays using compiler directives and sets the $IRP_ALIGN variable. For example, --align=32 aligns all arrays on a 32 byte boundary. ' , 1 ]
options [ ' m ' ] = [ ' memory ' , ' Print memory allocations/deallocations. ' , 0 ]
2015-02-07 15:49:29 +01:00
options [ ' n ' ] = [ ' inline ' , ' <all|providers|builders> : Force inlining of providers or builders ' , 1 ]
2013-07-08 23:40:40 +02:00
options [ ' o ' ] = [ ' checkopt ' , ' Shows where optimization may be required ' , 0 ]
options [ ' p ' ] = [ ' preprocess ' , ' Prints a preprocessed file to standard output. Useful for debugging files containing shell scripts. ' , 1 ]
options [ ' r ' ] = [ ' no_directives ' , ' Ignore all compiler directives !DEC$ and !DIR$ ' , 0 ]
2014-10-02 09:42:04 +02:00
options [ ' s ' ] = [ ' substitute ' , ' Substitute values in do loops for generating specific optimized code. ' , 1 ]
options [ ' t ' ] = [ ' touch ' , ' Display which entities are touched when touching the variable given as an argument. ' , 1 ]
options [ ' v ' ] = [ ' version ' , ' Prints version of irpf90 ' , 0 ]
2015-06-01 14:56:41 +02:00
options [ ' w ' ] = [ ' warnings ' , ' Activate Warnings ' , 0 ]
2014-10-08 16:24:01 +02:00
options [ ' z ' ] = [ ' openmp ' , ' Activate for OpenMP code ' , 0 ]
2009-09-02 20:45:53 +02:00
class CommandLine ( object ) :
def __init__ ( self ) :
2009-09-03 23:12:32 +02:00
global options
2009-09-03 00:46:11 +02:00
self . _opts = None
2009-09-03 23:12:32 +02:00
self . argv = list ( sys . argv )
self . executable_name = self . argv [ 0 ]
2009-09-02 20:45:53 +02:00
2009-09-03 23:12:32 +02:00
def defined ( self ) :
2009-09-04 15:11:42 +02:00
if ' _defined ' not in self . __dict__ :
2009-09-03 23:12:32 +02:00
self . _defined = [ ]
for o , a in self . opts :
2011-08-04 14:04:14 +02:00
if o in [ " -D " , ' -- ' + options [ ' D ' ] [ 0 ] ] :
2009-09-03 23:12:32 +02:00
self . _defined . append ( a )
return self . _defined
defined = property ( fget = defined )
2009-09-02 20:45:53 +02:00
2013-11-20 17:43:03 +01:00
def include_dir ( self ) :
if ' _include_dir ' not in self . __dict__ :
self . _include_dir = [ ]
for o , a in self . opts :
if o in [ " -I " , ' -- ' + options [ ' I ' ] [ 0 ] ] :
2014-02-27 14:06:31 +01:00
if len ( a ) < 1 :
2020-01-27 18:22:35 +01:00
print ( " Error: -I option needs a directory " )
2013-12-11 14:00:27 +01:00
if a [ - 1 ] != ' / ' :
a = a + ' / '
2013-11-20 17:43:03 +01:00
self . _include_dir . append ( a )
return self . _include_dir
include_dir = property ( fget = include_dir )
2011-10-21 09:10:40 +02:00
def inline ( self ) :
if ' _inline ' not in self . __dict__ :
self . _inline = " "
for o , a in self . opts :
if o in [ " -n " , ' -- ' + options [ ' n ' ] [ 0 ] ] :
self . _inline = a
break
return self . _inline
inline = property ( fget = inline )
2011-09-22 19:56:55 +02:00
def substituted ( self ) :
if ' _substituted ' not in self . __dict__ :
self . _substituted = { }
for o , a in self . opts :
if o in [ " -s " , ' -- ' + options [ ' s ' ] [ 0 ] ] :
k , v = a . split ( ' : ' )
2012-05-15 18:01:27 +02:00
v_re = re . compile ( r " ( \ W)( %s )( \ W.*$|$) " % k . strip ( ) )
2011-09-22 19:56:55 +02:00
self . _substituted [ k ] = [ v , v_re ]
return self . _substituted
substituted = property ( fget = substituted )
2014-01-07 17:01:40 +01:00
def codelet ( self ) :
if ' _codelet ' not in self . __dict__ :
self . _codelet = [ ]
for o , a in self . opts :
if o in [ " -c " , ' -- ' + options [ ' c ' ] [ 0 ] ] :
buffer = a . split ( ' : ' )
filename = ' codelet_ ' + buffer [ 0 ] + ' .irp.f '
if len ( buffer ) == 2 :
self . _codelet = [ buffer [ 0 ] , int ( buffer [ 1 ] ) , None , filename ]
elif len ( buffer ) == 3 :
self . _codelet = [ buffer [ 0 ] , int ( buffer [ 2 ] ) , buffer [ 1 ] , filename ]
else :
2020-01-27 18:22:35 +01:00
print ( """
2014-01-07 17:01:40 +01:00
Error in codelet definition . Use :
- - codelet = provider : NMAX
or
- - codelet = provider : precondition : NMAX
2020-01-27 18:22:35 +01:00
""" )
2014-01-07 17:01:40 +01:00
sys . exit ( 1 )
return self . _codelet
codelet = property ( fget = codelet )
2009-09-16 15:59:13 +02:00
def preprocessed ( self ) :
if ' _preprocessed ' not in self . __dict__ :
self . _preprocessed = [ ]
for o , a in self . opts :
2011-08-04 14:04:14 +02:00
if o in [ " -p " , ' -- ' + options [ ' p ' ] [ 0 ] ] :
2009-09-16 15:59:13 +02:00
self . _preprocessed . append ( a )
return self . _preprocessed
preprocessed = property ( fget = preprocessed )
2010-08-31 11:53:34 +02:00
def touched ( self ) :
if ' _touched ' not in self . __dict__ :
self . _touched = [ ]
for o , a in self . opts :
2011-08-04 14:04:14 +02:00
if o in [ " -t " , ' -- ' + options [ ' t ' ] [ 0 ] ] :
2010-09-01 15:10:16 +02:00
self . _touched . append ( a . lower ( ) )
2010-08-31 11:53:34 +02:00
return self . _touched
touched = property ( fget = touched )
2011-08-04 14:04:14 +02:00
def align ( self ) :
if ' _align ' not in self . __dict__ :
2012-12-07 15:12:10 +01:00
self . _align = ' 1 '
2011-08-04 14:04:14 +02:00
for o , a in self . opts :
if o in [ " -l " , ' -- ' + options [ ' l ' ] [ 0 ] ] :
2012-12-07 15:12:10 +01:00
self . _align = a
2011-08-04 14:04:14 +02:00
return self . _align
align = property ( fget = align )
2014-10-02 09:42:04 +02:00
def coarray ( self ) :
if ' _coarray ' not in self . __dict__ :
self . _coarray = False
for o , a in self . opts :
if o in [ " -C " , ' -- ' + options [ ' C ' ] [ 0 ] ] :
self . _coarray = True
return self . _coarray
coarray = property ( fget = coarray )
2015-06-01 14:56:41 +02:00
def warnings ( self ) :
if ' _warnings ' not in self . __dict__ :
self . _warnings = False
for o , a in self . opts :
if o in [ " -w " , ' -- ' + options [ ' w ' ] [ 0 ] ] :
self . _warnings = True
return self . _warnings
do_warnings = property ( fget = warnings )
2014-10-08 16:24:01 +02:00
def openmp ( self ) :
if ' _openmp ' not in self . __dict__ :
self . _openmp = False
for o , a in self . opts :
if o in [ " -z " , ' -- ' + options [ ' z ' ] [ 0 ] ] :
self . _openmp = True
return self . _openmp
do_openmp = property ( fget = openmp )
2015-05-28 00:28:17 +02:00
def ninja ( self ) :
if ' _ninja ' not in self . __dict__ :
self . _ninja = False
for o , a in self . opts :
if o in [ " -j " , ' -- ' + options [ ' j ' ] [ 0 ] ] :
self . _ninja = True
return self . _ninja
do_ninja = property ( fget = ninja )
2011-08-04 14:04:14 +02:00
def directives ( self ) :
if ' _directives ' not in self . __dict__ :
self . _directives = True
for o , a in self . opts :
if o in [ " -r " , ' -- ' + options [ ' r ' ] [ 0 ] ] :
self . _directives = False
return self . _directives
directives = property ( fget = directives )
2009-09-02 20:45:53 +02:00
def usage ( self ) :
t = """
$ EXE - $ DESCR
Usage :
$ EXE [ OPTION ]
Options :
"""
t = t . replace ( " $EXE " , self . executable_name )
t = t . replace ( " $DESCR " , description )
2020-01-27 18:22:35 +01:00
print ( t )
2013-07-08 23:40:40 +02:00
print_options ( )
2020-01-27 18:22:35 +01:00
print ( " " )
print ( " Version : " , version )
print ( " " )
2009-09-02 20:45:53 +02:00
def opts ( self ) :
2009-09-03 00:46:11 +02:00
if self . _opts is None :
optlist = [ " " , [ ] ]
2011-04-09 23:45:50 +02:00
for o in options :
2009-09-03 00:46:11 +02:00
b = [ o ] + options [ o ]
if b [ 3 ] == 1 :
b [ 0 ] = b [ 0 ] + " : "
b [ 1 ] = b [ 1 ] + " = "
optlist [ 0 ] + = b [ 0 ]
optlist [ 1 ] + = [ b [ 1 ] ]
try :
2009-09-03 23:12:32 +02:00
self . _opts , args = getopt . getopt ( self . argv [ 1 : ] , optlist [ 0 ] , optlist [ 1 ] )
2020-01-27 18:22:35 +01:00
except getopt . GetoptError as err :
2009-09-03 00:46:11 +02:00
# print help information and exit:
self . usage ( )
2020-01-27 18:22:35 +01:00
print ( str ( err ) ) # will print something like "option -a not recognized"
2009-09-03 00:46:11 +02:00
sys . exit ( 2 )
return self . _opts
opts = property ( fget = opts )
2009-09-02 20:45:53 +02:00
t = """
def do_ $ LONG ( self ) :
2009-09-04 15:11:42 +02:00
if ' _do_$LONG ' not in self . __dict__ :
2009-09-03 00:46:11 +02:00
self . _do_ $ LONG = False
for o , a in self . opts :
if o in ( " -$SHORT " , " --$LONG " ) :
self . _do_ $ LONG = True
break
return self . _do_ $ LONG
do_ $ LONG = property ( fget = do_ $ LONG )
2009-09-02 20:45:53 +02:00
"""
2020-01-27 18:43:22 +01:00
for short_opt in options :
long_opt = options [ short_opt ] [ 0 ]
exec ( t . replace ( " $LONG " , long_opt ) . replace ( " $SHORT " , short_opt ) ) #in locals()
2009-09-02 20:45:53 +02:00
def do_run ( self ) :
2009-09-04 15:11:42 +02:00
if ' _do_run ' not in self . __dict__ :
2009-09-17 10:54:09 +02:00
self . _do_run = not ( \
self . do_version or \
self . do_help or \
self . do_preprocess or \
2010-09-01 15:10:16 +02:00
self . do_touch or \
2009-09-17 10:54:09 +02:00
self . do_init )
2009-09-03 00:46:11 +02:00
return self . _do_run
do_run = property ( fget = do_run )
2009-09-02 20:45:53 +02:00
command_line = CommandLine ( )
2013-07-08 23:40:40 +02:00
def print_options ( ) :
2020-01-27 18:22:35 +01:00
keys = list ( options . keys ( ) )
2013-07-08 23:40:40 +02:00
keys . sort ( )
2014-11-24 09:59:22 +01:00
import subprocess
2013-07-08 23:40:40 +02:00
for k in keys :
description = options [ k ] [ 1 ]
p1 = subprocess . Popen ( [ " fold " , " -s " , " -w " , " 40 " ] , stdout = subprocess . PIPE , stdin = subprocess . PIPE )
description = p1 . communicate ( description ) [ 0 ]
description = description . replace ( ' \n ' , ' \n ' . ljust ( 27 ) )
2020-01-27 18:22:35 +01:00
print ( ( " - %s , -- %s " % ( k , options [ k ] [ 0 ] ) ) . ljust ( 25 ) , description + ' \n ' )
print ( " \n " )
2013-07-08 23:40:40 +02:00
if __name__ == ' __main__ ' :
print_options ( )