1#!/usr/bin/env python
2# encoding: utf-8
3# Brant Young, 2007
4
5"Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}"
6
7import re
8from waflib import Task
9from waflib.TaskGen import extension
10from waflib.Tools import c_preproc
11
12@extension('.rc')
13def rc_file(self, node):
14	"""
15	Binds the .rc extension to a winrc task
16	"""
17	obj_ext = '.rc.o'
18	if self.env.WINRC_TGT_F == '/fo':
19		obj_ext = '.res'
20	rctask = self.create_task('winrc', node, node.change_ext(obj_ext))
21	try:
22		self.compiled_tasks.append(rctask)
23	except AttributeError:
24		self.compiled_tasks = [rctask]
25
26re_lines = re.compile(
27	r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\
28	r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',
29	re.IGNORECASE | re.MULTILINE)
30
31class rc_parser(c_preproc.c_parser):
32	"""
33	Calculates dependencies in .rc files
34	"""
35	def filter_comments(self, node):
36		"""
37		Overrides :py:meth:`waflib.Tools.c_preproc.c_parser.filter_comments`
38		"""
39		code = node.read()
40		if c_preproc.use_trigraphs:
41			for (a, b) in c_preproc.trig_def:
42				code = code.split(a).join(b)
43		code = c_preproc.re_nl.sub('', code)
44		code = c_preproc.re_cpp.sub(c_preproc.repl, code)
45		ret = []
46		for m in re.finditer(re_lines, code):
47			if m.group(2):
48				ret.append((m.group(2), m.group(3)))
49			else:
50				ret.append(('include', m.group(5)))
51		return ret
52
53class winrc(Task.Task):
54	"""
55	Compiles resource files
56	"""
57	run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
58	color   = 'BLUE'
59	def scan(self):
60		tmp = rc_parser(self.generator.includes_nodes)
61		tmp.start(self.inputs[0], self.env)
62		return (tmp.nodes, tmp.names)
63
64def configure(conf):
65	"""
66	Detects the programs RC or windres, depending on the C/C++ compiler in use
67	"""
68	v = conf.env
69	if not v.WINRC:
70		if v.CC_NAME == 'msvc':
71			conf.find_program('RC', var='WINRC', path_list=v.PATH)
72			v.WINRC_TGT_F = '/fo'
73			v.WINRC_SRC_F = ''
74		else:
75			conf.find_program('windres', var='WINRC', path_list=v.PATH)
76			v.WINRC_TGT_F = '-o'
77			v.WINRC_SRC_F = '-i'
78
79