10
0
mirror of https://gitlab.com/scemama/irpf90.git synced 2025-01-03 10:05:40 +01:00

Removed tabs

This commit is contained in:
Anthony Scemama 2017-03-17 09:44:29 +01:00
parent dd2afebb0d
commit ebd4c780fa
14 changed files with 511 additions and 566 deletions

View File

@ -1,21 +1,7 @@
PYTHON=python PYTHON=python
PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])") PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])")
HAS_CYTHON=$(shell bash -c "which cython &> /dev/null && echo 1 || echo 0")
ifneq ($(HAS_CYTHON),0)
../bin/irpf90: irpf90.so
rm ../bin/irpf90 ; cd ../bin ; ln -s ../src/irpf90_python.exe irpf90
irpf90.so : $(wildcard *.py) irpf90.c
./cython_setup.py build_ext --inplace
irpf90.c: irpf90.py
cython --embed irpf90.py
else
../bin/irpf90: irpf90_python.exe ../bin/irpf90: irpf90_python.exe
rm ../bin/irpf90 ; cd ../bin ; ln -s ../src/irpf90_python.exe irpf90 rm ../bin/irpf90 ; cd ../bin ; ln -s ../src/irpf90_python.exe irpf90
endif
clean: clean:
rm -f *.c *.so *.pyc *.pyo 2>/dev/null rm -f *.c *.so *.pyc *.pyo 2>/dev/null

View File

