2009-09-02 20:45:53 +02:00
#!/usr/bin/python
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
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 [ ' 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 [ ' v ' ] = [ ' version ' , ' Prints version of irpf90 ' , 0 ]
options [ ' a ' ] = [ ' assert ' , ' Activates ASSERT statements. If absent, remove ASSERT statements. ' , 0 ]
2009-09-02 20:45:53 +02:00
options [ ' h ' ] = [ ' help ' , ' Print this help ' , 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 ]
options [ ' D ' ] = [ ' define ' , ' Defines a variable identified by the IRP_IF statements. ' , 1 ]
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 [ ' g ' ] = [ ' profile ' , ' Activates profiling of the code. ' , 0 ]
options [ ' t ' ] = [ ' touch ' , ' Display which entities are touched when touching the variable given as an argument. ' , 1 ]
options [ ' m ' ] = [ ' memory ' , ' Print memory allocations/deallocations. ' , 0 ]
#options['z'] = [ 'openmp' , 'Automatic openMP tasks (may not work)', 0 ]
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 [ ' s ' ] = [ ' substitute ' , ' Substitute values in do loops for generating specific optimized code. ' , 1 ]
options [ ' r ' ] = [ ' no_directives ' , ' Ignore all compiler directives !DEC$ and !DIR$ ' , 0 ]
2011-10-21 09:10:40 +02:00
options [ ' n ' ] = [ ' inline ' , ' all|providers|builders : Force inlining of providers or builders ' , 1 ]
2013-01-21 12:27:44 +01:00
options [ ' u ' ] = [ ' unused ' , ' Print unused providers ' , 0 ]
2013-11-20 17:43:03 +01:00
options [ ' I ' ] = [ ' include ' , ' Include directory ' , 1 ]
2009-09-02 20:45:53 +02:00
class CommandLine ( object ) :
2013-07-09 17:05:56 +02:00
do_openmp = False
2009-09-02 20:45:53 +02:00
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 ] ] :
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 )
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 )
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 )
print t
2013-07-08 23:40:40 +02:00
print_options ( )
2009-09-02 20:45:53 +02:00
print " "
print " Version : " , version
print " "
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 ] )
2009-09-03 00:46:11 +02:00
except getopt . GetoptError , err :
# print help information and exit:
self . usage ( )
print str ( err ) # will print something like "option -a not recognized"
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
"""
2011-04-09 23:45:50 +02:00
for short in options :
2009-09-02 20:45:53 +02:00
long = options [ short ] [ 0 ]
2011-12-19 14:24:52 +01:00
exec t . replace ( " $LONG " , long ) . replace ( " $SHORT " , short ) #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 ( ) :
keys = options . keys ( )
keys . sort ( )
import subprocess , threading
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 ) )
print ( " - %s , -- %s " % ( k , options [ k ] [ 0 ] ) ) . ljust ( 25 ) , description + ' \n '
if __name__ == ' __main__ ' :
print_options ( )