#! /usr/bin/env python
# encoding: utf-8
# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file

import re,shutil,os,sys,string,shlex
from waflib.Configure import conf
from waflib.TaskGen import feature,after_method,before_method
from waflib import Build,Utils
FC_FRAGMENT='        program main\n        end     program main\n'
FC_FRAGMENT2='        PROGRAM MAIN\n        END\n'
@conf
def fc_flags(conf):
	v=conf.env
	v['FC_SRC_F']=[]
	v['FC_TGT_F']=['-c','-o']
	v['FCINCPATH_ST']='-I%s'
	v['FCDEFINES_ST']='-D%s'
	if not v['LINK_FC']:v['LINK_FC']=v['FC']
	v['FCLNK_SRC_F']=[]
	v['FCLNK_TGT_F']=['-o']
	v['FCFLAGS_fcshlib']=['-fpic']
	v['LINKFLAGS_fcshlib']=['-shared']
	v['fcshlib_PATTERN']='lib%s.so'
	v['fcstlib_PATTERN']='lib%s.a'
	v['FCLIB_ST']='-l%s'
	v['FCLIBPATH_ST']='-L%s'
	v['FCSTLIB_ST']='-l%s'
	v['FCSTLIBPATH_ST']='-L%s'
	v['FCSTLIB_MARKER']='-Wl,-Bstatic'
	v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
	v['SONAME_ST']='-Wl,-h,%s'
@conf
def fc_add_flags(conf):
	conf.add_os_flags('FCFLAGS')
	conf.add_os_flags('LDFLAGS','LINKFLAGS')
@conf
def check_fortran(self,*k,**kw):
	self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
@conf
def check_fc(self,*k,**kw):
	kw['compiler']='fc'
	if not'compile_mode'in kw:
		kw['compile_mode']='fc'
	if not'type'in kw:
		kw['type']='fcprogram'
	if not'compile_filename'in kw:
		kw['compile_filename']='test.f90'
	if not'code'in kw:
		kw['code']=FC_FRAGMENT
	return self.check(*k,**kw)
