midori/waf-modules/wafadmin/Tools/misc.py

303 lines
9.8 KiB
Python
Raw Normal View History

2013-10-24 03:26:27 +00:00
#! /usr/bin/env python
# encoding: utf-8
import shutil,re,os
import TaskGen,Node,Task,Utils,Build,Constants
from TaskGen import feature,taskgen,after,before
from Logs import debug
def copy_func(tsk):
env=tsk.env
infile=tsk.inputs[0].abspath(env)
outfile=tsk.outputs[0].abspath(env)
try:
shutil.copy2(infile,outfile)
except(OSError,IOError):
return 1
else:
if tsk.chmod:os.chmod(outfile,tsk.chmod)
return 0
def action_process_file_func(tsk):
if not tsk.fun:raise Utils.WafError('task must have a function attached to it for copy_func to work!')
return tsk.fun(tsk)
class cmd_taskgen(TaskGen.task_gen):
def __init__(self,*k,**kw):
TaskGen.task_gen.__init__(self,*k,**kw)
def apply_cmd(self):
if not self.fun:raise Utils.WafError('cmdobj needs a function!')
tsk=Task.TaskBase()
tsk.fun=self.fun
tsk.env=self.env
self.tasks.append(tsk)
tsk.install_path=self.install_path
class copy_taskgen(TaskGen.task_gen):
def __init__(self,*k,**kw):
TaskGen.task_gen.__init__(self,*k,**kw)
def apply_copy(self):
Utils.def_attrs(self,fun=copy_func)
self.default_install_path=0
lst=self.to_list(self.source)
self.meths.remove('apply_core')
for filename in lst:
node=self.path.find_resource(filename)
if not node:raise Utils.WafError('cannot find input file %s for processing'%filename)
target=self.target
if not target or len(lst)>1:target=node.name
newnode=self.path.find_or_declare(target)
tsk=self.create_task('copy',node,newnode)
tsk.fun=self.fun
tsk.chmod=self.chmod
tsk.install_path=self.install_path
if not tsk.env:
tsk.debug()
raise Utils.WafError('task without an environment')
def subst_func(tsk):
m4_re=re.compile('@(\w+)@',re.M)
env=tsk.env
infile=tsk.inputs[0].abspath(env)
outfile=tsk.outputs[0].abspath(env)
code=Utils.readf(infile)
code=code.replace('%','%%')
s=m4_re.sub(r'%(\1)s',code)
di=tsk.dict or{}
if not di:
names=m4_re.findall(code)
for i in names:
di[i]=env.get_flat(i)or env.get_flat(i.upper())
file=open(outfile,'w')
file.write(s%di)
file.close()
if tsk.chmod:os.chmod(outfile,tsk.chmod)
class subst_taskgen(TaskGen.task_gen):
def __init__(self,*k,**kw):
TaskGen.task_gen.__init__(self,*k,**kw)
def apply_subst(self):
Utils.def_attrs(self,fun=subst_func)
self.default_install_path=0
lst=self.to_list(self.source)
self.meths.remove('apply_core')
self.dict=getattr(self,'dict',{})
for filename in lst:
node=self.path.find_resource(filename)
if not node:raise Utils.WafError('cannot find input file %s for processing'%filename)
if self.target:
newnode=self.path.find_or_declare(self.target)
else:
newnode=node.change_ext('')
try:
self.dict=self.dict.get_merged_dict()
except AttributeError:
pass
if self.dict and not self.env['DICT_HASH']:
self.env=self.env.copy()
keys=list(self.dict.keys())
keys.sort()
lst=[self.dict[x]for x in keys]
self.env['DICT_HASH']=str(Utils.h_list(lst))
tsk=self.create_task('copy',node,newnode)
tsk.fun=self.fun
tsk.dict=self.dict
tsk.dep_vars=['DICT_HASH']
tsk.install_path=self.install_path
tsk.chmod=self.chmod
if not tsk.env:
tsk.debug()
raise Utils.WafError('task without an environment')
class cmd_arg(object):
def __init__(self,name,template='%s'):
self.name=name
self.template=template
self.node=None
class input_file(cmd_arg):
def find_node(self,base_path):
assert isinstance(base_path,Node.Node)
self.node=base_path.find_resource(self.name)
if self.node is None:
raise Utils.WafError("Input file %s not found in "%(self.name,base_path))
def get_path(self,env,absolute):
if absolute:
return self.template%self.node.abspath(env)
else:
return self.template%self.node.srcpath(env)
class output_file(cmd_arg):
def find_node(self,base_path):
assert isinstance(base_path,Node.Node)
self.node=base_path.find_or_declare(self.name)
if self.node is None:
raise Utils.WafError("Output file %s not found in "%(self.name,base_path))
def get_path(self,env,absolute):
if absolute:
return self.template%self.node.abspath(env)
else:
return self.template%self.node.bldpath(env)
class cmd_dir_arg(cmd_arg):
def find_node(self,base_path):
assert isinstance(base_path,Node.Node)
self.node=base_path.find_dir(self.name)
if self.node is None:
raise Utils.WafError("Directory %s not found in "%(self.name,base_path))
class input_dir(cmd_dir_arg):
def get_path(self,dummy_env,dummy_absolute):
return self.template%self.node.abspath()
class output_dir(cmd_dir_arg):
def get_path(self,env,dummy_absolute):
return self.template%self.node.abspath(env)
class command_output(Task.Task):
color="BLUE"
def __init__(self,env,command,command_node,command_args,stdin,stdout,cwd,os_env,stderr):
Task.Task.__init__(self,env,normal=1)
assert isinstance(command,(str,Node.Node))
self.command=command
self.command_args=command_args
self.stdin=stdin
self.stdout=stdout
self.cwd=cwd
self.os_env=os_env
self.stderr=stderr
if command_node is not None:self.dep_nodes=[command_node]
self.dep_vars=[]
def run(self):
task=self
def input_path(node,template):
if task.cwd is None:
return template%node.bldpath(task.env)
else:
return template%node.abspath()
def output_path(node,template):
fun=node.abspath
if task.cwd is None:fun=node.bldpath
return template%fun(task.env)
if isinstance(task.command,Node.Node):
argv=[input_path(task.command,'%s')]
else:
argv=[task.command]
for arg in task.command_args:
if isinstance(arg,str):
argv.append(arg)
else:
assert isinstance(arg,cmd_arg)
argv.append(arg.get_path(task.env,(task.cwd is not None)))
if task.stdin:
stdin=open(input_path(task.stdin,'%s'))
else:
stdin=None
if task.stdout:
stdout=open(output_path(task.stdout,'%s'),"w")
else:
stdout=None
if task.stderr:
stderr=open(output_path(task.stderr,'%s'),"w")
else:
stderr=None
if task.cwd is None:
cwd=('None (actually %r)'%os.getcwd())
else:
cwd=repr(task.cwd)
debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r"%(cwd,stdin,stdout,argv))
if task.os_env is None:
os_env=os.environ
else:
os_env=task.os_env
command=Utils.pproc.Popen(argv,stdin=stdin,stdout=stdout,stderr=stderr,cwd=task.cwd,env=os_env)
return command.wait()
class cmd_output_taskgen(TaskGen.task_gen):
def __init__(self,*k,**kw):
TaskGen.task_gen.__init__(self,*k,**kw)
def init_cmd_output(self):
Utils.def_attrs(self,stdin=None,stdout=None,stderr=None,command=None,command_is_external=False,argv=[],dependencies=[],dep_vars=[],hidden_inputs=[],hidden_outputs=[],cwd=None,os_env=None)
def apply_cmd_output(self):
if self.command is None:
raise Utils.WafError("command-output missing command")
if self.command_is_external:
cmd=self.command
cmd_node=None
else:
cmd_node=self.path.find_resource(self.command)
assert cmd_node is not None,('''Could not find command '%s' in source tree.
Hint: if this is an external command,
use command_is_external=True''')%(self.command,)
cmd=cmd_node
if self.cwd is None:
cwd=None
else:
assert isinstance(cwd,CmdDirArg)
self.cwd.find_node(self.path)
args=[]
inputs=[]
outputs=[]
for arg in self.argv:
if isinstance(arg,cmd_arg):
arg.find_node(self.path)
if isinstance(arg,input_file):
inputs.append(arg.node)
if isinstance(arg,output_file):
outputs.append(arg.node)
if self.stdout is None:
stdout=None
else:
assert isinstance(self.stdout,str)
stdout=self.path.find_or_declare(self.stdout)
if stdout is None:
raise Utils.WafError("File %s not found"%(self.stdout,))
outputs.append(stdout)
if self.stderr is None:
stderr=None
else:
assert isinstance(self.stderr,str)
stderr=self.path.find_or_declare(self.stderr)
if stderr is None:
raise Utils.WafError("File %s not found"%(self.stderr,))
outputs.append(stderr)
if self.stdin is None:
stdin=None
else:
assert isinstance(self.stdin,str)
stdin=self.path.find_resource(self.stdin)
if stdin is None:
raise Utils.WafError("File %s not found"%(self.stdin,))
inputs.append(stdin)
for hidden_input in self.to_list(self.hidden_inputs):
node=self.path.find_resource(hidden_input)
if node is None:
raise Utils.WafError("File %s not found in dir %s"%(hidden_input,self.path))
inputs.append(node)
for hidden_output in self.to_list(self.hidden_outputs):
node=self.path.find_or_declare(hidden_output)
if node is None:
raise Utils.WafError("File %s not found in dir %s"%(hidden_output,self.path))
outputs.append(node)
if not(inputs or getattr(self,'no_inputs',None)):
raise Utils.WafError('command-output objects must have at least one input file or give self.no_inputs')
if not(outputs or getattr(self,'no_outputs',None)):
raise Utils.WafError('command-output objects must have at least one output file or give self.no_outputs')
task=command_output(self.env,cmd,cmd_node,self.argv,stdin,stdout,cwd,self.os_env,stderr)
Utils.copy_attrs(self,task,'before after ext_in ext_out',only_if_set=True)
self.tasks.append(task)
task.inputs=inputs
task.outputs=outputs
task.dep_vars=self.to_list(self.dep_vars)
for dep in self.dependencies:
assert dep is not self
dep.post()
for dep_task in dep.tasks:
task.set_run_after(dep_task)
if not task.inputs:
task.runnable_status=type(Task.TaskBase.run)(runnable_status,task,task.__class__)
task.post_run=type(Task.TaskBase.run)(post_run,task,task.__class__)
def post_run(self):
for x in self.outputs:
h=Utils.h_file(x.abspath(self.env))
self.generator.bld.node_sigs[self.env.variant()][x.id]=h
def runnable_status(self):
return Constants.RUN_ME
Task.task_type_from_func('copy',vars=[],func=action_process_file_func)
TaskGen.task_gen.classes['command-output']=cmd_output_taskgen
feature('cmd')(apply_cmd)
feature('copy')(apply_copy)
before('apply_core')(apply_copy)
feature('subst')(apply_subst)
before('apply_core')(apply_subst)
feature('command-output')(init_cmd_output)
feature('command-output')(apply_cmd_output)
after('init_cmd_output')(apply_cmd_output)