@ -41,7 +41,7 @@ def dress(f, in_root=False):
""" Transfoms the filename into $PWD/IRPF90_temp/f """ Transfoms the filename into $PWD/IRPF90_temp/f
Note: Note:
In root=True resurn $PWD/f In root=True resurn $PWD/f
""" """
pwd = os.getcwd() pwd = os.getcwd()
@ -66,14 +66,14 @@ def create_build_touches(l_irp_m, ninja):
result_ninja = '\n'.join([ result_ninja = '\n'.join([
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}", "build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_modules_irp}",
" short_in = {short_target_F90}", " short_in = {short_target_F90}",
" short_out = {short_target_o}", " short_out = {short_target_o}",
"" ""
]) ])
result_make = '\n'.join([ result_make = '\n'.join([
"{target_o}: {target_F90} | {list_of_modules_irp}", "{target_o}: {target_F90} | {list_of_modules_irp}",
'\t@printf "F: {short_target_F90} -> {short_target_o}\\n"', '\t@printf "F: {short_target_F90} -> {short_target_o}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", "" "\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
]) ])
result = result_ninja if ninja else result_make result = result_ninja if ninja else result_make
@ -97,14 +97,14 @@ def create_build_archive(l_irp_o, l_usr_o_wo_main, l_ext_o, l_irp_sup_o, ninja=T
list_of_object = ' '.join(l_irp_o + l_usr_o_wo_main + l_ext_o + l_irp_sup_o) list_of_object = ' '.join(l_irp_o + l_usr_o_wo_main + l_ext_o + l_irp_sup_o)
result_ninja = '\n'.join([ result_ninja = '\n'.join([
"build {lib}: archive_{irp_id} {list_of_object}", "build {lib}: archive_{irp_id} {list_of_object}",
" short_out = {short_lib}", " short_out = {short_lib}",
""]) ""])
result_make = '\n'.join([ result_make = '\n'.join([
"{lib}: {list_of_object}", "{lib}: {list_of_object}",
'\t@printf "Archive: {short_lib}\\n"', '\t@printf "Archive: {short_lib}\\n"',
"\t@$(AR) cr $@ $^", ""]) "\t@$(AR) cr $@ $^", ""])
result = result_ninja if ninja else result_make result = result_ninja if ninja else result_make
return result.format(**locals()) return result.format(**locals())
@ -114,7 +114,7 @@ def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
# (Module, List[str], List[str]) -> str # (Module, List[str], List[str]) -> str
""" Create the build command who will link the .o file into the target executable """ Create the build command who will link the .o file into the target executable
To link we need the .o file corresponding to the target, and the ar lib. To link we need the .o file corresponding to the target, and the ar lib.
""" """
irp_id = irpf90_t.irp_id irp_id = irpf90_t.irp_id
@ -124,8 +124,8 @@ def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
basename = os.path.basename(filename) basename = os.path.basename(filename)
if basename != progname: if basename != progname:
from util import logger from util import logger
logger.info('program-name `{0}` != file-name `{1}` (using file-name for now...)'.format(progname,basename)) logger.info('program-name `{0}` != file-name `{1}` (using file-name for now...)'.format(progname,basename))
target = dress(filename, in_root=True) target = dress(filename, in_root=True)
short_target = filename short_target = filename
@ -139,12 +139,12 @@ def create_build_link(t, l_irp_m, l_usr_m, l_ext_m, ninja=True):
result_ninja = '\n'.join([ result_ninja = '\n'.join([
"build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}", "build {target}: link_{irp_id} {target_o} {irp_lib} | {list_of_module}",
" short_out = {short_target}", " short_out = {short_target}",
""]) ""])
result_make = '\n'.join([ result_make = '\n'.join([
"{target}:{target_o} {irp_lib} | {list_of_module}", "{target}:{target_o} {irp_lib} | {list_of_module}",
'\t@printf "Link: {short_target}\\n"', '\t@printf "Link: {short_target}\\n"',
"\t@$(FC) $^ $(LIB) -o $@", "\t@$(FC) $^ $(LIB) -o $@",
""]) ""])
result = result_ninja if ninja else result_make result = result_ninja if ninja else result_make
@ -158,8 +158,8 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
- The module can produce a .MOD file - The module can produce a .MOD file
- The module can Need another .MOD file. - The module can Need another .MOD file.
This .MOD file can be produced by: This .MOD file can be produced by:
1) a file generated by IRP_F90 preprocessor. 1) a file generated by IRP_F90 preprocessor.
2) a file defined by the user but a .irp.f90 file. 2) a file defined by the user but a .irp.f90 file.
3) a file not handle at all by IRPF90. 3) a file not handle at all by IRPF90.
@ -186,10 +186,10 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
# Expensive and stupid. We can create a dict to do the loockup only once # Expensive and stupid. We can create a dict to do the loockup only once
for m in t.needed_modules_usr: for m in t.needed_modules_usr:
# m is name # m is name
for x in l_module: for x in l_module:
if m in x.gen_mod and x.filename != t.filename: if m in x.gen_mod and x.filename != t.filename:
needed_modules.append("%s.irp.o" % x.filename) needed_modules.append("%s.irp.o" % x.filename)
from util import uniquify from util import uniquify
needed_modules = uniquify(needed_modules) needed_modules = uniquify(needed_modules)
@ -211,23 +211,23 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
inline_include = True inline_include = True
if not inline_include: if not inline_include:
#Wrong name, this not work! #Wrong name, this not work!
#list_of_includes = ' '.join(map(lambda x: dress(x, in_root=True), t.includes)) #list_of_includes = ' '.join(map(lambda x: dress(x, in_root=True), t.includes))
raise NotImplemented raise NotImplemented
else: else:
#The include have already by included #The include have already by included
list_of_includes = ' ' list_of_includes = ' '
l_build = [ l_build = [
"build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}", "build {target_o}: compile_fortran_{irp_id} {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
" short_in = {short_target_F90}", " short_in = {short_target_F90}",
" short_out = {short_target}", " short_out = {short_target}",
"" ""
] ]
l_build_make = [ l_build_make = [
"{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}", "{target_o}: {target_F90} | {list_of_includes} {list_of_modules} {list_of_modules_irp}",
'\t@printf "F: {short_target_F90} -> {short_target}\\n"', '\t@printf "F: {short_target_F90} -> {short_target}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", "" "\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
] ]
@ -236,14 +236,14 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
l_build += [ l_build += [
"build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ", "build {target_module_o}: compile_fortran_{irp_id} {target_module_F90} | {list_of_includes} {list_of_modules} ",
" short_in = {short_target_module_F90}", " short_in = {short_target_module_F90}",
" short_out = {short_target_module_o}", " short_out = {short_target_module_o}",
"" ""
] ]
l_build_make += [ l_build_make += [
"{target_module_o}: {target_module_F90} | {list_of_includes} {list_of_modules}", "{target_module_o}: {target_module_F90} | {list_of_includes} {list_of_modules}",
'\t@printf "F: {short_target_module_F90} -> {short_target_module_o}\\n"', '\t@printf "F: {short_target_module_F90} -> {short_target_module_o}\\n"',
"\t@$(FC) $(FCFLAGS) -c $^ -o $@", "" "\t@$(FC) $(FCFLAGS) -c $^ -o $@", ""
] ]
l_cur = l_build if ninja else l_build_make l_cur = l_build if ninja else l_build_make
@ -285,95 +285,95 @@ def create_makefile(d_flags,d_var,irpf90_flags,ninja=True):
result = ["IRPF90= irpf90", result = ["IRPF90= irpf90",
"IRPF90FLAGS= %s" % irpf90_flags, "IRPF90FLAGS= %s" % irpf90_flags,
"BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'), "BUILD_SYSTEM= %s" % ('ninja' if ninja else 'make'),
""] ""]
# Export all the env variable used by irpf90 # Export all the env variable used by irpf90
result += ['.EXPORT_ALL_VARIABLES:', result += ['.EXPORT_ALL_VARIABLES:',
'', '',
'\n'.join("{0} = {1}".format(k, v) for k, v in sorted(d_flags.iteritems())), '\n'.join("{0} = {1}".format(k, v) for k, v in sorted(d_flags.iteritems())),
'', '',
'\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())), '\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())),
''] '']
result += [ r'# Dark magic below modify with caution!', result += [ r'# Dark magic below modify with caution!',
r'# "You are Not Expected to Understand This"', r'# "You are Not Expected to Understand This"',
r"# .", r"# .",
r"# /^\ .", r"# /^\ .",
r'# /\ "V",', r'# /\ "V",',
r"# /__\ I O o", r"# /__\ I O o",
r"# //..\\ I .", r"# //..\\ I .",
r"# \].`[/ I", r"# \].`[/ I",
r"# /l\/j\ (] . O", r"# /l\/j\ (] . O",
r"# /. ~~ ,\/I .", r"# /. ~~ ,\/I .",
r"# \\L__j^\/I o", r"# \\L__j^\/I o",
r"# \/--v} I o .", r"# \/--v} I o .",
r"# | | I _________", r"# | | I _________",
r"# | | I c(` ')o", r"# | | I c(` ')o",
r"# | l I \. ,/", r"# | l I \. ,/",
r"# _/j L l\_! _//^---^\\_", r"# _/j L l\_! _//^---^\\_",
r""] r""]
result += ["", result += ["",
"ifeq ($(BUILD_SYSTEM),ninja)", "ifeq ($(BUILD_SYSTEM),ninja)",
"\tBUILD_FILE=IRPF90_temp/build.ninja", "\tBUILD_FILE=IRPF90_temp/build.ninja",
"\tIRPF90FLAGS += -j", "\tIRPF90FLAGS += -j",
"else ifeq ($(BUILD_SYSTEM),make)", "else ifeq ($(BUILD_SYSTEM),make)",
"\tBUILD_FILE=IRPF90_temp/build.make", "\tBUILD_FILE=IRPF90_temp/build.make",
"\tBUILD_SYSTEM += -j", "\tBUILD_SYSTEM += -j",
"else", "else",
"DUMMY:", "DUMMY:",
"\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')", "\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')",
"endif"] "endif"]
result += ["", result += ["",
"define run_and_touch", "define run_and_touch",
" $(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)", " $(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)",
"endef", "endef",
"", "",
"EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)", "EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)",
"", "",
".PHONY: all", ".PHONY: all",
"", "",
"all: $(BUILD_FILE)", "all: $(BUILD_FILE)",
"\t$(call run_and_touch, $<, $(EXE))", "\t$(call run_and_touch, $<, $(EXE))",
"", "",
".NOTPARALLEL: $(EXE)", ".NOTPARALLEL: $(EXE)",
"$(EXE): $(BUILD_FILE)", "$(EXE): $(BUILD_FILE)",
"\t$(call run_and_touch, $<, $(EXE))", "\t$(call run_and_touch, $<, $(EXE))",
"$(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print)", "$(BUILD_FILE): $(shell find . -maxdepth 2 -path ./IRPF90_temp -prune -o -name '*.irp.f' -print)",
"\t$(IRPF90) $(IRPF90FLAGS)", "\t$(IRPF90) $(IRPF90FLAGS)",
"", "",
"clean:", "clean:",
'\trm -f -- $(BUILD_FILE) $(EXE)' '\trm -f -- $(BUILD_FILE) $(EXE)'
'\t$(shell find IRPF90_temp -type f \\( -name "*.o" -o -name "*.mod" -name "*.a" \\) -delete;)', '\t$(shell find IRPF90_temp -type f \\( -name "*.o" -o -name "*.mod" -name "*.a" \\) -delete;)',
"veryclean: clean", "veryclean: clean",
"\trm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags"] "\trm -rf IRPF90_temp/ IRPF90_man/ irpf90_entities dist tags"]
import util import util
data = '%s\n' % '\n'.join(result) data = '%s\n' % '\n'.join(result)
util.lazy_write_file('Makefile',data,conservative=True) util.lazy_write_file('Makefile',data,conservative=True)
def create_make_all_clean(l_main): def create_make_all_clean(l_main):
# #
'''Create the ALL and CLEAN target of Makefile '''Create the ALL and CLEAN target of Makefile
Note: Portability doesn't mater. -delete is maybe not posix Note: Portability doesn't mater. -delete is maybe not posix
but -exec rm {} + is far more ugly! but -exec rm {} + is far more ugly!
''' '''
l_executable =' '.join(dress( t.filename, in_root=True) for t in l_main) l_executable =' '.join(dress( t.filename, in_root=True) for t in l_main)
output = [".PHONY : all", output = [".PHONY : all",
"all: {l_executable}", "all: {l_executable}",
"", "",
".PHONY: clean", ".PHONY: clean",
"clean:", "clean:",
'\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --' '\tfind . -type f \( -name "*.o" -o -name "*.mod" \) -delete; rm -f {l_executable} --'
""] ""]
return [ '\n'.join(output).format(**locals())] return [ '\n'.join(output).format(**locals())]
def create_var_and_rule(d_flags, ninja): def create_var_and_rule(d_flags, ninja):
@ -385,7 +385,7 @@ def create_var_and_rule(d_flags, ninja):
# Rules # Rules
t = [ t = [
"rule compile_fortran_{irp_id}", "rule compile_fortran_{irp_id}",
" command = $FC $FCFLAGS -c $in -o $out", " command = $FC $FCFLAGS -c $in -o $out",
" description = F : $short_in -> $short_out", " description = F : $short_in -> $short_out",
"", "",
"rule compile_c_{irp_id}", "rule compile_c_{irp_id}",
@ -399,7 +399,7 @@ def create_var_and_rule(d_flags, ninja):
"rule archive_{irp_id}", "rule archive_{irp_id}",
" command = $AR cr $out $in", " command = $AR cr $out $in",
" description = Archive: $short_out", " description = Archive: $short_out",
"", "",
"rule link_{irp_id}", "rule link_{irp_id}",
" command = $FC $FCFLAGS $in $LIB -o $out", " command = $FC $FCFLAGS $in $LIB -o $out",
" description = Link: $short_out", " description = Link: $short_out",
@ -422,7 +422,7 @@ d_default = {
"CFLAGS": "-O2", "CFLAGS": "-O2",
"CXX": "g++", "CXX": "g++",
"CXXFLAGS": "-O2", "CXXFLAGS": "-O2",
"LIB": ""} "LIB": ""}
d_flags = dict() d_flags = dict()
for k, v in d_default.iteritems(): for k, v in d_default.iteritems():
@ -436,15 +436,15 @@ for k in ['SRC', 'OBJ']:
def create_generalmakefile(ninja): def create_generalmakefile(ninja):
create_makefile(d_flags,d_var, include_dir,ninja) create_makefile(d_flags,d_var, include_dir,ninja)
def run(d_module, ninja): def run(d_module, ninja):
#(Dict[str,Module],bool) -> str #(Dict[str,Module],bool) -> str
"""Wrote the ninja file needed to compile the program """Wrote the ninja file needed to compile the program
Note: Note:
- FC,AR,CC,CXX,LIB, FCFLAGS, CFLAGS, CXXFLAGS are compiler enviroment read - FC,AR,CC,CXX,LIB, FCFLAGS, CFLAGS, CXXFLAGS are compiler enviroment read
- SRC,OBJ: Are the not irp.f file defined by the user - SRC,OBJ: Are the not irp.f file defined by the user
""" """
# Add required flags # Add required flags
@ -510,7 +510,7 @@ def run(d_module, ninja):
output = create_var_and_rule(d_flags, ninja) output = create_var_and_rule(d_flags, ninja)
if not ninja: if not ninja:
output += create_make_all_clean(l_mod_main) output += create_make_all_clean(l_mod_main)
# Create all the .irp.F90 -> .o # Create all the .irp.F90 -> .o
for m in l_mod: for m in l_mod:

View File

@ -168,7 +168,7 @@ def run(d_entity, d_routine):
def worker(l): def worker(l):
filename, text = l filename, text = l
lazy_write_file(filename, text) lazy_write_file(filename, text)
parmap(worker, l_data_to_write) parmap(worker, l_data_to_write)

View File

@ -1,41 +0,0 @@
#!/usr/bin/env python
# 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
# scemama@irsamc.ups-tlse.fr
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import os
to_remove = """__init__.py cython_setup.py version.py command_line.py""".split()
ext_modules = []
for f in os.listdir('.') if f.emswith(".py") and not f in to_remove:
module = f.split('.')[0]
ext_modules.append(Extension(module,list(f)))
setup(name = 'IRPF90 extensions',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules)

View File

@ -42,15 +42,15 @@ class Entity(object):
############################################################ ############################################################
def __init__(self, text, label, name=None, comm_world=None): def __init__(self, text, label, name=None, comm_world=None):
# (list[str], str, int, Irpy_comm_world) # (list[str], str, int, Irpy_comm_world)
'''Instantiate the object. '''Instantiate the object.
Args: Args:
text: List of lines between BEGIN_PROVIDER and END_PROVIDER included text: List of lines between BEGIN_PROVIDER and END_PROVIDER included
int: An unique int id (usefull when profilling) int: An unique int id (usefull when profilling)
name: The name of the provider defined after the chosen BEGIN_PROVIDER statement name: The name of the provider defined after the chosen BEGIN_PROVIDER statement
comm_world: A object to communicate we the external world. comm_world: A object to communicate we the external world.
''' '''
assert type(text) == list assert type(text) == list
assert len(text) > 0 assert len(text) > 0
@ -59,7 +59,7 @@ class Entity(object):
self.label = label self.label = label
self.text = text self.text = text
self.same_as = text[0].filename[1] self.same_as = text[0].filename[1]
self.name = name if name else self.same_as self.name = name if name else self.same_as
self.comm_world = comm_world self.comm_world = comm_world
@ -70,27 +70,27 @@ class Entity(object):
# ~ # ~ # ~ # ~ # ~ # ~
@irpy.lazy_property @irpy.lazy_property
def d_entity(self): def d_entity(self):
# () -> Dict[str,Entity] # () -> Dict[str,Entity]
'''Create an alias to the global dictionary of Entity. '''Create an alias to the global dictionary of Entity.
Note: Be aware of the possiblity of Cyclic Dependency. Note: Be aware of the possiblity of Cyclic Dependency.
''' '''
return self.comm_world.d_entity return self.comm_world.d_entity
@irpy.lazy_property @irpy.lazy_property
def cm_t_filename_parsed_text(self): def cm_t_filename_parsed_text(self):
# () -> Tuple[str, Parsed_text] # () -> Tuple[str, Parsed_text]
'''Create an alias to the global tuple for parsed text '''Create an alias to the global tuple for parsed text
Note: self.comm_world.t_filename_parsed_text need d_entity. Note: self.comm_world.t_filename_parsed_text need d_entity.
Be aware of the possibility of Cyclic Dependency Be aware of the possibility of Cyclic Dependency
''' '''
return self.comm_world.t_filename_parsed_text return self.comm_world.t_filename_parsed_text
@irpy.lazy_property @irpy.lazy_property
def d_type_lines(self): def d_type_lines(self):
# () -> Dict[Line, Tuple[int,Line] ] # () -> Dict[Line, Tuple[int,Line] ]
'''Contruct a mapping table between the type of the line and the possition''' '''Contruct a mapping table between the type of the line and the possition'''
from collections import defaultdict from collections import defaultdict
d = defaultdict(list) d = defaultdict(list)
for i, line in enumerate(self.text): for i, line in enumerate(self.text):
@ -103,45 +103,45 @@ class Entity(object):
# ~ # ~ # ~ # ~ # ~ # ~
@irpy.lazy_property @irpy.lazy_property
def is_main(self): def is_main(self):
# () -> bool # () -> bool
'''Check if this Entity is the main one '''Check if this Entity is the main one
Exemple: Exemple:
BEGIN_PROVIDER [pi, double precision] & BEGIN_PROVIDER [pi, double precision] &
BEGIN_PROVIDER [e, double preision] BEGIN_PROVIDER [e, double preision]
return True for 'pi' and False for 'e' return True for 'pi' and False for 'e'
''' '''
return self.name == self.same_as return self.name == self.same_as
@irpy.lazy_property @irpy.lazy_property
def prototype(self): def prototype(self):
# () -> Line # () -> Line
'''Find the declaration statement associated with the name of the provider '''Find the declaration statement associated with the name of the provider
Exemple: Exemple:
BEGIN_PROVIDER [pi, double precision] & BEGIN_PROVIDER [pi, double precision] &
BEGIN_PROVIDER [e, double preision] BEGIN_PROVIDER [e, double preision]
if self.name == e, will return BEGIN_PROVIDER [e, double preision] if self.name == e, will return BEGIN_PROVIDER [e, double preision]
''' '''
d = self.d_type_lines d = self.d_type_lines
return next(line for _,line in d[Begin_provider]+d[Cont_provider] if line.filename[1] == self.name) return next(line for _,line in d[Begin_provider]+d[Cont_provider] if line.filename[1] == self.name)
@irpy.lazy_property @irpy.lazy_property
def others_entity_name(self): def others_entity_name(self):
# () -> List[str] # () -> List[str]
'''Extract the other entity-name defined''' '''Extract the other entity-name defined'''
d = self.d_type_lines d = self.d_type_lines
return [line.filename[1] for _,line in d[Begin_provider]+d[Cont_provider] if not line.filename[1] == self.name] return [line.filename[1] for _,line in d[Begin_provider]+d[Cont_provider] if not line.filename[1] == self.name]
@irpy.lazy_property @irpy.lazy_property
def doc(self): def doc(self):
# () -> List[str] # () -> List[str]
doc = [line.text.lstrip()[1:] for _,line in self.d_type_lines[Doc]] doc = [line.text.lstrip()[1:] for _,line in self.d_type_lines[Doc]]
if not doc: if not doc:
logger.warning("Entity '%s' is not documented" % (self.name)) logger.warning("Entity '%s' is not documented" % (self.name))
@ -149,7 +149,7 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def documented(self): def documented(self):
#() -> bool #() -> bool
return bool(self.doc) return bool(self.doc)
# ~ # ~ # ~ # ~ # ~ # ~
@ -158,8 +158,8 @@ class Entity(object):
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def is_written(self): def is_written(self):
#() -> bool #() -> bool
'''Check if it will be written on disk''' '''Check if it will be written on disk'''
return any(self.d_entity[i].is_written for i in self.parents) return any(self.d_entity[i].is_written for i in self.parents)
@irpy.lazy_property @irpy.lazy_property
@ -205,7 +205,7 @@ class Entity(object):
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def is_read(self): def is_read(self):
'''Check if it will be read from disk''' '''Check if it will be read from disk'''
return any(self.d_entity[i].is_read for i in self.parents) return any(self.d_entity[i].is_read for i in self.parents)
@irpy.lazy_property @irpy.lazy_property
@ -258,7 +258,7 @@ class Entity(object):
if self.is_self_touched or any(self.d_entity[i].is_touched for i in self.children): if self.is_self_touched or any(self.d_entity[i].is_touched for i in self.children):
return True return True
return False return False
# ~ # ~ # ~ # ~ # ~ # ~
# INCLUDE, USE, CALL # INCLUDE, USE, CALL
@ -266,8 +266,8 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def includes(self): def includes(self):
# () -> str # () -> str
'''Extract the name of include who need be to be include in this Entity''' '''Extract the name of include who need be to be include in this Entity'''
return [line.filename for _,line in self.d_type_lines[Include]] return [line.filename for _,line in self.d_type_lines[Include]]
@irpy.lazy_property @irpy.lazy_property
@ -277,12 +277,12 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def calls(self): def calls(self):
'''Extract the name ofthe function called by the entity''' '''Extract the name ofthe function called by the entity'''
def extract_name(line): def extract_name(line):
return line.text.split('(', 1)[0].split()[1].lower() return line.text.split('(', 1)[0].split()[1].lower()
return [extract_name(line) for _,line in self.d_type_lines[Call] ] return [extract_name(line) for _,line in self.d_type_lines[Call] ]
# ~ # ~ # ~ # ~ # ~ # ~
# Array Dimension # Array Dimension
@ -290,19 +290,19 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def dim(self): def dim(self):
# () -> List[str] # () -> List[str]
'''Extract the dimension of the needed array in a form of list of variable name '''Extract the dimension of the needed array in a form of list of variable name
Exemple: Exemple:
BEGIN_PROVIDER [real, ao_num ] BEGIN_PROVIDER [real, ao_num ]
-> [] -> []
BEGIN_PROVIDER [ real, ao_oneD_p, (ao_num) ] BEGIN_PROVIDER [ real, ao_oneD_p, (ao_num) ]
-> ['ao_num'] -> ['ao_num']
BEGIN_PROVIDER [ real, ao_oneD_prim_p, (ao_num,ao_prim_num_max) ] BEGIN_PROVIDER [ real, ao_oneD_prim_p, (ao_num,ao_prim_num_max) ]
-> ['ao_num', 'ao_prim_num_max'] -> ['ao_num', 'ao_prim_num_max']
''' '''
line = self.prototype.text.split('!')[0] line = self.prototype.text.split('!')[0]
buffer = line.replace(']', '').split(',', 2) buffer = line.replace(']', '').split(',', 2)
@ -331,24 +331,24 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def type(self): def type(self):
# () -> str # () -> str
'''Compute the fortran type code of the entity''' '''Compute the fortran type code of the entity'''
type_ = self.prototype.text.split(',')[0].split('[')[1].strip() type_ = self.prototype.text.split(',')[0].split('[')[1].strip()
if not type_: if not type_:
logger.error( "Error in definition of %s." % (self.name)) logger.error( "Error in definition of %s." % (self.name))
sys.exit(1) sys.exit(1)
if self.dim: if self.dim:
return "%s, allocatable" % (type_) return "%s, allocatable" % (type_)
else: else:
return type_ return type_
@irpy.lazy_property @irpy.lazy_property
def header(self): def header(self):
# () -> List[str] # () -> List[str]
'''Compute all the code needed to inistanticant the entity''' '''Compute all the code needed to inistanticant the entity'''
name = self.name name = self.name
@ -360,7 +360,7 @@ class Entity(object):
else: else:
str_ += " [:]" str_ += " [:]"
l = [str_] l = [str_]
if self.dim and command_line.align != '1': if self.dim and command_line.align != '1':
l += [" !DIR$ ATTRIBUTES ALIGN: %s :: %s" % (command_line.align, name)] l += [" !DIR$ ATTRIBUTES ALIGN: %s :: %s" % (command_line.align, name)]
@ -374,16 +374,16 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def fmodule(self): def fmodule(self):
# () -> str # () -> str
'''Contruct the name of the module who will contain the entity''' '''Contruct the name of the module who will contain the entity'''
name = self.prototype.filename[0].replace('/', '__').split('.irp.f')[0] name = self.prototype.filename[0].replace('/', '__').split('.irp.f')[0]
return '%s_mod' % name return '%s_mod' % name
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
def regexp(self): def regexp(self):
# () -> Regex # () -> Regex
'''Compile a regex targeted to 'search' the name of this entity''' '''Compile a regex targeted to 'search' the name of this entity'''
import re import re
return re.compile(r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)" % (self.name), re.I).search return re.compile(r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)" % (self.name), re.I).search
# ~ # ~ # ~ # ~ # ~ # ~
@ -392,10 +392,10 @@ class Entity(object):
@irpy.lazy_property @irpy.lazy_property
def toucher(self): def toucher(self):
# () -> List[str] # () -> List[str]
'''Fabric the f90 routine who handle the cache invalidation''' '''Fabric the f90 routine who handle the cache invalidation'''
# Only one by EntityColleciton # Only one by EntityColleciton
if not self.is_main: if not self.is_main:
return [] return []
@ -465,20 +465,20 @@ class Entity(object):
########################################################## ##########################################################
@irpy.lazy_property @irpy.lazy_property
def free(self): def free(self):
# () -> List[ str ] # () -> List[ str ]
'''Compute an part of a subroutine used to free a variable''' '''Compute an part of a subroutine used to free a variable'''
name = self.name name = self.name
result = ["!", result = ["!",
"! >>> FREE %s" % (name), "! >>> FREE %s" % (name),
" %s_is_built = .False." % (self.same_as)] " %s_is_built = .False." % (self.same_as)]
if self.dim: if self.dim:
result += [ result += [
" if (allocated(%s)) then"%(name), " if (allocated(%s)) then"%(name),
" deallocate (%s)"%(name)] " deallocate (%s)"%(name)]
if command_line.do_memory: if command_line.do_memory:
result += " print *, 'Deallocating %s'"%(name) result += " print *, 'Deallocating %s'"%(name)
result += [" endif"] result += [" endif"]
@ -488,8 +488,8 @@ class Entity(object):
########################################################## ##########################################################
@irpy.lazy_property @irpy.lazy_property
def provider(self): def provider(self):
# () -> List[str] # () -> List[str]
'''Create the fortran90 code for the EntityCollection''' '''Create the fortran90 code for the EntityCollection'''
if not self.is_main: if not self.is_main:
return [] return []
@ -498,15 +498,15 @@ class Entity(object):
same_as = self.same_as same_as = self.same_as
def dimsize(x): def dimsize(x):
# (str) -> str # (str) -> str
'''Compute the number of element in the array''' '''Compute the number of element in the array'''
try: try:
b0, b1 = x.split(':') b0, b1 = x.split(':')
except ValueError: except ValueError:
return x return x
b0_is_digit = b0.replace('-', '').isdigit() b0_is_digit = b0.replace('-', '').isdigit()
b1_is_digit = b1.replace('-', '').isdigit() b1_is_digit = b1.replace('-', '').isdigit()
if b0_is_digit and b1_is_digit: if b0_is_digit and b1_is_digit:
@ -669,7 +669,7 @@ class Entity(object):
import parsed_text import parsed_text
# Move the variable to top, and add the text # Move the variable to top, and add the text
parsed_text.move_to_top_list(text, [Declaration, Implicit, Use]) parsed_text.move_to_top_list(text, [Declaration, Implicit, Use])
result.extend( line.text for _,line in text if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider))) result.extend( line.text for _,line in text if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider)))