@conf
def fortran_modifier_darwin(conf):
	v=conf.env
	v['FCFLAGS_fcshlib']=['-fPIC']
	v['LINKFLAGS_fcshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
	v['fcshlib_PATTERN']='lib%s.dylib'
	v['FRAMEWORKPATH_ST']='-F%s'
	v['FRAMEWORK_ST']='-framework %s'
	v['LINKFLAGS_fcstlib']=[]
	v['FCSHLIB_MARKER']=''
	v['FCSTLIB_MARKER']=''
	v['SONAME_ST']=''
@conf
def fortran_modifier_win32(conf):
	v=conf.env
	v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
	v['fcshlib_PATTERN']='%s.dll'
	v['implib_PATTERN']='lib%s.dll.a'
	v['IMPLIB_ST']='-Wl,--out-implib,%s'
	v['FCFLAGS_fcshlib']=[]
	v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
@conf
def fortran_modifier_cygwin(conf):
	fortran_modifier_win32(conf)
	v=conf.env
	v['fcshlib_PATTERN']='cyg%s.dll'
	v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
	v['FCFLAGS_fcshlib']=[]
@conf
def check_fortran_dummy_main(self,*k,**kw):
	if not self.env.CC:
		self.fatal('A c compiler is required for check_fortran_dummy_main')
	lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
	lst.extend([m.lower()for m in lst])
	lst.append('')
	self.start_msg('Detecting whether we need a dummy main')
	for main in lst:
		kw['fortran_main']=main
		try:
			self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
			if not main:
				self.env.FC_MAIN=-1
				self.end_msg('no')
			else:
				self.env.FC_MAIN=main
				self.end_msg('yes %s'%main)
			break
		except self.errors.ConfigurationError:
			pass
	else:
		self.end_msg('not found')
		self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
GCC_DRIVER_LINE=re.compile('^Driving:')
POSIX_STATIC_EXT=re.compile('\S+\.a')
POSIX_LIB_FLAGS=re.compile('-l\S+')
@conf
def is_link_verbose(self,txt):
	assert isinstance(txt,str)
	for line in txt.splitlines():
		if not GCC_DRIVER_LINE.search(line):
			if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
				return True
	return False
@conf
def check_fortran_verbose_flag(self,*k,**kw):
	self.start_msg('fortran link verbose flag')
	for x in['-v','--verbose','-verbose','-V']:
		try:
			self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
		except self.errors.ConfigurationError:
			pass
		else:
			if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
				self.end_msg(x)
				break
	else:
		self.end_msg('failure')
		self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
	self.env.FC_VERBOSE_FLAG=x
	return x
LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
if os.name=='nt':
	LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
else:
	LINKFLAGS_IGNORED.append(r'-lgcc*')
RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
def _match_ignore(line):
	for i in RLINKFLAGS_IGNORED:
		if i.match(line):
			return True
	return False
def parse_fortran_link(lines):
	final_flags=[]
	for line in lines:
		if not GCC_DRIVER_LINE.match(line):
			_parse_flink_line(line,final_flags)
	return final_flags
SPACE_OPTS=re.compile('^-[LRuYz]$')
NOSPACE_OPTS=re.compile('^-[RL]')
def _parse_flink_line(line,final_flags):
	lexer=shlex.shlex(line,posix=True)
	lexer.whitespace_split=True
	t=lexer.get_token()
	tmp_flags=[]
	while t:
		def parse(token):
			if _match_ignore(token):
				pass
			elif token.startswith('-lkernel32')and sys.platform=='cygwin':
				tmp_flags.append(token)
			elif SPACE_OPTS.match(token):
				t=lexer.get_token()
				if t.startswith('P,'):
					t=t[2:]
				for opt in t.split(os.pathsep):
					tmp_flags.append('-L%s'%opt)
			elif NOSPACE_OPTS.match(token):
				tmp_flags.append(token)
			elif POSIX_LIB_FLAGS.match(token):
				tmp_flags.append(token)
			else:
				pass
			t=lexer.get_token()
			return t
		t=parse(t)
	final_flags.extend(tmp_flags)
	return final_flags
@conf
def check_fortran_clib(self,autoadd=True,*k,**kw):
	if not self.env.FC_VERBOSE_FLAG:
		self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
	self.start_msg('Getting fortran runtime link flags')
	try:
		self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
	except Exception:
		self.end_msg(False)
		if kw.get('mandatory',True):
			conf.fatal('Could not find the c library flags')
	else:
		out=self.test_bld.err
		flags=parse_fortran_link(out.splitlines())
		self.end_msg('ok (%s)'%' '.join(flags))
		self.env.LINKFLAGS_CLIB=flags
		return flags
	return[]
def getoutput(conf,cmd,stdin=False):
	if stdin:
		stdin=Utils.subprocess.PIPE
	else:
		stdin=None
	env=conf.env.env or None
	try:
		p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
		if stdin:
			p.stdin.write('\n')
		out,err=p.communicate()
	except Exception:
		conf.fatal('could not determine the compiler version %r'%cmd)
	if not isinstance(out,str):
		out=out.decode(sys.stdout.encoding or'iso8859-1')
	if not isinstance(err,str):
		err=err.decode(sys.stdout.encoding or'iso8859-1')
	return(out,err)
ROUTINES_CODE="""\
      subroutine foobar()
      return
      end
      subroutine foo_bar()
      return
      end
"""
MAIN_CODE="""
void %(dummy_func_nounder)s(void);
void %(dummy_func_under)s(void);
int %(main_func_name)s() {
  %(dummy_func_nounder)s();
  %(dummy_func_under)s();
  return 0;
}
"""
@feature('link_main_routines_func')
@before_method('process_source')
def link_main_routines_tg_method(self):
	def write_test_file(task):
		task.outputs[0].write(task.generator.code)
	bld=self.bld
	bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
	bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
	bld(features='fc fcstlib',source='test.f',target='test')
	bld(features='c fcprogram',source='main.c',target='app',use='test')
def mangling_schemes():
	for u in['_','']:
		for du in['','_']:
			for c in["lower","upper"]:
				yield(u,du,c)
def mangle_name(u,du,c,name):
	return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
@conf
def check_fortran_mangling(self,*k,**kw):
	if not self.env.CC:
		self.fatal('A c compiler is required for link_main_routines')
	if not self.env.FC:
		self.fatal('A fortran compiler is required for link_main_routines')
	if not self.env.FC_MAIN:
		self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
	self.start_msg('Getting fortran mangling scheme')
	for(u,du,c)in mangling_schemes():
		try:
			self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
		except self.errors.ConfigurationError:
			pass
		else:
			self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
			self.env.FORTRAN_MANGLING=(u,du,c)
			break
	else:
		self.end_msg(False)
		self.fatal('mangler not found')
	return(u,du,c)
@feature('pyext')
@before_method('propagate_uselib_vars','apply_link')
def set_lib_pat(self):
	self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
@conf
def detect_openmp(self):
	for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
		try:
			self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n  call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
		except self.errors.ConfigurationError:
			pass
		else:
			break
	else:
		self.fatal('Could not find OpenMP')
