@@ -7,34 +7,190 @@ include_guard(GLOBAL)
77# Debug
88message (VERBOSE "rsp/debug module included" )
99
10+ include ("rsp/helpers" )
11+
1012if (NOT COMMAND "dump" )
1113
1214 #! dump : Outputs given variables' name and value
1315 #
16+ # Note: function outputs using cmake's WARNING message mode
17+ #
18+ # @see https://cmake.org/cmake/help/latest/command/message.html#general-messages
19+ # @see var_dump()
20+ #
1421 # @param ... Variables to output
1522 #
1623 function (dump)
17- foreach (var ${ARGN} )
18- message ("${var} = ${${var} }" )
19- endforeach ()
24+ var_dump(OUTPUT output PROPERTIES ${ARGN} )
25+
26+ # Attempt to keep the formatting - see details in rsp/output::output()
27+ string (ASCII 13 CR)
28+ set (formatted_output "${CR}${COLOR_WHITE} dump:${RESTORE} \n ${output} " )
29+ string (REPLACE "\n " "\n " formatted_output "${formatted_output} " )
2030
21- # Output as warning so that the developer is able to see call stack!
22- message (WARNING " ${CMAKE_CURRENT_FUNCTION} () called from ${CMAKE_CURRENT_LIST_FILE} " )
31+ message (WARNING "${formatted_output} " )
2332 endfunction ()
2433endif ()
2534
2635if (NOT COMMAND "dd" )
2736
28- #! dump and die: Outputs given variables' name and value and stops build
37+ #! dd: Outputs given variables' name and value and stops build (dump and die)
38+ #
39+ # Note: function outputs using cmake's FATAL_ERROR message mode
40+ #
41+ # @see https://cmake.org/cmake/help/latest/command/message.html#general-messages
42+ # @see var_dump()
2943 #
3044 # @param ... Variables to output
3145 #
3246 function (dd)
33- foreach (var ${ARGN} )
34- message ("${var} = ${${var} }" )
47+ var_dump(OUTPUT output PROPERTIES ${ARGN} )
48+
49+ # Attempt to keep the formatting - see details in rsp/output::output()
50+ string (ASCII 13 CR)
51+ set (formatted_output "${CR}${COLOR_WHITE} dd:${RESTORE} \n ${output} " )
52+ string (REPLACE "\n " "\n " formatted_output "${formatted_output} " )
53+
54+ message (FATAL_ERROR "${formatted_output} " )
55+ endfunction ()
56+ endif ()
57+
58+ if (NOT COMMAND "var_dump" )
59+
60+ #! var_dump : Outputs human-readable information about given properties
61+ #
62+ #
63+ # @param [OUTPUT <variable>] Optional - If specified, information is assigned to output variable
64+ # instead of being printed to stderr.
65+ # @param [PROPERTIES <variable>...] One or more variables to dump information about.
66+ # @param [WITHOUT_NAMES] Option, if given then property names are omitted from the output
67+ # @param [IGNORE_LIST] Option, if specified the variable values of the type "list" are
68+ # treated as "string".
69+ #
70+ # @return
71+ # [OUTPUT] The resulting output variable, if OUTPUT was specified.
72+ #
73+ function (var_dump)
74+ set (options WITHOUT_NAMES IGNORE_LIST)
75+ set (oneValueArgs OUTPUT )
76+ set (multiValueArgs PROPERTIES)
77+
78+ cmake_parse_arguments (INPUT "${options} " "${oneValueArgs} " "${multiValueArgs} " ${ARGN} )
79+ requires_arguments("PROPERTIES" INPUT )
80+
81+ # ---------------------------------------------------------------------------------------------- #
82+
83+ set (buffer "" )
84+
85+ foreach (key IN LISTS INPUT_PROPERTIES)
86+ # Attempt to resolve value and it's datatype
87+ set (value "${${key} }" )
88+ get_type("${key} " type )
89+
90+ # ---------------------------------------------------------------------------------------------- #
91+
92+ set (tmp_list_separator "<!list!>" )
93+ if (INPUT_IGNORE_LIST AND type STREQUAL "list" )
94+ # Debug
95+ #message("Ignoring list: ${key} | ${value}")
96+
97+ set (type "string" )
98+ string (REPLACE ";" "${tmp_list_separator} " value "${value} " )
99+ endif ()
100+
101+ # ---------------------------------------------------------------------------------------------- #
102+
103+ # If key is defined as an environment variable, the value
104+ # must be obtained via ENV{}.
105+ if (DEFINED ENV{${key} })
106+ set (value "$ENV{${key} }" )
107+ get_type("${value} " type )
108+ elseif (NOT DEFINED ${key} AND type STREQUAL "string" )
109+ # We ONLY deal with variables, meaning that if key isn't
110+ # defined, and the type is determined to be a string,
111+ # then we must assume that it's an undefined property!
112+
113+ set (type "${COLOR_RED}${TEXT_ITALIC} undefined${TEXT_ITALIC_RESTORE}${COLOR_DEFAULT} " )
114+ endif ()
115+
116+ # Format the value...
117+ if (type STREQUAL "string" )
118+ # Resolve string length, by ensuring to count the length of
119+ # the original value, without list separator replacement.
120+ set (tmp_str "${value} " )
121+ string (REPLACE "${tmp_list_separator} " ";" tmp_str "${tmp_str} " )
122+ string (LENGTH "${tmp_str} " str_length)
123+
124+ set (type "${type} ${str_length} " )
125+ set (value "${COLOR_GREEN} \" ${value} \" ${RESTORE} " )
126+ elseif (type STREQUAL "int" OR type STREQUAL "float" )
127+ set (value "${COLOR_BRIGHT_BLUE}${value}${RESTORE} " )
128+ elseif (type STREQUAL "bool" )
129+ set (value "${COLOR_CYAN}${value}${RESTORE} " )
130+ elseif (type STREQUAL "command" )
131+ set (value "${COLOR_BLUE}${key} ()${RESTORE} " )
132+ elseif (type STREQUAL "list" )
133+ list (LENGTH value lst_length)
134+ set (type "${type} ${lst_length} " )
135+ set (list_buffer "" )
136+
137+ set (i 0) # index counter
138+ foreach (item IN LISTS value )
139+ # Get property information about the "item", but without key name.
140+ # Also, ensure to ignore values of the type "list", to avoid
141+ # strange behaviour (caused by cmake's variable scopes...)
142+ set ("list_item_${i} " "${item} " )
143+ var_dump(OUTPUT list_item WITHOUT_NAMES IGNORE_LIST PROPERTIES "list_item_${i} " )
144+
145+ # Append to list buffer and increment the "index" counter.
146+ list (APPEND list_buffer "${COLOR_MAGENTA}${i} :${RESTORE} ${list_item} " )
147+ math (EXPR i "${i} +1" OUTPUT_FORMAT DECIMAL)
148+ endforeach ()
149+
150+ string (REPLACE ";" "\n " list_buffer "${list_buffer} " )
151+ set (value "[ \n ${list_buffer} \n ]" )
152+ endif ()
153+
154+ # Mark the key as cached, if needed...
155+ if (DEFINED CACHE {${key} })
156+ set (type "${type} , ${TEXT_ITALIC}${TEXT_BOLD} cached${TEXT_BOLD_RESTORE}${TEXT_ITALIC_RESTORE} " )
157+ endif ()
158+
159+ # Mark the key an environment variable, if needed...
160+ if (DEFINED ENV{${key} })
161+ set (type "${type} , ${TEXT_ITALIC}${TEXT_BOLD} ENV${TEXT_BOLD_RESTORE}${TEXT_ITALIC_RESTORE} " )
162+ endif ()
163+
164+ # The output format: <key> = (<type>) <value>
165+ # Unless key is omitted.
166+ set (formatted_key "${COLOR_BRIGHT_MAGENTA}${key}${RESTORE} = " )
167+ if (INPUT_WITHOUT_NAMES)
168+ set (formatted_key "" )
169+ endif ()
170+
171+ list (APPEND buffer "${formatted_key}${COLOR_WHITE} (${type}${COLOR_WHITE} )${RESTORE} ${value} " )
35172 endforeach ()
36173
37- # Output as fatal error to ensure that build stops.
38- message (FATAL_ERROR " ${CMAKE_CURRENT_FUNCTION} () called from ${CMAKE_CURRENT_LIST_FILE} " )
174+ # ---------------------------------------------------------------------------------------------- #
175+
176+ string (REPLACE ";" "\n " buffer "${buffer} " )
177+
178+ # Restore list value (as a string) if needed.
179+ if (INPUT_IGNORE_LIST)
180+ string (REPLACE "${tmp_list_separator} " ";" buffer "${buffer} " )
181+ endif ()
182+
183+ # ---------------------------------------------------------------------------------------------- #
184+
185+ # Assign to output variable, if requested and stop any further processing.
186+ if (DEFINED INPUT_OUTPUT)
187+ set ("${INPUT_OUTPUT} " "${buffer} " )
188+ return (PROPAGATE "${INPUT_OUTPUT} " )
189+ endif ()
190+
191+ # ---------------------------------------------------------------------------------------------- #
192+
193+ message (NOTICE "${buffer} " )
194+
39195 endfunction ()
40- endif ()
196+ endif ()
0 commit comments