Skip to content

Commit 7839f4d

Browse files
authored
Merge pull request #16 from rsps/redesign-safeguard-properties
Redesign safeguard properties
2 parents 1f51e73 + f830d5c commit 7839f4d

File tree

5 files changed

+52
-49
lines changed

5 files changed

+52
-49
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Project's root `CMakeLists.txt`.
1313
* `dependencies.cmake` and `dev-dependencies.cmake` scripts.
1414
* `CPM.cmake` script that downloads specified version of [CPM](https://github.com/cpm-cmake/CPM.cmake).
15-
* `fail_in_source_build()`, `extract_value()`, `requires_arguments()` and `safeguard_properties()` utils functions, in `helpers.cmake`.
15+
* `fail_in_source_build()`, `extract_value()`, `requires_arguments()` and `safeguard_properties()` utils, in `helpers.cmake`.
1616
* `dump()`, `dd()` and `var_dump()` in `debug.cmake`.
1717
* ANSI utils, in `output.cmake`
1818
* `semver_parse()`, `write_version_file` and `version_from_file()` utils, in `version.cmake`.

cmake/rsp/helpers.cmake

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,45 +90,28 @@ if (NOT COMMAND "safeguard_properties")
9090

9191
#! safeguard_properties : Invoke a "risky" callback whilst "safeguarding" properties
9292
#
93-
# Function copies the values of the specified properties, invokes the callback, and
94-
# restores the properties' values.
93+
# Macro copies the values of the specified properties, invokes the callback, and
94+
# restores the properties' original values.
9595
#
96-
# Caution: This function does NOT prevent properties from being force-cached.
96+
# Caution: This macro does NOT prevent properties from being force-cached.
9797
# Environment variables are NOT prevented changed.
9898
#
99-
# Alternatively, consider using cmake's `block()`.
99+
# Alternatively, consider using cmake's `block()` or a function with its own variable
100+
# scope.
100101
#
101102
# @see https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variables
102103
# @see https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#environment-variables
103104
# @see https://cmake.org/cmake/help/latest/command/block.html#block
104105
#
105-
# @param [CALLBACK <command>] Risky command or macro to be invoked.
106-
# @param [PROPERTIES <variable>...] One or more properties to safeguard.
106+
# @param <command> callback Risky command or macro to be invoked.
107+
# @param <list> properties List of variable names - variables to safeguard from
108+
# undesired value changes.
107109
#
108-
# @return
109-
# [PROPERTIES <variable>...] Restored properties
110-
#
111-
function(safeguard_properties)
112-
set(options "") # N/A
113-
set(oneValueArgs CALLBACK)
114-
set(multiValueArgs PROPERTIES)
115-
116-
cmake_parse_arguments(INPUT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
117-
requires_arguments("CALLBACK;PROPERTIES" INPUT)
118-
119-
# ---------------------------------------------------------------------------------------------- #
120-
121-
# Abort if callback not defined
122-
if (NOT COMMAND "${INPUT_CALLBACK}")
123-
message(FATAL_ERROR "Callback \"${INPUT_CALLBACK}()\" does not exist")
124-
endif ()
125-
126-
# ---------------------------------------------------------------------------------------------- #
127-
110+
macro(safeguard_properties callback properties)
128111
set(prefix "original_")
129112

130113
# Copy each provided property
131-
foreach (prop ${INPUT_PROPERTIES})
114+
foreach (prop ${properties})
132115
message(VERBOSE "Safeguarding: ${prop}, original value: ${${prop}}")
133116

134117
set("${prefix}${prop}" "${${prop}}")
@@ -137,17 +120,17 @@ if (NOT COMMAND "safeguard_properties")
137120
# ---------------------------------------------------------------------------------------------- #
138121

139122
# Invoke the risky callback
140-
message(VERBOSE "Invoking risky callback: ${INPUT_CALLBACK}")
141-
cmake_language(CALL "${INPUT_CALLBACK}")
123+
message(VERBOSE "Invoking risky callback: ${callback}")
124+
cmake_language(CALL "${callback}")
142125

143126
# ---------------------------------------------------------------------------------------------- #
144127

145128
# Restore each provided property
146-
foreach (prop ${INPUT_PROPERTIES})
129+
foreach (prop ${properties})
147130
message(VERBOSE "Restoring: ${prop} from: ${${prop}}, to original value: ${${prefix}${prop}}")
148131

149-
# Ensure that property is set on parent scope
150-
set("${prop}" "${${prefix}${prop}}" PARENT_SCOPE)
132+
# Restore property's original value
133+
set("${prop}" "${${prefix}${prop}}")
151134
endforeach ()
152-
endfunction()
135+
endmacro()
153136
endif ()

dependencies.cmake

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55
include_guard()
66

7-
function(install_dependencies)
7+
macro(install_dependencies)
88
message(VERBOSE "Installing Dependencies for ${PROJECT_NAME}")
99

1010
# Avoid building tests for dependencies...
1111
set(BUILD_TESTING off)
1212

1313
# Add dependencies here...
1414
message(VERBOSE " N/A")
15-
16-
endfunction()
17-
safeguard_properties(CALLBACK "install_dependencies" PROPERTIES BUILD_TESTING)
15+
endmacro()
16+
safeguard_properties("install_dependencies" "BUILD_TESTING")

dev-dependencies.cmake

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ include_guard()
77
# Include regular dependencies
88
include("dependencies.cmake")
99

10-
function(install_dev_dependencies)
10+
macro(install_dev_dependencies)
1111
message(VERBOSE "Installing Development Dependencies for ${PROJECT_NAME}")
1212

1313
# Avoid building tests for dependencies...
1414
set(BUILD_TESTING off)
1515

1616
# Add dev-dependencies here...
1717
message(VERBOSE " N/A")
18-
19-
endfunction()
20-
safeguard_properties(CALLBACK "install_dev_dependencies" PROPERTIES BUILD_TESTING)
18+
endmacro()
19+
safeguard_properties("install_dev_dependencies" "BUILD_TESTING")
Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
include("rsp/testing")
22
include("rsp/helpers")
3+
include("rsp/debug")
34

45
define_test_case(
56
"Safeguard Properties Test"
@@ -13,18 +14,14 @@ function(can_safeguard_properties)
1314
set(c "ccc")
1415

1516
function(risky_callback)
17+
message(VERBOSE "risky callback invoked (function)")
18+
1619
set(a "1" PARENT_SCOPE)
1720
set(b "2" PARENT_SCOPE)
1821
set(c "3" PARENT_SCOPE)
1922
endfunction()
2023

21-
safeguard_properties(
22-
CALLBACK "risky_callback"
23-
PROPERTIES
24-
a
25-
b
26-
c
27-
)
24+
safeguard_properties("risky_callback" "a;b;c")
2825

2926
# Debug
3027
#risky_callback()
@@ -33,3 +30,28 @@ function(can_safeguard_properties)
3330
assert_string_equals("bbb" ${b} MESSAGE "Property b was modified")
3431
assert_string_equals("ccc" ${c} MESSAGE "Property c was modified")
3532
endfunction()
33+
34+
define_test("unguarded properties can be changed" "unguarded_properties_can_be_changed")
35+
function(unguarded_properties_can_be_changed)
36+
set(a "aaa")
37+
set(b "bbb")
38+
set(c "ccc")
39+
40+
macro(risky_callback)
41+
message(NOTICE "risky callback invoked (macro)")
42+
43+
set(a "1")
44+
set(b "2")
45+
set(c "3")
46+
endmacro()
47+
48+
# Note: "c" is NOT safeguarded here
49+
safeguard_properties("risky_callback" "a;b")
50+
51+
# Debug
52+
#risky_callback()
53+
54+
assert_string_equals("aaa" ${a} MESSAGE "Property a was modified")
55+
assert_string_equals("bbb" ${b} MESSAGE "Property b was modified")
56+
assert_string_equals("3" ${c} MESSAGE "Property c SHOULD had been modified")
57+
endfunction()

0 commit comments

Comments
 (0)