View File

@ -41,36 +41,36 @@ def main():
if command_line.do_help: if command_line.do_help:
command_line.usage() command_line.usage()
return return
if command_line.do_version: if command_line.do_version:
from version import version from version import version
print version print version
return return
if command_line.do_init: if command_line.do_init:
from build_file import create_generalmakefile from build_file import create_generalmakefile
create_generalmakefile(command_line.do_ninja) create_generalmakefile(command_line.do_ninja)
return return
comm_world = Irpy_comm_world() comm_world = Irpy_comm_world()
if command_line.do_graph: if command_line.do_graph:
comm_world.t_filename_parsed_text # Initialize entity need. Dirty I know. comm_world.t_filename_parsed_text # Initialize entity need. Dirty I know.
print 'graph { ' print 'graph { '
for name,entity in comm_world.d_entity.items(): for name,entity in comm_world.d_entity.items():
if entity.needs: if entity.needs:
print ' {0} -> {1}'.format(name, ' '.join(entity.needs)) print ' {0} -> {1}'.format(name, ' '.join(entity.needs))
print '}' print '}'
return return
if command_line.do_preprocess: if command_line.do_preprocess:
for filename, text in comm_world.preprocessed_text: for filename, text in comm_world.preprocessed_text:
if filename in command_line.preprocessed: if filename in command_line.preprocessed:
for line in text: for line in text:
print line.text print line.text
return return
if command_line.do_touch: if command_line.do_touch:
for var in command_line.touched: for var in command_line.touched:
@ -80,7 +80,7 @@ def main():
print "Touching %s invalidates the following entities:" % var print "Touching %s invalidates the following entities:" % var
for x in sorted(d_entity[var].parents): for x in sorted(d_entity[var].parents):
print "- %s" % (x, ) print "- %s" % (x, )
return return
if command_line.do_codelet: if command_line.do_codelet:
import profile import profile
@ -102,7 +102,7 @@ def main():
profile.run(comm_world.d_entity) profile.run(comm_world.d_entity)
if command_line.do_openmp: if command_line.do_openmp:
comm_world.create_lock() comm_world.create_lock()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -63,9 +63,9 @@ class LineWithName(Line):
l_name = l_buf[0].split() l_name = l_buf[0].split()
if len(l_name) < 2: if len(l_name) < 2:
import loger import loger
logger.error("Syntax Error: %s" % line) logger.error("Syntax Error: %s" % line)
sys.exit(1) sys.exit(1)
return l_name.pop() return l_name.pop()
l_type = [ l_type = [

View File

@ -29,12 +29,12 @@ import os
import sys import sys
if __name__ == "__main__": if __name__ == "__main__":
from irpf90_t import mandir from irpf90_t import mandir
entity = sys.argv[1].lower() entity = sys.argv[1].lower()
filename = '%s.l'% entity filename = '%s.l'% entity
if filename not in os.listdir(mandir): if filename not in os.listdir(mandir):
print "Error: `%s` does not exist"% entity print "Error: `%s` does not exist"% entity
sys.exit(-1) sys.exit(-1)
os.system("man %s" % os.path.join(mandir,filename)) os.system("man %s" % os.path.join(mandir,filename))

View File

@ -18,43 +18,43 @@ class Irpy_comm_world(object):
'''Maestro.''' '''Maestro.'''
def __init__(self,l_dir=None, l_file=None): def __init__(self,l_dir=None, l_file=None):
# (Iter, Iter) -> None # (Iter, Iter) -> None
# Create directories # Create directories
from itertools import ifilterfalse from itertools import ifilterfalse
i_folder = ifilterfalse(os.path.exists, (irpf90_t.irpdir, irpf90_t.mandir)) i_folder = ifilterfalse(os.path.exists, (irpf90_t.irpdir, irpf90_t.mandir))
map(os.mkdir,i_folder) map(os.mkdir,i_folder)
# List file # List file
l_dir =l_dir if l_dir else (command_line.include_dir+['.']) l_dir =l_dir if l_dir else (command_line.include_dir+['.'])
l_not_dir = [d for d in l_dir if not (os.path.exists(d) and os.path.isdir(d))] l_not_dir = [d for d in l_dir if not (os.path.exists(d) and os.path.isdir(d))]
if l_not_dir: if l_not_dir:
logger.error('Try to include no existing directory: [%s]' % ','.join(l_not_dir)) logger.error('Try to include no existing directory: [%s]' % ','.join(l_not_dir))
sys.exit(1) sys.exit(1)
# Create folder in IRPDIR # Create folder in IRPDIR
i_folder = ifilterfalse(os.path.exists, (os.path.join(irpf90_t.irpdir,d) for d in l_dir)) i_folder = ifilterfalse(os.path.exists, (os.path.join(irpf90_t.irpdir,d) for d in l_dir))
map(os.mkdir, i_folder) map(os.mkdir, i_folder)
s_folder_abs = set(os.path.abspath(path) for path in l_dir) s_folder_abs = set(os.path.abspath(path) for path in l_dir)
s_file_folder_all = set(flatten(listdir(path,abspath=True) for path in s_folder_abs)) s_file_folder_all = set(flatten(listdir(path,abspath=True) for path in s_folder_abs))
# Take everything! # Take everything!
s_file_folder = filter(lambda f: os.path.isfile(f) and not f.startswith("."), s_file_folder_all) s_file_folder = filter(lambda f: os.path.isfile(f) and not f.startswith("."), s_file_folder_all)
s_file_tot = set(l_file) if l_file else set() s_file_tot = set(l_file) if l_file else set()
s_file_tot.update(s_file_folder) s_file_tot.update(s_file_folder)
s_file_rel = set(os.path.relpath(f,self.cwd) for f in s_file_tot) s_file_rel = set(os.path.relpath(f,self.cwd) for f in s_file_tot)
# Lazy Copy file # Lazy Copy file
for f in s_file_rel: for f in s_file_rel:
src = os.path.join(self.cwd,f) src = os.path.join(self.cwd,f)
text_ref = open(src, 'rb').read() text_ref = open(src, 'rb').read()
dest = os.path.join(self.cwd,irpf90_t.irpdir, f) dest = os.path.join(self.cwd,irpf90_t.irpdir, f)
@ -63,16 +63,16 @@ class Irpy_comm_world(object):
if command_line.do_codelet: if command_line.do_codelet:
s_file_tot.update(command_line.codelet[3]) s_file_tot.update(command_line.codelet[3])
# No filter the irpf90 file # No filter the irpf90 file
self.irpf90_files_ordered=sorted(filter(lambda f: f.endswith(".irp.f") ,s_file_rel)) self.irpf90_files_ordered=sorted(filter(lambda f: f.endswith(".irp.f") ,s_file_rel))
@irpy.lazy_property @irpy.lazy_property
def cwd(self): def cwd(self):
return os.getcwd() return os.getcwd()
@irpy.lazy_property @irpy.lazy_property
def t_filename_preprocessed_text(self): def t_filename_preprocessed_text(self):
'''Tuple (filename, preprocessed_text)''' '''Tuple (filename, preprocessed_text)'''
from preprocessed_text import Preprocess_text from preprocessed_text import Preprocess_text
def worker_preprocess(filename): def worker_preprocess(filename):
@ -82,8 +82,8 @@ class Irpy_comm_world(object):
@irpy.lazy_property @irpy.lazy_property
def l_preprocessed_text(self): def l_preprocessed_text(self):
# (None) -> List[Line] # (None) -> List[Line]
'''List preprocessed_text''' '''List preprocessed_text'''
return [line for _, text in self.t_filename_preprocessed_text for line in text] return [line for _, text in self.t_filename_preprocessed_text for line in text]
@ -98,7 +98,7 @@ class Irpy_comm_world(object):
@irpy.lazy_property @irpy.lazy_property
def d_entity(self): def d_entity(self):
# None -> Dict[Str,Entity] # None -> Dict[Str,Entity]
'''And entity is a collection of line between BEGIN_PROVIDER and END_PROVIDER ''' '''And entity is a collection of line between BEGIN_PROVIDER and END_PROVIDER '''
from irpf90_t import Begin_provider, End_provider from irpf90_t import Begin_provider, End_provider
from entity import Entity from entity import Entity
@ -108,26 +108,26 @@ class Irpy_comm_world(object):
l_provider = [ self.l_preprocessed_text[begin:end] for begin, end in zip(l_begin, l_end)] l_provider = [ self.l_preprocessed_text[begin:end] for begin, end in zip(l_begin, l_end)]
l_ent = [] l_ent = []
for icount, buf in enumerate(l_provider): for icount, buf in enumerate(l_provider):
from functools import partial from functools import partial
Ent_part = partial(Entity,buf,icount,comm_world=self) Ent_part = partial(Entity,buf,icount,comm_world=self)
ent = Ent_part() ent = Ent_part()
l_ent += [ent] + [Ent_part(other) for other in ent.others_entity_name] l_ent += [ent] + [Ent_part(other) for other in ent.others_entity_name]
# O(2) but who care # O(2) but who care
l_duplicate = [x for x in l_ent if l_ent.count(x) > 1] l_duplicate = [x for x in l_ent if l_ent.count(x) > 1]
if l_duplicate: if l_duplicate:
from util import logger from util import logger
logger.error('You have duplicate PROVIDER: %s' % ' '.join([e.name for e in l_duplicate])) logger.error('You have duplicate PROVIDER: %s' % ' '.join([e.name for e in l_duplicate]))
import sys import sys
sys.exit(1) sys.exit(1)
# Python 2.6 Don't allow list comprehesion # Python 2.6 Don't allow list comprehesion
d_ent = dict() d_ent = dict()
for e in l_ent: for e in l_ent:
d_ent[e.name] = e d_ent[e.name] = e
# #
# Second pass # Second pass
@ -145,7 +145,7 @@ class Irpy_comm_world(object):
return l_var return l_var
d_modif = dict() d_modif = dict()
from irpf90_t import Touch, SoftTouch, Free from irpf90_t import Touch, SoftTouch, Free
from util import flatten from util import flatten
for cmd, l_type in [('is_self_touched', [Touch, SoftTouch]), for cmd, l_type in [('is_self_touched', [Touch, SoftTouch]),
@ -181,12 +181,12 @@ class Irpy_comm_world(object):
# ~#~#~#~#~# # ~#~#~#~#~#
from irpf90_t import Subroutine, Function, Program, End from irpf90_t import Subroutine, Function, Program, End
d_type = self.d_type_lines d_type = self.d_type_lines
l_begin = sorted(i for type_ in (Subroutine, Function, Program) for i, _ in d_type[type_]) l_begin = sorted(i for type_ in (Subroutine, Function, Program) for i, _ in d_type[type_])
l_end = [i for i, _ in d_type[End]] l_end = [i for i, _ in d_type[End]]
from routine import Routine from routine import Routine
text = self.l_preprocessed_text text = self.l_preprocessed_text
l_rou = [ Routine(text[b:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b], Program)] l_rou = [ Routine(text[b:e]) for b, e in zip(l_begin, l_end) if not isinstance(text[b], Program)]
# Now we can create a dict and at it # Now we can create a dict and at it
@ -207,27 +207,27 @@ class Irpy_comm_world(object):
for x in entity.calls: for x in entity.calls:
d_called_by[x].add(name) d_called_by[x].add(name)
from util import uniquify from util import uniquify
for routine in d_rou.values(): for routine in d_rou.values():
for x in routine.calls: for x in routine.calls:
d_called_by[x].add(routine.name) d_called_by[x].add(routine.name)
for routine in d_rou.values(): for routine in d_rou.values():
routine.called_by = sorted(d_called_by[routine.name]) routine.called_by = sorted(d_called_by[routine.name])
l_set = [d_rou[name].touches_my_self for name in routine.calls if name in d_rou] l_set = [d_rou[name].touches_my_self for name in routine.calls if name in d_rou]
routine.touches_ancestor = set().union(*l_set) routine.touches_ancestor = set().union(*l_set)
return d_rou return d_rou
@irpy.lazy_property @irpy.lazy_property
def t_filename_parsed_text(self): def t_filename_parsed_text(self):
'''(filename,parsed_text)''' '''(filename,parsed_text)'''
d_entity = self.d_entity d_entity = self.d_entity
d_routine = self.d_routine d_routine = self.d_routine
import parsed_text import parsed_text
vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()] vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()]
def worker_parsed(filename_text): def worker_parsed(filename_text):
filename, text = filename_text filename, text = filename_text
return parsed_text.get_parsed_text(filename, text, d_entity, d_routine, vtuple) return parsed_text.get_parsed_text(filename, text, d_entity, d_routine, vtuple)
@ -235,11 +235,11 @@ class Irpy_comm_world(object):
parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text) parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text)
from irpf90_t import NoDep,Declaration,Implicit,Use,Cont_provider from irpf90_t import NoDep,Declaration,Implicit,Use,Cont_provider
def moved_to_top_l(ptext): def moved_to_top_l(ptext):
l = [NoDep, Declaration, Implicit, Use, Cont_provider] l = [NoDep, Declaration, Implicit, Use, Cont_provider]
for _, text in ptext: for _, text in ptext:
parsed_text.move_to_top_list(text, l) parsed_text.move_to_top_list(text, l)
#Touch routine #Touch routine
parsed_text.build_sub_needs(parsed_text_0, d_routine) parsed_text.build_sub_needs(parsed_text_0, d_routine)
@ -248,13 +248,13 @@ class Irpy_comm_world(object):
parsed_text_1 = parsed_text.add_subroutine_needs(parsed_text_0, d_routine) parsed_text_1 = parsed_text.add_subroutine_needs(parsed_text_0, d_routine)
parsed_text_1 = parsed_text.move_variables(parsed_text_1) parsed_text_1 = parsed_text.move_variables(parsed_text_1)
moved_to_top_l(parsed_text_1) moved_to_top_l(parsed_text_1)
parsed_text.check_opt(parsed_text_1) parsed_text.check_opt(parsed_text_1)
parsed_text_1 = parsed_text.perform_loop_substitutions(parsed_text_1) parsed_text_1 = parsed_text.perform_loop_substitutions(parsed_text_1)
#touch entity #touch entity
stuple = [(s, v.regexp) for s, v in d_routine.iteritems() if v.is_function] stuple = [(s, v.regexp) for s, v in d_routine.iteritems() if v.is_function]
parsed_text.build_needs(parsed_text_1, d_routine, stuple,d_entity) parsed_text.build_needs(parsed_text_1, d_routine, stuple,d_entity)
return parsed_text_1 return parsed_text_1
@ -277,7 +277,7 @@ class Irpy_comm_world(object):
# Module data # Module data
if m.has_irp_module: if m.has_irp_module:
filename = os.path.join(irpdir, '%s.irp.module.F90' % m.filename) filename = os.path.join(irpdir, '%s.irp.module.F90' % m.filename)
text = '\n'.join(m.header + m.head) text = '\n'.join(m.header + m.head)
lazy_write_file(filename, '%s\n' % text) lazy_write_file(filename, '%s\n' % text)
# Subroutines # Subroutines
@ -290,7 +290,7 @@ class Irpy_comm_world(object):
irp_stack.create() irp_stack.create()
def create_buildfile(self,ninja): def create_buildfile(self,ninja):
import build_file import build_file
build_file.run(self.d_module,ninja) build_file.run(self.d_module,ninja)
def create_touches(self): def create_touches(self):
@ -303,11 +303,11 @@ class Irpy_comm_world(object):
def create_lock(self): def create_lock(self):
from util import lazy_write_file from util import lazy_write_file
l = sorted(self.d_entity.keys()) l = sorted(self.d_entity.keys())
out = [] out = []
for v in l: for v in l:
out += self.d_entity[v].locker out += self.d_entity[v].locker
out += [ "subroutine irp_init_locks_%s()"%(irpf90_t.irp_id), out += [ "subroutine irp_init_locks_%s()"%(irpf90_t.irp_id),
@ -317,6 +317,6 @@ class Irpy_comm_world(object):
out += [ " call irp_lock_%s(.False.)"%v ] out += [ " call irp_lock_%s(.False.)"%v ]
out += [ "end subroutine", "" ] out += [ "end subroutine", "" ]
filename = os.path.join(irpf90_t.irpdir,'irp_locks.irp.F90') filename = os.path.join(irpf90_t.irpdir,'irp_locks.irp.F90')
lazy_write_file(filename, '\n'.join(out)) lazy_write_file(filename, '\n'.join(out))

View File

@ -37,7 +37,7 @@ def put_info(text, filename):
str_ = '{text:{width}} ! {filename}:{i:4}' str_ = '{text:{width}} ! {filename}:{i:4}'
for _, line in text: for _, line in text:
line.text = str_.format(text=line.text,filename=line.filename,i=line.i,width=lenmax) line.text = str_.format(text=line.text,filename=line.filename,i=line.i,width=lenmax)
return text return text
@ -50,13 +50,13 @@ class Fmodule(object):
"! !", "! !",
"! DO NOT MODIFY IT BY HAND !", "! DO NOT MODIFY IT BY HAND !",
"!-----------------------------------------------!", "!-----------------------------------------------!",
""] ""]
def __init__(self, text, filename, d_variable): def __init__(self, text, filename, d_variable):
self.text = put_info(text, filename) self.text = put_info(text, filename)
self.filename = filename[:-6] self.filename = filename[:-6]
self.name = "%s_mod" % (self.filename).replace('/', '__').replace('.', 'Dot') self.name = "%s_mod" % (self.filename).replace('/', '__').replace('.', 'Dot')
self.d_all_variable = d_variable self.d_all_variable = d_variable
@irpy.lazy_property @irpy.lazy_property
def prog_name(self): def prog_name(self):
@ -75,22 +75,22 @@ class Fmodule(object):
def head(self): def head(self):
'''The module who containt the declaration of the entity''' '''The module who containt the declaration of the entity'''
body = list(self.use) body = list(self.use)
body += list(self.dec) body += list(self.dec)
body += [header for var in self.l_entity for header in var.header] body += [header for var in self.l_entity for header in var.header]
if body: if body:
result = ["module %s" % (self.name)] result = ["module %s" % (self.name)]
result += body result += body
result += ["end module %s" % (self.name)] result += ["end module %s" % (self.name)]
else: else:
result = [] result = []
return result return result
@irpy.lazy_property @irpy.lazy_property
def has_irp_module(self): def has_irp_module(self):
return bool(self.head) return bool(self.head)
@irpy.lazy_property @irpy.lazy_property
def needed_vars(self): def needed_vars(self):
@ -102,7 +102,7 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def generated_text(self): def generated_text(self):
'Routine genereraed by the IRPF90. provide, build, ...' 'Routine genereraed by the IRPF90. provide, build, ...'
result = [] result = []
for var in self.l_entity: for var in self.l_entity:
result += var.provider result += var.provider
@ -134,14 +134,14 @@ class Fmodule(object):
result = [] result = []
variable_list = [] variable_list = []
skip_interface = False skip_interface = False
for vars, line in text: for vars, line in text:
if type(line) in [Interface, End_interface]: if type(line) in [Interface, End_interface]:
skip_interface = not skip_interface skip_interface = not skip_interface
if skip_interface: if skip_interface:
result.append((vars, line)) result.append((vars, line))
continue continue
if type(line) in [Subroutine, Function, Program]: if type(line) in [Subroutine, Function, Program]:
@ -156,8 +156,8 @@ class Fmodule(object):
return result return result
def extract_use_dec_text(text): def extract_use_dec_text(text):
# (List[ Tuple(Entity,Line) ]) -> (List[ Tuple(Entity,Line),List[ Tuple(Entity,Line),List[ Tuple(Entity,Line)) # (List[ Tuple(Entity,Line) ]) -> (List[ Tuple(Entity,Line),List[ Tuple(Entity,Line),List[ Tuple(Entity,Line))
'''Extract the global declaration statement and module use form the declaration of function. ''' '''Extract the global declaration statement and module use form the declaration of function. '''
inside = 0 inside = 0
result,dec,use,module = [],[],[],[] result,dec,use,module = [],[],[],[]
@ -167,8 +167,8 @@ class Fmodule(object):
if isinstance(line, (Subroutine, Function, Program,Interface,Module)): if isinstance(line, (Subroutine, Function, Program,Interface,Module)):
inside += 1 inside += 1
if type(line) == Module: if type(line) == Module:
module.append((vars,line)) module.append((vars,line))
if inside: if inside:
result.append((vars, line)) result.append((vars, line))
@ -180,11 +180,11 @@ class Fmodule(object):
if isinstance(line,(End,End_interface,End_module)): if isinstance(line,(End,End_interface,End_module)):
inside += -1 inside += -1
if inside: if inside:
print 'Something wrong append' print 'Something wrong append'
sys.exit(1) sys.exit(1)
return use, module, dec, result return use, module, dec, result
@ -202,32 +202,32 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def gen_mod(self): def gen_mod(self):
'''List of module generated by the user in this module...''' '''List of module generated by the user in this module...'''
return set("%s" % line.subname for _, line in self.residual_text_use_dec.module) return set("%s" % line.subname for _, line in self.residual_text_use_dec.module)
@irpy.lazy_property @irpy.lazy_property
def dec(self): def dec(self):
'''The declaration of this module '''The declaration of this module
Note: Note:
Because user can define F90 Type, we need to keep the correct order. Because user can define F90 Type, we need to keep the correct order.
Warning: Warning:
If we uniquify that can cause a problem with the type in guess. If we uniquify that can cause a problem with the type in guess.
```type toto ```type toto
integer :: n integer :: n
end type toto end type toto
integer :: n integer :: n
``` ```
Fix: Fix:
We need to support Type keyword. We need to support Type keyword.
''' '''
l = [" %s" % line.text for _, line in self.residual_text_use_dec.dec] l = [" %s" % line.text for _, line in self.residual_text_use_dec.dec]
from util import uniquify from util import uniquify
if len(l) != len(uniquify(l)): if len(l) != len(uniquify(l)):
raise NotImplementedError raise NotImplementedError
return l return l
@ -244,13 +244,13 @@ class Fmodule(object):
from parsed_text import move_to_top_list, move_interface from parsed_text import move_to_top_list, move_interface
move_to_top_list(result, [Declaration, Implicit, Use]) move_to_top_list(result, [Declaration, Implicit, Use])
move_interface(result) move_interface(result)
return [line.text for _, line in result] return [line.text for _, line in result]
@irpy.lazy_property @irpy.lazy_property
def needed_modules(self): def needed_modules(self):
l = set(x.split(',only').pop(0).split()[1] for x in self.generated_text + self.head + self.residual_text if x.lstrip().startswith("use ")) l = set(x.split(',only').pop(0).split()[1] for x in self.generated_text + self.head + self.residual_text if x.lstrip().startswith("use "))
if self.name in l: if self.name in l:
l.remove(self.name) l.remove(self.name)
@ -264,6 +264,6 @@ class Fmodule(object):
@irpy.lazy_property @irpy.lazy_property
def needed_modules_usr(self): def needed_modules_usr(self):
return [i for i in self.needed_modules if not i.endswith("_mod")] return [i for i in self.needed_modules if not i.endswith("_mod")]

