1# Rules without side effects.
2
3# Vanilla Jam compatibility
4if ! $(INVOCATION_SUBDIR_SET) {
5	rule FIsPrefix
6	{
7		# FIsPrefix <a> : <b> ;
8		# Returns true, if list <a> is a prefix (a proper one or equal) of
9		# list <b>, an empty list otherwise.
10		local a = $(1) ;
11		local b = $(2) ;
12		while $(a) && $(a[1]) = $(b[1]) {
13			a = $(a[2-]) ;
14			b = $(b[2-]) ;
15		}
16
17		if $(a) {
18			return ;
19		} else {
20			return true ;
21		}
22	}
23
24	rule LocalClean { Clean $(1) : $(2) ; }
25
26	rule LocalDepends { Depends $(1) : $(2) ; }
27
28} # vanilla Jam compatibility
29
30rule FFilter
31{
32	# FFilter <list> : <excludes> ;
33	# Removes all occurrences of <excludes> in <list>.
34
35	local list = $(1) ;
36	local excludes = $(2) ;
37	local newList ;
38	local item ;
39	for item in $(list) {
40		local skip ;
41		local exclude ;
42		for exclude in $(excludes) {
43			if $(item) = $(exclude) {
44				skip = true ;
45			}
46		}
47		if ! $(skip) {
48			newList += $(item) ;
49		}
50	}
51	return $(newList) ;
52}
53
54rule FGetGrist
55{
56	# FGetGrist <target> ;
57	#
58	# Returns the grist of a target, not including leading "<" and trailing ">".
59
60	local grist = $(1[1]:G) ;
61	if ! $(grist) {
62		return ;
63	}
64
65	return [ Match <(.*)> : $(grist) ] ;
66}
67
68rule FSplitString string : delimiterChar
69{
70	local result ;
71
72	while $(string) {
73		local split = [ Match $(delimiterChar)*([^$(delimiterChar)]+)(.*)
74			: $(string) ] ;
75		result += $(split[1]) ;
76		string = $(split[2-]) ;
77	}
78
79	return $(result) ;
80}
81
82rule FSplitPath
83{
84	# SplitPath <path> ;
85	# Decomposes a path into its components.
86	local path = $(1:G=) ;
87	local components ;
88	# $(path:D) for "/" is "/". Therefore the second condition.
89	while $(path:D) && $(path:D) != $(path)
90	{
91		# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
92		components = $(path:D=) $(components) ;
93		path = $(path:D) ;
94	}
95	components = $(path) $(components) ;
96	return $(components) ;
97}
98
99
100rule FSetConditionsHold conditions : set
101{
102	# FSetConditionsHold <conditions> : <set> ;
103	# Checks whether the conditions <conditions> are satisfied by the list of
104	# elements <set> and returns a respective result (if so: "1", if not: empty
105	# list). The conditions are satisfied when <conditions> is not empty and
106	# * none of the negative conditions it contains hold and
107	# * if <conditions> contains any positive conditions, at least one one of
108	#   those holds.
109	# A positive condition is an element not starting with a "!". It holds when
110	# the element is contained in <set>.
111	# A negative condition is an element that starts with a "!". It holds when
112	# the string resulting from removing the leading "!" is not contained in
113	# <set>.
114	#
115	# <conditions> - The list of conditions.
116	# <set> - The elements against which the conditions are tested.
117	#
118	# Examples:
119	# For set { a b c } the following conditions hold:
120	# { a }, { a d }, { !d }, { !d !e }, { a !d }, { b !e !f }
121	# The following conditions don't hold:
122	# { }, { d }, { d e }, { !a }, { !a b }, { !d e } { a b !c !d }
123
124	local hasPositive ;
125	local hasNegative ;
126	local positiveMatch ;
127	local condition ;
128	for condition in $(conditions) {
129		switch $(condition) {
130			case !* :
131			{
132				hasNegative = 1 ;
133				condition = [ Match "!(.*)" : $(condition) ] ;
134				if $(condition) in $(set) {
135					return ;
136				}
137			}
138			case * :
139			{
140				hasPositive = 1 ;
141				if $(condition) in $(set) {
142					positiveMatch = 1 ;
143				}
144			}
145		}
146	}
147
148	if $(hasPositive) {
149		return $(positiveMatch) ;
150	}
151	return $(hasNegative) ;
152}
153
154
155rule SetPlatformCompatibilityFlagVariables
156{
157	# SetPlatformCompatibilityFlagVariables <platform var> : <var prefix>
158	#	: <platform kind> [ : other platforms ] ;
159
160	local platformVar = $(1) ;
161	local platform = $($(platformVar)) ;
162	local varPrefix = $(2) ;
163	local platformKind = $(3) ;
164	local otherPlatforms = $(4) ;
165
166	if ! $(platform) {
167		ECHO "Variable $(platformVar) not set. Please run ./configure or" ;
168		EXIT "specify it manually." ;
169	}
170
171	# special case: Haiku libbe.so built for testing under BeOS
172	if $(platform) = libbe_test {
173		platform = $(HOST_PLATFORM) ;
174	}
175
176	$(varPrefix)_PLATFORM_BEOS_COMPATIBLE = ;
177	$(varPrefix)_PLATFORM_BONE_COMPATIBLE = ;
178	$(varPrefix)_PLATFORM_DANO_COMPATIBLE = ;
179	$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = ;
180
181	switch $(platform)
182	{
183		case r5 :
184		{
185			$(varPrefix)_PLATFORM_BEOS_COMPATIBLE = true ;
186		}
187
188		case bone :
189		{
190			$(varPrefix)_PLATFORM_BONE_COMPATIBLE = true ;
191		}
192
193		case dano :
194		{
195			$(varPrefix)_PLATFORM_DANO_COMPATIBLE = true ;
196		}
197
198		case haiku_host :
199		{
200			$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;
201		}
202
203		case haiku :
204		{
205			$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;
206		}
207
208		case * :
209		{
210			if ! ( $(platform) in $(otherPlatforms) ) {
211				Exit Unsupported $(platformKind) platform: $(platform) ;
212			}
213		}
214	}
215
216	# set lesser flags, e.g. "DANO" for "HAIKU" and "BEOS" for "BONE"
217	$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE
218		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
219	$(varPrefix)_PLATFORM_DANO_COMPATIBLE
220		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
221	$(varPrefix)_PLATFORM_BONE_COMPATIBLE
222		?= $($(varPrefix)_PLATFORM_DANO_COMPATIBLE) ;
223	$(varPrefix)_PLATFORM_BEOS_COMPATIBLE
224		?= $($(varPrefix)_PLATFORM_BONE_COMPATIBLE) ;
225
226	# set the machine friendly flags
227	$(varPrefix)_PLATFORM_(haiku)_COMPATIBLE
228		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
229	$(varPrefix)_PLATFORM_(haiku_host)_COMPATIBLE
230		?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;
231	$(varPrefix)_PLATFORM_(dano)_COMPATIBLE
232		?= $($(varPrefix)_PLATFORM_DANO_COMPATIBLE) ;
233	$(varPrefix)_PLATFORM_(bone)_COMPATIBLE
234		?= $($(varPrefix)_PLATFORM_BONE_COMPATIBLE) ;
235	$(varPrefix)_PLATFORM_(r5)_COMPATIBLE
236		?= $($(varPrefix)_PLATFORM_BEOS_COMPATIBLE) ;
237
238	$(varPrefix)_PLATFORM_(libbe_test)_COMPATIBLE
239		?= $($(varPrefix)_PLATFORM_BEOS_COMPATIBLE) ;
240}
241
242rule FAnalyzeGCCVersion
243{
244	# FAnalyzeGCCVersion <rawVersionVariable> ;
245	#
246	local varName = $(1) ;
247	local rawVersion = $($(varName)) ;
248
249	if ! $(rawVersion) {
250		ECHO "Variable $(varName) not set. Please run ./configure or" ;
251		EXIT "specify it manually." ;
252	}
253
254	local version = ;
255	# split the raw version string at `.' and `-' characters
256	while $(rawVersion) {
257		local split = [ Match "([^.-]*)[.-](.*)" : $(rawVersion) ] ;
258		if $(split) {
259			version += $(split[1]) ;
260			rawVersion = $(split[2]) ;
261		} else {
262			version += $(rawVersion) ;
263			rawVersion = ;
264		}
265	}
266
267	return $(version) ;
268}
269
270rule SetIncludePropertiesVariables
271{
272	# SetIncludePropertiesVariables <varPrefix> ;
273	#
274	local prefix = $(1) ;
275	if $($(prefix)_GCC_VERSION[1]) < 4 {
276		$(prefix)_INCLUDES_SEPARATOR = -I- ;
277		$(prefix)_LOCAL_INCLUDES_OPTION = -I ;
278		$(prefix)_SYSTEM_INCLUDES_OPTION = -I ;
279	} else {
280		$(prefix)_INCLUDES_SEPARATOR = ;
281		$(prefix)_LOCAL_INCLUDES_OPTION = "-iquote " ;
282		$(prefix)_SYSTEM_INCLUDES_OPTION = "-I " ;
283	}
284}
285
286
287#pragma mark -
288
289rule SetPlatformForTarget
290{
291	# SetPlatformForTarget <target> : <platform> ;
292
293	PLATFORM on $(1) = $(2) ;
294}
295
296rule SetSubDirPlatform
297{
298	# SetSubDirPlatform <platform> ;
299
300	PLATFORM = $(1) ;
301}
302
303rule SetSupportedPlatformsForTarget
304{
305	# SetSupportedPlatformsForTarget <target> : <platforms> ;
306
307	SUPPORTED_PLATFORMS on $(1) = $(2) ;
308}
309
310rule SetSubDirSupportedPlatforms
311{
312	# SetSubDirSupportedPlatforms <platforms> ;
313
314	SUPPORTED_PLATFORMS = $(1) ;
315}
316
317rule AddSubDirSupportedPlatforms
318{
319	# AddSubDirSupportedPlatforms <platforms> ;
320
321	SUPPORTED_PLATFORMS += $(1) ;
322}
323
324rule SetSubDirSupportedPlatformsBeOSCompatible
325{
326	# SetSubDirSupportedPlatformsBeOSCompatible ;
327
328	SUPPORTED_PLATFORMS = $(HAIKU_BEOS_COMPATIBLE_PLATFORMS) ;
329}
330
331rule IsPlatformSupportedForTarget
332{
333	# IsPlatformSupportedForTarget <target> [ : <platform> ]
334	#
335
336	on $(1) {
337		if $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
338			return true ;
339		} else {
340			return ;
341		}
342	}
343}
344
345rule InheritPlatform
346{
347	# InheritPlatform <children> : <parent> ;
348	# PLATFORM and SUPPORTED_PLATFORMS are set on <children> to their value
349	# on <parent>.
350	#
351	local children = $(1) ;
352	local parent = $(2) ;
353
354	on $(parent) {
355		PLATFORM on $(children) = $(PLATFORM) ;
356		SUPPORTED_PLATFORMS on $(children) = $(SUPPORTED_PLATFORMS) ;
357	}
358}
359
360rule SubDirAsFlags
361{
362        SUBDIRASFLAGS += $(<) ;
363}
364
365