Skip to content

Commit b2a5b10

Browse files
committed
Add types sub-module
Utils to determine the type of a target value
1 parent 40a7d56 commit b2a5b10

File tree

2 files changed

+357
-0
lines changed

2 files changed

+357
-0
lines changed

cmake/rsp/helpers.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ include_guard(GLOBAL)
77
# Debug
88
message(VERBOSE "rsp/helpers module included")
99

10+
include("rsp/helpers/types")
11+
1012
if (NOT COMMAND "fail_in_source_build")
1113

1214
#! fail_in_source_build : Fails when building project in the source directory

cmake/rsp/helpers/types.cmake

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
# -------------------------------------------------------------------------------------------------------------- #
2+
# Types
3+
# -------------------------------------------------------------------------------------------------------------- #
4+
5+
include_guard(GLOBAL)
6+
7+
# Debug
8+
message(VERBOSE "rsp/helpers/types module included")
9+
10+
if (NOT COMMAND "is_int")
11+
12+
#! is_int : Determine if value is an integer
13+
#
14+
# @param <mixed> target_value The value in question
15+
# @param <variable> output The variable to assign extracted result to
16+
#
17+
# @return
18+
# output True or false
19+
#
20+
function(is_int target_value output)
21+
set("${output}" false)
22+
23+
# Resolve "value" from variable
24+
if (DEFINED "${target_value}")
25+
set(target_value "${${target_value}}")
26+
endif ()
27+
28+
if (target_value MATCHES "^([\-\+]?)([0-9]+)$")
29+
set("${output}" true)
30+
endif ()
31+
32+
return(PROPAGATE "${output}")
33+
endfunction()
34+
endif ()
35+
36+
if (NOT COMMAND "is_float")
37+
38+
#! is_float : Determine if value is a float
39+
#
40+
# @param <mixed> target_value The value in question
41+
# @param <variable> output The variable to assign extracted result to
42+
#
43+
# @return
44+
# output True or false
45+
#
46+
function(is_float target_value output)
47+
set("${output}" false)
48+
49+
# Resolve "value" from variable
50+
if (DEFINED "${target_value}")
51+
set(target_value "${${target_value}}")
52+
endif ()
53+
54+
if (target_value MATCHES "^([\-\+]?)([0-9]+)\.([0-9]+)$")
55+
set("${output}" true)
56+
endif ()
57+
58+
return(PROPAGATE "${output}")
59+
endfunction()
60+
endif ()
61+
62+
if (NOT COMMAND "is_numeric")
63+
64+
#! is_numeric : Determine if value is numeric
65+
#
66+
# @param <mixed> target_value The value in question
67+
# @param <variable> output The variable to assign extracted result to
68+
#
69+
# @return
70+
# output True or false
71+
#
72+
function(is_numeric target_value output)
73+
set("${output}" false)
74+
75+
# Resolve "value" from variable
76+
if (DEFINED "${target_value}")
77+
set(target_value "${${target_value}}")
78+
endif ()
79+
80+
if (target_value MATCHES "^([\-\+]?)([0-9]+)$" OR target_value MATCHES "^([\-\+]?)([0-9]+)\.([0-9]+)$")
81+
set("${output}" true)
82+
endif ()
83+
84+
return(PROPAGATE "${output}")
85+
endfunction()
86+
endif ()
87+
88+
if (NOT COMMAND "is_bool")
89+
90+
#! is_bool : Determine if value is a boolean
91+
#
92+
# Caution: Function only recognises `true` and `false` as
93+
# boolean values.
94+
#
95+
# @see is_bool_like()
96+
#
97+
# @param <mixed> target_value The value in question
98+
# @param <variable> output The variable to assign extracted result to
99+
#
100+
# @return
101+
# output True or false
102+
#
103+
function(is_bool target_value output)
104+
set("${output}" false)
105+
106+
# Resolve "value" from variable
107+
if (DEFINED "${target_value}")
108+
set(target_value "${${target_value}}")
109+
endif ()
110+
111+
set(accepted "true;false")
112+
string(TOLOWER "${target_value}" target_value)
113+
114+
if (target_value IN_LIST accepted)
115+
set("${output}" true)
116+
endif ()
117+
118+
return(PROPAGATE "${output}")
119+
endfunction()
120+
endif ()
121+
122+
if (NOT COMMAND "is_bool_like")
123+
124+
#! is_bool_like : Determine if value is a boolean
125+
#
126+
# Caution: Function recognises all values that cmake can
127+
# evaluate as truthy or falsy.
128+
#
129+
# @see https://cmake.org/cmake/help/latest/command/if.html#constant
130+
# @see https://cmake.org/cmake/help/latest/command/if.html#logic-operators
131+
#
132+
# @param <mixed> target_value The value in question
133+
# @param <variable> output The variable to assign extracted result to
134+
#
135+
# @return
136+
# output True or false
137+
#
138+
function(is_bool_like target_value output)
139+
set("${output}" false)
140+
141+
# Resolve "value" from variable
142+
if (DEFINED "${target_value}")
143+
set(target_value "${${target_value}}")
144+
endif ()
145+
146+
# ...a non-zero number (including floating point numbers) is also considered
147+
# to be boolean (true).
148+
# NOTE: negative values DO NOT evaluate to false!
149+
is_numeric("${target_value}" is_num)
150+
if (is_num AND "${target_value}" GREATER_EQUAL 0)
151+
set("${output}" true)
152+
return(PROPAGATE "${output}")
153+
endif ()
154+
155+
set(accepted "on;yes;true;y;off;0;no;false;n;ignore;notfound")
156+
string(TOLOWER "${target_value}" target_value)
157+
string(LENGTH "${target_value}" length)
158+
159+
if (target_value IN_LIST accepted OR length EQUAL 0 OR target_value MATCHES "-notfound$")
160+
set("${output}" true)
161+
endif ()
162+
163+
return(PROPAGATE "${output}")
164+
endfunction()
165+
endif ()
166+
167+
if (NOT COMMAND "is_list")
168+
169+
#! is_list : Determine if value is a list of values
170+
#
171+
# @see https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#cmake-language-lists
172+
# @see https://cmake.org/cmake/help/latest/command/list.html
173+
#
174+
# @param <mixed> target_value The value in question
175+
# @param <variable> output The variable to assign extracted result to
176+
#
177+
# @return
178+
# output True or false
179+
#
180+
function(is_list target_value output)
181+
set("${output}" false)
182+
183+
# Resolve "value" from variable
184+
if (DEFINED "${target_value}")
185+
set(target_value "${${target_value}}")
186+
endif ()
187+
188+
string(FIND "${target_value}" ";" has_separator)
189+
list(LENGTH target_value length)
190+
191+
if (NOT has_separator EQUAL -1 AND length GREATER 0)
192+
set("${output}" true)
193+
endif ()
194+
195+
return(PROPAGATE "${output}")
196+
endfunction()
197+
endif ()
198+
199+
if (NOT COMMAND "is_command")
200+
201+
#! is_command : Determine if value is command, macro or function
202+
#
203+
# @see https://cmake.org/cmake/help/latest/command/if.html#command
204+
#
205+
# @param <mixed> target_value The value in question
206+
# @param <variable> output The variable to assign extracted result to
207+
#
208+
# @return
209+
# output True or false
210+
#
211+
function(is_command target_value output)
212+
set("${output}" false)
213+
214+
# Resolve "value" from variable
215+
if (DEFINED "${target_value}")
216+
set(target_value "${${target_value}}")
217+
endif ()
218+
219+
if (COMMAND "${target_value}")
220+
set("${output}" true)
221+
endif ()
222+
223+
return(PROPAGATE "${output}")
224+
endfunction()
225+
endif ()
226+
227+
if (NOT COMMAND "is_string")
228+
229+
#! is_string : Determine if value is a string
230+
#
231+
# Warning: This function evaluates only to true, if given value
232+
# is:
233+
# - not numeric
234+
# - not a boolean (true or false)
235+
# - not a list (semicolon separated list)
236+
# - not a command
237+
#
238+
# @see https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variables
239+
# @see is_numeric()
240+
# @see is_bool()
241+
# @see is_list()
242+
# @see is_command()
243+
#
244+
# @param <mixed> target_value The value in question
245+
# @param <variable> output The variable to assign extracted result to
246+
#
247+
# @return
248+
# output True or false
249+
#
250+
function(is_string target_value output)
251+
set("${output}" false)
252+
253+
# Resolve "value" from variable
254+
if (DEFINED "${target_value}")
255+
set(target_value "${${target_value}}")
256+
endif ()
257+
258+
is_numeric("${target_value}" num)
259+
is_bool("${target_value}" bool)
260+
is_list("${target_value}" lst)
261+
is_command("${target_value}" cmd)
262+
263+
if (NOT num
264+
AND NOT bool
265+
AND NOT lst
266+
AND NOT cmd
267+
)
268+
set("${output}" true)
269+
endif ()
270+
271+
return(PROPAGATE "${output}")
272+
endfunction()
273+
endif ()
274+
275+
if (NOT COMMAND "get_type")
276+
277+
#! get_type : Determine the type of given value
278+
#
279+
# @see is_int()
280+
# @see is_float()
281+
# @see is_bool()
282+
# @see is_list()
283+
# @see is_command()
284+
# @see is_string()
285+
#
286+
# @param <mixed> target_value The value in question
287+
# @param <variable> output The variable to assign extracted result to
288+
#
289+
# @return
290+
# output String representation of the type (int, float, bool, list, command, or string).
291+
# @throws If unable to determine target value's type
292+
#
293+
#
294+
function(get_type target_value output)
295+
set("${output}" "undefined")
296+
297+
# Resolve "value" from variable
298+
if (DEFINED "${target_value}")
299+
set(target_value "${${target_value}}")
300+
endif ()
301+
302+
# ---------------------------------------------------------------------------------------------- #
303+
304+
is_string("${target_value}" str)
305+
if (str)
306+
set("${output}" "string")
307+
return(PROPAGATE "${output}")
308+
endif ()
309+
310+
# ---------------------------------------------------------------------------------------------- #
311+
312+
is_int("${target_value}" int)
313+
if (int)
314+
set("${output}" "int")
315+
return(PROPAGATE "${output}")
316+
endif ()
317+
318+
# ---------------------------------------------------------------------------------------------- #
319+
320+
is_float("${target_value}" float)
321+
if (float)
322+
set("${output}" "float")
323+
return(PROPAGATE "${output}")
324+
endif ()
325+
326+
# ---------------------------------------------------------------------------------------------- #
327+
328+
is_bool("${target_value}" bool)
329+
if (bool)
330+
set("${output}" "bool")
331+
return(PROPAGATE "${output}")
332+
endif ()
333+
334+
# ---------------------------------------------------------------------------------------------- #
335+
336+
is_list("${target_value}" lst)
337+
if (lst)
338+
set("${output}" "list")
339+
return(PROPAGATE "${output}")
340+
endif ()
341+
342+
# ---------------------------------------------------------------------------------------------- #
343+
344+
is_command("${target_value}" cmd)
345+
if (cmd)
346+
set("${output}" "command")
347+
return(PROPAGATE "${output}")
348+
endif ()
349+
350+
# ---------------------------------------------------------------------------------------------- #
351+
# Fail in case that the type cannot be determined!
352+
353+
message(FATAL_ERROR "Unable to determine type of target value: ${target_value}")
354+
endfunction()
355+
endif ()

0 commit comments

Comments
 (0)