View File

@ -205,15 +205,15 @@ def move_to_top_list(text, it):
Note: Note:
- The permutation neeed to be done following `it` order - The permutation neeed to be done following `it` order
- We can have `nested` subroutine / Function. (Because of interface) - We can have `nested` subroutine / Function. (Because of interface)
- This function is called way to much. Is need to be efficient - This function is called way to much. Is need to be efficient
- This function is Unpure - This function is Impure
- One pass over `text` - One pass over `text`
NB: NB:
- I am not really proud of the Sentinel value for the deleted, - I am not really proud of the Sentinel value for the deleted,
but I waste already so much time on more cleaver but not working solution... but I waste already so much time on more cleaver but not working solution...
''' '''
assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_provider]) assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_provider])
@ -235,12 +235,12 @@ def move_to_top_list(text, it):
if t in [Begin_provider, Module,Program, Subroutine, Function]: if t in [Begin_provider, Module,Program, Subroutine, Function]:
l_begin.append(i) l_begin.append(i)
elif t in [End_provider, End]: elif t in [End_provider, End]:
l_begin.pop() l_begin.pop()
elif l_begin and t in it: elif l_begin and t in it:
d_permutation[t].append( (l_begin[-1], [l_var, line]) ) d_permutation[t].append( (l_begin[-1], [l_var, line]) )
# Put the sentinel, will be deleted after the insertion # Put the sentinel, will be deleted after the insertion
text[i] = None text[i] = None
# ~ # ~ # ~ # ~ # ~ # ~
# O r d e r t h e m # O r d e r t h e m
@ -264,8 +264,8 @@ def move_to_top_list(text, it):
# Now do the Delete part of the move. Fortunatly we put a sentinel to know the line to delete # Now do the Delete part of the move. Fortunatly we put a sentinel to know the line to delete
for i in reversed(xrange(len(text))): for i in reversed(xrange(len(text))):
if text[i] is None: if text[i] is None:
del text[i] del text[i]
def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Function,Module)): def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Function,Module)):
@ -273,7 +273,7 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
'''Move everything containt into 'interface' below the first instance of s_type who preced it '''Move everything containt into 'interface' below the first instance of s_type who preced it
Note: Note:
= This function is unpur = This function is impure
''' '''
# Get the born of the interface # Get the born of the interface
@ -283,14 +283,14 @@ def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Funct
# Get the begin of the insert # Get the begin of the insert
i_insert = [] i_insert = []
for begin in i_begin: for begin in i_begin:
i_insert.append(next(i+1 for i in range(begin,-1,-1) if isinstance(parsed_text[i][1], s_type))) i_insert.append(next(i+1 for i in range(begin,-1,-1) if isinstance(parsed_text[i][1], s_type)))
# Do the insert and the delete in one passe # Do the insert and the delete in one passe
for insert, begin, end in zip(i_insert,i_begin,i_end): for insert, begin, end in zip(i_insert,i_begin,i_end):
parsed_text[insert:insert] = parsed_text[begin:end] parsed_text[insert:insert] = parsed_text[begin:end]
padding = end-begin padding = end-begin
parsed_text[begin+padding:end+padding] = [] parsed_text[begin+padding:end+padding] = []
###################################################################### ######################################################################
def build_sub_needs(parsed_text, d_subroutine): def build_sub_needs(parsed_text, d_subroutine):
@ -298,7 +298,7 @@ def build_sub_needs(parsed_text, d_subroutine):
'''Set the needs, and provides arguements of Routine present in parsed_text '''Set the needs, and provides arguements of Routine present in parsed_text
Note: Note:
This function is unpure This function is impure
''' '''
l_buffer = [] l_buffer = []
@ -347,15 +347,15 @@ def move_variables(parsed_text):
revtext = list(text) revtext = list(text)
revtext.reverse() revtext.reverse()
skip_interface = False skip_interface = False
try: try:
for vars, line in revtext: for vars, line in revtext:
if type(line) in [Interface, End_interface]: if type(line) in [Interface, End_interface]:
skip_interface = not skip_interface skip_interface = not skip_interface
if skip_interface: if skip_interface:
append(([], line)) append(([], line))
continue continue
if type(line) in [End_provider, End]: if type(line) in [End_provider, End]:
varlist = [] varlist = []
@ -399,10 +399,10 @@ def move_variables(parsed_text):
varlist += vars varlist += vars
append(([], line)) append(([], line))
except: except:
from util import logger from util import logger
logger.error("Unable to parse file %s", line) logger.error("Unable to parse file %s", line)
import sys import sys
sys.exit(1) sys.exit(1)
result.reverse() result.reverse()

