00001 """
00002 Create SLIMpy default builders
00003 """
00004 from SCons.Defaults import ConstructionEnvironment as _ConstructionEnvironment
00005 from SCons.Script import Builder,Action
00006
00007 from slimproj_core.builders.BuilderFunctions import dottest_emitter_wrapper
00008 from slimproj_core.builders.BuilderFunctions import function_parameters
00009 from slimproj_core.builders.BuilderFunctions import help_emitter
00010 from slimproj_core.builders.BuilderFunctions import logfile_emitter,rsf_binary_emitter,slimpy_variable_emitter,additional_parameters
00011 from slimproj_core.builders.BuilderFunctions import profile_emitter_wrapper,slimpy_file
00012
00013
00014
00015
00016
00017 from slimproj_core.builders.my_de_call import DefaultEnvCall
00018
00019 import re
00020 import sys
00021
00022 __copyright__ = """
00023 Copyright 2008 Sean Ross-Ross
00024 """
00025 __license__ = """
00026 This file is part of SLIMpy .
00027
00028 SLIMpy is free software: you can redistribute it and/or modify
00029 it under the terms of the GNU Lesser General Public License as published by
00030 the Free Software Foundation, either version 3 of the License, or
00031 (at your option) any later version.
00032
00033 SLIMpy is distributed in the hope that it will be useful,
00034 but WITHOUT ANY WARRANTY; without even the implied warranty of
00035 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00036 GNU Lesser General Public License for more details.
00037
00038 You should have received a copy of the GNU Lesser General Public License
00039 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00040 """
00041
00042
00043
00044 Default_SLIM_Builders = {}
00045
00046
00047
00048 def default_str_closure(name):
00049 'functional closure on default string function for slimpy actions'
00050
00051 def default_str(target, source, env):
00052 'default string function for a slimpy action'
00053 targets = ', '.join( [repr(t.name) for t in target if hasattr(t,'suffix') and t.suffix == '.rsf' ])
00054 sources = ', '.join( [repr(t.name) for t in source if hasattr(t,'suffix') and t.suffix == '.rsf' ])
00055
00056 cond = lambda val : hasattr(val,'read') and isinstance( val.read(), tuple ) and len(val.read()) == 2
00057
00058 xvals = [ val.read() for val in source if cond(val) ]
00059
00060 vals = []
00061 for key,val in xvals:
00062 if isinstance(val, str):
00063 newvals = val.split('\n')
00064 i = 0
00065 lnv = len(newvals)
00066 while i < lnv and newvals[i].startswith('@'):
00067 i+=1
00068 newval = newvals[i]
00069 allre = re.findall("def (.*)\(.*\):", newval)
00070 if allre:
00071 newval = "<function %s>" %allre[0]
00072 else:
00073 allre = re.findall(" lambda.*:", newval)
00074 if allre:
00075 newval = "<function <lambda>>"
00076
00077 vals.append( (key,newval) )
00078 else:
00079 vals.append( (key,val) )
00080
00081 values = ",\n ".join([ "%s=%s"%( key,repr(item) ) for key,item in vals ])
00082
00083
00084 sources = sources and ", [ %s ]" %sources or ", None"
00085 targets = targets and "[ %s ]" %targets or "None"
00086 values = values and ",\n %s" %values or ""
00087
00088 return "\n"+name + "( %(targets)s%(sources)s%(values)s )\n" %vars()
00089
00090 return default_str
00091
00092 def post_mortem_closure( act ):
00093 """
00094 adds post mortem pdb stack trace
00095 """
00096 def pm_action( target, source, env ):
00097 import bdb
00098 try:
00099 act( target, source, env )
00100 except bdb.BdbQuit:
00101 pass
00102 except:
00103 if env.get('post_mortem'):
00104 type, val, tb = sys.exc_info()
00105 import pdb
00106 print
00107 print type, val
00108 print "launching post mortem"
00109 pdb.post_mortem( tb )
00110
00111 raise
00112
00113 return pm_action
00114
00115 def add_function_emitter( act ,slim_emitters):
00116
00117 if hasattr(act, '__function_dependancies__'):
00118 funcnames = getattr(act, '__function_dependancies__')
00119 slim_emitters.append( function_parameters( funcnames) )
00120 else:
00121 pass
00122
00123 return
00124
00125
00126 def CreateSLIMpyBuilder( name, act , file_name=None, str_func=None , emitters=None, depends_on=None ):
00127 '''
00128 ???
00129 '''
00130
00131 if str_func is None:
00132 str_func = default_str_closure( name )
00133
00134 pm_act = post_mortem_closure( act )
00135 slimpy_action = Action( pm_act, str_func )
00136
00137 if file_name is None:
00138 mod = sys.modules[act.__module__]
00139 file_name = mod.__file__
00140
00141 if depends_on is None:
00142 depends_on = []
00143
00144 if hasattr(act, "__additional_dependancies__" ):
00145 additional_deps = getattr(act, "__additional_dependancies__" )
00146 depends_on.extend( additional_deps )
00147
00148 slim_emitters = [
00149 rsf_binary_emitter,
00150 logfile_emitter,
00151 slimpy_variable_emitter,
00152 slimpy_file(file_name),
00153 additional_parameters(depends_on),
00154 profile_emitter_wrapper(act),
00155 dottest_emitter_wrapper(act),
00156 help_emitter
00157 ]
00158
00159 add_function_emitter(act, slim_emitters)
00160
00161 if emitters is None:
00162 emitters = []
00163
00164 slim_emitters.extend( emitters )
00165
00166 slimpy_builder = Builder( action = slimpy_action,
00167 emitter=slim_emitters,
00168 suffix = '.rsf',
00169 src_suffix = '.rsf')
00170
00171 return slimpy_builder
00172
00173 def add_to_slim_env( name, act , file_name=None, str_func=None , emitters=None, depends_on=None):
00174 '''
00175 add default emitters and string functions and dependencies
00176 '''
00177
00178 global Default_SLIM_Builders
00179
00180 slimpy_builder = CreateSLIMpyBuilder( name, act , file_name, str_func , emitters, depends_on )
00181
00182 Default_SLIM_Builders[name] = slimpy_builder
00183
00184
00185 def new_slim_tool(env):
00186 'auto '
00187 env['BUILDERS'][name] = slimpy_builder
00188
00189 from SCons.Script import _SConscript
00190 if _SConscript._DefaultEnvironmentProxy:
00191 _SConscript._DefaultEnvironmentProxy['BUILDERS'][name] = slimpy_builder
00192
00193 if 'TOOLS' in _ConstructionEnvironment:
00194 _ConstructionEnvironment[ 'TOOLS' ].append( new_slim_tool )
00195 else:
00196 _ConstructionEnvironment[ 'TOOLS' ] = ['default',new_slim_tool]
00197
00198 dec = DefaultEnvCall( name, None, act.__doc__ )
00199
00200 return dec
00201
00202
00203