# Path: waflib/Configure.py
# def conf(f):
# 	"""
# 	Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and
# 	:py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter
# 	named 'mandatory' to disable the configuration errors::
# 
# 		def configure(conf):
# 			conf.find_program('abc', mandatory=False)
# 
# 	:param f: method to bind
# 	:type f: function
# 	"""
# 	def fun(*k, **kw):
# 		mandatory = kw.pop('mandatory', True)
# 		try:
# 			return f(*k, **kw)
# 		except Errors.ConfigurationError:
# 			if mandatory:
# 				raise
# 
# 	fun.__name__ = f.__name__
# 	setattr(ConfigurationContext, f.__name__, fun)
# 	setattr(Build.BuildContext, f.__name__, fun)
# 	return f
# 
# Path: waflib/TaskGen.py
# def feature(*k):
# 	"""
# 	Decorator that registers a task generator method that will be executed when the
# 	object attribute ``feature`` contains the corresponding key(s)::
# 
# 		from waflib.Task import feature
# 		@feature('myfeature')
# 		def myfunction(self):
# 			print('that is my feature!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: feature names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for name in k:
# 			feats[name].update([func.__name__])
# 		return func
# 	return deco
# 
# def before_method(*k):
# 	"""
# 	Decorator that registera task generator method which will be executed
# 	before the functions of given name(s)::
# 
# 		from waflib.TaskGen import feature, before
# 		@feature('myfeature')
# 		@before_method('fun2')
# 		def fun1(self):
# 			print('feature 1!')
# 		@feature('myfeature')
# 		def fun2(self):
# 			print('feature 2!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: method names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for fun_name in k:
# 			task_gen.prec[func.__name__].add(fun_name)
# 		return func
# 	return deco
# 
# def after_method(*k):
# 	"""
# 	Decorator that registers a task generator method which will be executed
# 	after the functions of given name(s)::
# 
# 		from waflib.TaskGen import feature, after
# 		@feature('myfeature')
# 		@after_method('fun2')
# 		def fun1(self):
# 			print('feature 1!')
# 		@feature('myfeature')
# 		def fun2(self):
# 			print('feature 2!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: method names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for fun_name in k:
# 			task_gen.prec[fun_name].add(func.__name__)
# 		return func
# 	return deco


from waflib import Task
from waflib.Configure import conf
from waflib.TaskGen import feature, before_method, after_method
testEXPORT int lib_func(void);
int main(int argc, char **argv) {
	(void)argc; (void)argv;
	return !(lib_func() == 9);
}
'''

@feature('link_lib_test')
@before_method('process_source')
def link_lib_test_fun(self):
	"""
	The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator,
	so we need to create other task generators from here to check if the linker is able to link libraries.
	"""
	def write_test_file(task):
		task.outputs[0].write(task.generator.code)

	rpath = []
	if getattr(self, 'add_rpath', False):
		rpath = [self.bld.path.get_bld().abspath()]

	mode = self.mode
	m = '%s %s' % (mode, mode)
	ex = self.test_exec and 'test_exec' or ''
	bld = self.bld
	bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE)
	bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE)
	bld(features='%sshlib' % m, source='test.' + mode, target='test')
	bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath)


# Path: waflib/Configure.py
# def conf(f):
# 	"""
# 	Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and
# 	:py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter
# 	named 'mandatory' to disable the configuration errors::
# 
# 		def configure(conf):
# 			conf.find_program('abc', mandatory=False)
# 
# 	:param f: method to bind
# 	:type f: function
# 	"""
# 	def fun(*k, **kw):
# 		mandatory = kw.pop('mandatory', True)
# 		try:
# 			return f(*k, **kw)
# 		except Errors.ConfigurationError:
# 			if mandatory:
# 				raise
# 
# 	fun.__name__ = f.__name__
# 	setattr(ConfigurationContext, f.__name__, fun)
# 	setattr(Build.BuildContext, f.__name__, fun)
# 	return f
# 
# Path: waflib/TaskGen.py
# def feature(*k):
# 	"""
# 	Decorator that registers a task generator method that will be executed when the
# 	object attribute ``feature`` contains the corresponding key(s)::
# 
# 		from waflib.Task import feature
# 		@feature('myfeature')
# 		def myfunction(self):
# 			print('that is my feature!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: feature names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for name in k:
# 			feats[name].update([func.__name__])
# 		return func
# 	return deco
# 
# def before_method(*k):
# 	"""
# 	Decorator that registera task generator method which will be executed
# 	before the functions of given name(s)::
# 
# 		from waflib.TaskGen import feature, before
# 		@feature('myfeature')
# 		@before_method('fun2')
# 		def fun1(self):
# 			print('feature 1!')
# 		@feature('myfeature')
# 		def fun2(self):
# 			print('feature 2!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: method names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for fun_name in k:
# 			task_gen.prec[func.__name__].add(fun_name)
# 		return func
# 	return deco
# 
# def after_method(*k):
# 	"""
# 	Decorator that registers a task generator method which will be executed
# 	after the functions of given name(s)::
# 
# 		from waflib.TaskGen import feature, after
# 		@feature('myfeature')
# 		@after_method('fun2')
# 		def fun1(self):
# 			print('feature 1!')
# 		@feature('myfeature')
# 		def fun2(self):
# 			print('feature 2!')
# 		def build(bld):
# 			bld(features='myfeature')
# 
# 	:param k: method names
# 	:type k: list of string
# 	"""
# 	def deco(func):
# 		setattr(task_gen, func.__name__, func)
# 		for fun_name in k:
# 			task_gen.prec[fun_name].add(func.__name__)
# 		return func
# 	return deco


# Path: waflib/Tools/c_tests.py
from waflib import Task
from waflib.Configure import conf
from waflib.TaskGen import feature, before_method, after_method

testEXPORT int lib_func(void);
int main(int argc, char **argv) {
	(void)argc; (void)argv;
	return !(lib_func() == 9);
}
'''

@feature('link_lib_test')
@before_method('process_source')
def link_lib_test_fun(self):
	"""
	The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator,
	so we need to create other task generators from here to check if the linker is able to link libraries.
	"""
	def write_test_file(task):
		task.outputs[0].write(task.generator.code)

	rpath = []
	if getattr(self, 'add_rpath', False):
		rpath = [self.bld.path.get_bld().abspath()]

	mode = self.mode
	m = '%s %s' % (mode, mode)
	ex = self.test_exec and 'test_exec' or ''
	bld = self.bld
	bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE)
	bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE)
	bld(features='%sshlib' % m, source='test.' + mode, target='test')
	bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath)


@conf