View File

@ -129,11 +129,11 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
# Handle archaic do loop of f77 # Handle archaic do loop of f77
firstword = l_word[0] firstword = l_word[0]
if firstword.isdigit(): if firstword.isdigit():
l_word = l_word[1:] l_word = l_word[1:]
firstword = l_word[0] firstword = l_word[0]
if firstword == "contains": if firstword == "contains":
return [Contains(i, line, filename)], False return [Contains(i, line, filename)], False
if firstword == "end_doc": if firstword == "end_doc":
return [End_doc(i, line, filename)], False return [End_doc(i, line, filename)], False
@ -151,7 +151,7 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
#label do-loop (outer: do i=1,sze) #label do-loop (outer: do i=1,sze)
reg_do_lab = ur":\s+do\s+" reg_do_lab = ur":\s+do\s+"
if re.search(reg_do_lab,line_lower): if re.search(reg_do_lab,line_lower):
return [Do(i,line,filename)], is_doc return [Do(i,line,filename)], is_doc
lower_line = line_lower.strip()[1:] lower_line = line_lower.strip()[1:]
@ -170,7 +170,7 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
result = [Simple_line(i, line, filename)] result = [Simple_line(i, line, filename)]
logger.info("%s:" logger.info("%s:"
"irpf90 may not work with preprocessor directives. You can use" "irpf90 may not work with preprocessor directives. You can use"
"Irp_if ... Irp_else ... Irp_endif" "Irp_if ... Irp_else ... Irp_endif"
"instead of" "instead of"
"#ifdef ... #else ... #endif"%line) "#ifdef ... #else ... #endif"%line)
@ -189,7 +189,7 @@ def get_type(i, filename, line, line_lower, line_lower_canonized, is_doc):
# Detect errors # Detect errors
if firstword == "dowhile": if firstword == "dowhile":
logger.error("%s 'do while' should be in 2 words." % Do(i, line, filename)) logger.error("%s 'do while' should be in 2 words." % Do(i, line, filename))
sys.exit(1) sys.exit(1)
return [Simple_line(i, line, filename)], is_doc return [Simple_line(i, line, filename)], is_doc
@ -202,8 +202,8 @@ def save_and_execute(irpdir, scriptname, code, interpreter):
''' Save the script in irpdir/scriptname and Execute it ''' Save the script in irpdir/scriptname and Execute it
Note: Note:
The script are executed in the orginal directory of the .irp.f (aka '..') The script are executed in the orginal directory of the .irp.f (aka '..')
and this directory is added to PYTHONPATH. and this directory is added to PYTHONPATH.
''' '''
irpdir_scriptname = os.path.abspath(os.path.join(irpdir, scriptname)) irpdir_scriptname = os.path.abspath(os.path.join(irpdir, scriptname))
@ -213,11 +213,11 @@ def save_and_execute(irpdir, scriptname, code, interpreter):
# Execute shell # Execute shell
import util import util
try: try:
text = util.check_output('PYTHONPATH=$PYTHONPATH:. %s %s' % (interpreter, irpdir_scriptname), shell=True, bufsize=-1, cwd=os.path.join(irpdir,'..')) text = util.check_output('PYTHONPATH=$PYTHONPATH:. %s %s' % (interpreter, irpdir_scriptname), shell=True, bufsize=-1, cwd=os.path.join(irpdir,'..'))
except: except:
util.logger.error("Something wrong append with embeded '%s' script: %s"% (interpreter, irpdir_scriptname)) util.logger.error("Something wrong append with embeded '%s' script: %s"% (interpreter, irpdir_scriptname))
import sys import sys
sys.exit(1) sys.exit(1)
# Create the Line # Create the Line
p = Preprocess_text(scriptname) p = Preprocess_text(scriptname)
@ -242,21 +242,21 @@ def execute_shell(text):
import sys import sys
def fail(l, a, b): def fail(l, a, b):
logger.error("%s In Begin_Shell, %s '%s'" % (l,a, b)) logger.error("%s In Begin_Shell, %s '%s'" % (l,a, b))
sys.exit(1) sys.exit(1)
for begin,end in zip(l_begin,l_end): for begin,end in zip(l_begin,l_end):
header = text[begin] header = text[begin]
header_text = header.text header_text = header.text
for bracket in ['[', ']']: for bracket in ['[', ']']:
n = header_text.count(bracket) n = header_text.count(bracket)
assert n <= 1, fail(header_text, "Too many", bracket) assert n <= 1, fail(header_text, "Too many", bracket)
assert n >= 1, fail(header_text, "Missing", bracket) assert n >= 1, fail(header_text, "Missing", bracket)
else: else:
interpreter = header_text[header_text.find('[')+1: header_text.find(']')].strip() interpreter = header_text[header_text.find('[')+1: header_text.find(']')].strip()
script = ['%s\n' % l.text for l in text[begin+1:end] ] script = ['%s\n' % l.text for l in text[begin+1:end] ]
scriptname="%s_shell_%d" % (header.filename, header.i) scriptname="%s_shell_%d" % (header.filename, header.i)
l_output.append(save_and_execute(irpdir, scriptname, script,interpreter)) l_output.append(save_and_execute(irpdir, scriptname, script,interpreter))
@ -271,8 +271,8 @@ def execute_shell(text):
l_end_include = [i+1 for i in l_end] l_end_include = [i+1 for i in l_end]
padding = 0 padding = 0
for begin,end, out in zip(l_begin,l_end_include,l_output): for begin,end, out in zip(l_begin,l_end_include,l_output):
text_new[begin+padding:end+padding] = out text_new[begin+padding:end+padding] = out
padding += len(out) - (end-begin) padding += len(out) - (end-begin)
return text_new return text_new
@ -407,30 +407,30 @@ def remove_comments(text, form):
'''Remove all comments '''Remove all comments
Note: Note:
This function is unpur This function is impure
''' '''
result = [] result = []
def remove_after_bang(str_): def remove_after_bang(str_):
# str -> str # str -> str
i_bang = str_.find('!') i_bang = str_.find('!')
if i_bang == -1: if i_bang == -1:
return str_ return str_
else: else:
sentinel, inside = None, False sentinel, inside = None, False
for i,c in enumerate(str_): for i,c in enumerate(str_):
if c == '"' or c == "'": if c == '"' or c == "'":
if not inside: if not inside:
inside = True inside = True
sentinel = c sentinel = c
elif sentinel == c: elif sentinel == c:
inside = False inside = False
elif c == '!' and not inside: elif c == '!' and not inside:
return str_[:i].strip() return str_[:i].strip()
return str_ return str_
if form == Free_form: if form == Free_form:
@ -442,10 +442,10 @@ def remove_comments(text, form):
else: else:
newline = line.text.lstrip() newline = line.text.lstrip()
if (newline != "" and newline[0] != "!#"): if (newline != "" and newline[0] != "!#"):
text = remove_after_bang(line.text) text = remove_after_bang(line.text)
if text: if text:
line.text = text line.text = text
result.append(line) result.append(line)
return result return result
else: else:
@ -511,7 +511,7 @@ def irp_simple_statements(text):
'''Processes simple statements''' '''Processes simple statements'''
def process_irp_rw(line, rw, t): def process_irp_rw(line, rw, t):
'''Read Write''' '''Read Write'''
assert type(line) == t assert type(line) == t
buffer = line.text.split() buffer = line.text.split()
if len(buffer) == 2: if len(buffer) == 2:
@ -652,7 +652,7 @@ def irp_simple_statements(text):
def process_function(line): def process_function(line):
assert type(line) == Function assert type(line) == Function
subname = line.subname subname = line.subname
length = len(subname) length = len(subname)
i = line.i i = line.i
f = line.filename f = line.filename
@ -740,15 +740,15 @@ def process_old_style_do(text):
DO 1 i=1,10''' DO 1 i=1,10'''
def change_matching_enddo(begin, number): def change_matching_enddo(begin, number):
for i,line in enumerate(text[begin+1:]): for i,line in enumerate(text[begin+1:]):
if isinstance(line,(Continue,Enddo)) and line.text.split()[0] == number: if isinstance(line,(Continue,Enddo)) and line.text.split()[0] == number:
text[begin+1+i] = Enddo(line.i, " enddo", line.filename) text[begin+1+i] = Enddo(line.i, " enddo", line.filename)
return return
from util import logger from util import logger
logger.error(text[begin], "(%s) Old-style do loops should end with 'continue' or 'end do'" % text[begin]) logger.error(text[begin], "(%s) Old-style do loops should end with 'continue' or 'end do'" % text[begin])
from util import sys from util import sys
sys.exit(1) sys.exit(1)
result = [] result = []
for i in range(len(text)): for i in range(len(text)):
@ -769,8 +769,8 @@ def process_old_style_do(text):
###################################################################### ######################################################################
def change_single_line_ifs(text): def change_single_line_ifs(text):
# List[Line] -> List[Line] # List[Line] -> List[Line]
'''Changes: `if (test) result` '''Changes: `if (test) result`
into into
`if (test) then `if (test) then
result result
endif`''' endif`'''
@ -785,9 +785,9 @@ def change_single_line_ifs(text):
else: else:
buffer = line.text buffer = line.text
begin = buffer.find('(') begin = buffer.find('(')
if begin == -1: if begin == -1:
logger.error("No '(' in if statemnt: %s" % line) logger.error("No '(' in if statemnt: %s" % line)
sys.exit(1) sys.exit(1)
level = 0 level = 0
instring = False instring = False
@ -805,7 +805,7 @@ def change_single_line_ifs(text):
break break
if level != 0: if level != 0:
logger.error("If statement not valid: %s (%s)" % (line, line.filename)) logger.error("If statement not valid: %s (%s)" % (line, line.filename))
sys.exit(1) sys.exit(1)
test = buffer[:end] test = buffer[:end]
code = buffer[end:] code = buffer[end:]
@ -832,34 +832,34 @@ def check_begin_end(raw_text):
''' '''
d_block = {Enddo: [Do], d_block = {Enddo: [Do],
Endif: [If], Endif: [If],
End_provider: [Begin_provider], End_provider: [Begin_provider],
End_doc: [Begin_doc], End_doc: [Begin_doc],
End: [Program, Subroutine, Function], End: [Program, Subroutine, Function],
End_module: [Module], End_module: [Module],
End_interface: [Interface]} End_interface: [Interface]}
from collections import defaultdict from collections import defaultdict
d_type = defaultdict(list) d_type = defaultdict(list)
for line in raw_text: for line in raw_text:
d_type[type(line)].append(line) d_type[type(line)].append(line)
for t_end, l_begin in d_block.iteritems(): for t_end, l_begin in d_block.iteritems():
n_end = len(d_type[t_end]) n_end = len(d_type[t_end])
n_begin = sum(len(d_type[t_begin]) for t_begin in l_begin) n_begin = sum(len(d_type[t_begin]) for t_begin in l_begin)
if n_end != n_begin: if n_end != n_begin:
if n_end > n_begin: if n_end > n_begin:
logger.error("You have more close statement than open statement (%s) (%s)",line.filename,t_end) logger.error("You have more close statement than open statement (%s) (%s)",line.filename,t_end)
else: else:
logger.error('You have more end statement than open statenemt for (%s) (%s)' % (line.filename, t_end)) logger.error('You have more end statement than open statenemt for (%s) (%s)' % (line.filename, t_end))
for i in zip([l for i in l_begin for l in d_type[i]], d_type[t_end]): for i in zip([l for i in l_begin for l in d_type[i]], d_type[t_end]):
logger.debug(i) logger.debug(i)
sys.exit(1) sys.exit(1)
###################################################################### ######################################################################
def remove_ifdefs(text): def remove_ifdefs(text):
@ -912,13 +912,13 @@ class Preprocess_text(object):
with open(self.filename, 'r') as f: with open(self.filename, 'r') as f:
str_ = f.read() str_ = f.read()
#Dirty thing. We will replace 'end program' by 'end subroutine' #Dirty thing. We will replace 'end program' by 'end subroutine'
#because afterward the program will be replaced by a subroutine... #because afterward the program will be replaced by a subroutine...
import re import re
transform = re.compile(re.escape('end program'), re.IGNORECASE) transform = re.compile(re.escape('end program'), re.IGNORECASE)
return transform.sub('end subroutine', str_) return transform.sub('end subroutine', str_)
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def text_align(self): def text_align(self):

View File

@ -82,15 +82,15 @@ class Routine(object):
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property
def touches_my_self(self): def touches_my_self(self):
return set(x for line in self.text for x in line.text.split()[1:] if isinstance(line,(Touch, SoftTouch))) return set(x for line in self.text for x in line.text.split()[1:] if isinstance(line,(Touch, SoftTouch)))
@irpy.lazy_property_mutable @irpy.lazy_property_mutable
def touches_ancestor(self): def touches_ancestor(self):
raise AttributeError raise AttributeError
@irpy.lazy_property @irpy.lazy_property
def touches(self): def touches(self):
return list(self.touches_my_self.union(self.touches_ancestor)) return list(self.touches_my_self.union(self.touches_ancestor))
############################################################ ############################################################
@irpy.lazy_property @irpy.lazy_property

View File

@ -62,11 +62,11 @@ def parmap(f, it, parallel=False):
The parallel flag is set to togle the // execusion The parallel flag is set to togle the // execusion
Note: Note:
- We try to use the Mulprocesses map is possible else we use our own - We try to use the Mulprocesses map is possible else we use our own
- The order of the sequence if concerved - The order of the sequence if concerved
- Will use all the processesor possible - Will use all the processesor possible
- We return a List - We return a List
- The traceback is loose if an error occur but a Exception is raise. - The traceback is loose if an error occur but a Exception is raise.
''' '''
if not parallel: if not parallel:
@ -82,12 +82,12 @@ def parmap(f, it, parallel=False):
# https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled # https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled
#from cPickle import PicklingError #from cPickle import PicklingError
#try: #try:
# p = multiprocessing.Pool(nproc) # p = multiprocessing.Pool(nproc)
# l_res = p.map(f, it,nproc) # l_res = p.map(f, it,nproc)
#except PicklingError: #except PicklingError:
# pass # pass
#else: #else:
# return l_res # return l_res
# ~!~!~! # ~!~!~!
# Parallelisation By Us # Parallelisation By Us
@ -116,21 +116,21 @@ def parmap(f, it, parallel=False):
'''Read a task from q_in, excute it, and store it in q_out '''Read a task from q_in, excute it, and store it in q_out
Note: Note:
- We use 'F' and not 'f'. - We use 'F' and not 'f'.
- The for loop will break when stop_contition occur - The for loop will break when stop_contition occur
- We get, and put an idx to allow the possibility of ordering afterward - We get, and put an idx to allow the possibility of ordering afterward
- We store any exeception, to raise her afterward - We store any exeception, to raise her afterward
''' '''
for i, x in iter(q_in.get, stop_condition): for i, x in iter(q_in.get, stop_condition):
try: try:
result = F(x) result = F(x)
except BaseException as e: except BaseException as e:
t = e t = e
else: else:
t = (i, result) t = (i, result)
q_out.put(t) q_out.put(t)
q_in.task_done() q_in.task_done()
q_in.task_done() q_in.task_done()
@ -143,7 +143,7 @@ def parmap(f, it, parallel=False):
# Add the job to the queue (Note we add an idx, this will all) # Add the job to the queue (Note we add an idx, this will all)
for i, x in enumerate(it_chunk): for i, x in enumerate(it_chunk):
q_in.put((i, x)) q_in.put((i, x))
# Now add the stop contidion and join # Now add the stop contidion and join
# (Because q_in.get is blocking we don't need to join the queue before) # (Because q_in.get is blocking we don't need to join the queue before)
@ -159,13 +159,13 @@ def parmap(f, it, parallel=False):
# Check if error have occured # Check if error have occured
try: try:
from itertools import ifilter from itertools import ifilter
e = next(ifilter(lambda t: isinstance(t,BaseException), l_res)) e = next(ifilter(lambda t: isinstance(t,BaseException), l_res))
except StopIteration: except StopIteration:
# Now we need first to order the result, and secondly to flatte it # Now we need first to order the result, and secondly to flatte it
return [item for _, chunk in sorted(l_res) for item in chunk] return [item for _, chunk in sorted(l_res) for item in chunk]
else: else:
raise e raise e
# ~#~#~#~#~# # ~#~#~#~#~#
# I O _ R E L A T E D # I O _ R E L A T E D
@ -177,16 +177,16 @@ def cached_file(filename, text):
'''Check if file locatte at filename containt the same data as text '''Check if file locatte at filename containt the same data as text
Return: Return:
True if data is the same, false otherwise True if data is the same, false otherwise
''' '''
def digest(data): def digest(data):
# (str) -> str # (str) -> str
'''compute an uniq data id''' '''compute an uniq data id'''
return hashlib.md5(data).hexdigest() return hashlib.md5(data).hexdigest()
try: try:
text_ref = open(filename, 'rb').read() text_ref = open(filename, 'rb').read()
except IOError: except IOError:
return False return False
else: else:
@ -198,14 +198,14 @@ def lazy_write_file(filename, text, conservative=False,touch=False):
'''Write data lazily in filename location. '''Write data lazily in filename location.
Note: Note:
If convervative is set, we don't overwrite. If convervative is set, we don't overwrite.
''' '''
if not os.path.exists(filename) or not cached_file(filename, text) and not conservative: if not os.path.exists(filename) or not cached_file(filename, text) and not conservative:
with open(filename, 'w') as f: with open(filename, 'w') as f:
f.write(text) f.write(text)
elif touch: elif touch:
os.utime(filename,None) os.utime(filename,None)
def listdir(directory, abspath=False): def listdir(directory, abspath=False):
#(str, bool) -> List[str] #(str, bool) -> List[str]
@ -246,9 +246,9 @@ def uniquify(l,sort=False):
'''Uniquify a immutable iterable. Don't preserve the order''' '''Uniquify a immutable iterable. Don't preserve the order'''
r = list(set(l)) r = list(set(l))
if not sort: if not sort:
return r return r
else: else:
return sorted(r) return sorted(r)
def OrderedUniqueList(l): def OrderedUniqueList(l):
# (Iter, bool) -> List[Any] # (Iter, bool) -> List[Any]
@ -260,7 +260,7 @@ def flatten(l_2d):
'''Construct a copy of the 2d list collapsed into one dimension. '''Construct a copy of the 2d list collapsed into one dimension.
Note: Note:
- We collapse in a C-style fashion (row_major). - We collapse in a C-style fashion (row_major).
''' '''
return [item for l_1d in l_2d for item in l_1d] return [item for l_1d in l_2d for item in l_1d]
@ -274,8 +274,8 @@ def build_dim(l_dim, colons=False):
'''Contruct a valid fortran90 array dimension code from a list dimension '''Contruct a valid fortran90 array dimension code from a list dimension
Exemple: Exemple:
[4,8] -> (4,8) if not colons [4,8] -> (4,8) if not colons
[4,8] -> (:,:) if colons [4,8] -> (:,:) if colons
''' '''
if not l_dim: if not l_dim: