ceedling 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/README.md +1 -1
  4. data/assets/fake_crash_test_fixture.rb +14 -0
  5. data/assets/partial_all_module.h +11 -0
  6. data/assets/run_with_ubsan.rb +15 -0
  7. data/assets/same_dir_pairing_module.c +4 -0
  8. data/assets/same_dir_pairing_module.h +8 -0
  9. data/assets/same_dir_pairing_module_func.h +6 -0
  10. data/assets/same_dir_pairing_other.c +4 -0
  11. data/assets/same_dir_pairing_other.h +8 -0
  12. data/assets/test_example_file_crash_sigsegv_with_param.c +32 -0
  13. data/assets/test_example_file_ub_shift_overflow.c +22 -0
  14. data/assets/test_partial_all_module.c +16 -0
  15. data/assets/test_same_dir_pairing.c +23 -0
  16. data/bin/actions_wrapper.rb +7 -6
  17. data/docs/Changelog.md +29 -1
  18. data/docs/mkdocs/configuration/reference/index.md +8 -0
  19. data/docs/mkdocs/configuration/reference/partials.md +38 -0
  20. data/examples/wondrous_forest/src/LightSensor.c +21 -4
  21. data/examples/wondrous_forest/src/LightSensor.h +12 -4
  22. data/examples/wondrous_forest/test/TestLightSensor.c +34 -4
  23. data/lib/ceedling/c_extractor/c_extractor.rb +37 -11
  24. data/lib/ceedling/c_extractor/c_extractor_constants.rb +0 -3
  25. data/lib/ceedling/c_extractor/c_extractor_declarations.rb +26 -25
  26. data/lib/ceedling/c_extractor/c_extractor_functions.rb +5 -12
  27. data/lib/ceedling/config/configurator.rb +8 -1
  28. data/lib/ceedling/config/configurator_setup.rb +26 -0
  29. data/lib/ceedling/defaults.rb +16 -2
  30. data/lib/ceedling/file_path_utils.rb +7 -0
  31. data/lib/ceedling/file_wrapper.rb +8 -0
  32. data/lib/ceedling/generators/generator.rb +15 -0
  33. data/lib/ceedling/generators/generator_helper.rb +25 -6
  34. data/lib/ceedling/generators/generator_partials.rb +84 -3
  35. data/lib/ceedling/generators/generator_test_results_backtrace.rb +268 -100
  36. data/lib/ceedling/generators/generator_test_runner.rb +20 -2
  37. data/lib/ceedling/includes/includes.rb +66 -11
  38. data/lib/ceedling/objects.yml +5 -0
  39. data/lib/ceedling/partials/partializer.rb +18 -3
  40. data/lib/ceedling/partials/partializer_utils.rb +6 -1
  41. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +43 -16
  42. data/lib/ceedling/test_invoker/test_build_executor.rb +19 -8
  43. data/lib/version.rb +1 -1
  44. data/mkdocs.yml +1 -0
  45. data/plugins/gcov/lib/gcov.rb +2 -2
  46. data/site-local/404.html +30 -0
  47. data/site-local/configuration/environment-vars.html +30 -0
  48. data/site-local/configuration/global-collections.html +30 -0
  49. data/site-local/configuration/index.html +30 -0
  50. data/site-local/configuration/loading.html +30 -0
  51. data/site-local/configuration/mixins.html +30 -0
  52. data/site-local/configuration/parallel-builds.html +30 -0
  53. data/site-local/configuration/project-file.html +30 -0
  54. data/site-local/configuration/reference/cexception.html +30 -0
  55. data/site-local/configuration/reference/cmock.html +30 -0
  56. data/site-local/configuration/reference/defines.html +30 -0
  57. data/site-local/configuration/reference/environment.html +30 -0
  58. data/site-local/configuration/reference/extension.html +30 -0
  59. data/site-local/configuration/reference/files.html +30 -0
  60. data/site-local/configuration/reference/flags.html +30 -0
  61. data/site-local/configuration/reference/index.html +36 -0
  62. data/site-local/configuration/reference/libraries.html +30 -0
  63. data/site-local/configuration/reference/mixins.html +30 -0
  64. data/site-local/configuration/reference/partials.html +4257 -0
  65. data/site-local/configuration/reference/paths.html +30 -0
  66. data/site-local/configuration/reference/plugins.html +30 -0
  67. data/site-local/configuration/reference/project.html +30 -0
  68. data/site-local/configuration/reference/release-build.html +31 -1
  69. data/site-local/configuration/reference/test-build.html +31 -1
  70. data/site-local/configuration/reference/test-runner.html +30 -0
  71. data/site-local/configuration/reference/tools.html +30 -0
  72. data/site-local/configuration/reference/unity.html +30 -0
  73. data/site-local/configuration/which-ceedling.html +30 -0
  74. data/site-local/development/index.html +30 -0
  75. data/site-local/development/plugins/configuration.html +30 -0
  76. data/site-local/development/plugins/index.html +30 -0
  77. data/site-local/development/plugins/plugin-subclass.html +30 -0
  78. data/site-local/development/plugins/rake-tasks.html +30 -0
  79. data/site-local/development/workflow.html +30 -0
  80. data/site-local/getting-started/command-line.html +30 -0
  81. data/site-local/getting-started/example-projects/cipher-quest.html +30 -0
  82. data/site-local/getting-started/example-projects/index.html +30 -0
  83. data/site-local/getting-started/example-projects/temp-sensor.html +30 -0
  84. data/site-local/getting-started/example-projects/wondrous-forest.html +30 -0
  85. data/site-local/getting-started/index.html +30 -0
  86. data/site-local/getting-started/installation.html +30 -0
  87. data/site-local/getting-started/quick-start.html +30 -0
  88. data/site-local/help.html +30 -0
  89. data/site-local/index.html +30 -0
  90. data/site-local/overview/build-system.html +30 -0
  91. data/site-local/overview/index.html +30 -0
  92. data/site-local/overview/test-environments.html +30 -0
  93. data/site-local/overview/tools-and-frameworks.html +30 -0
  94. data/site-local/plugins/beep.html +30 -0
  95. data/site-local/plugins/bullseye.html +30 -0
  96. data/site-local/plugins/command-hooks.html +30 -0
  97. data/site-local/plugins/compile-commands-json-db.html +30 -0
  98. data/site-local/plugins/cppcheck.html +30 -0
  99. data/site-local/plugins/dependencies.html +30 -0
  100. data/site-local/plugins/fff.html +30 -0
  101. data/site-local/plugins/gcov/examples.html +30 -0
  102. data/site-local/plugins/gcov/gcovr.html +30 -0
  103. data/site-local/plugins/gcov/index.html +30 -0
  104. data/site-local/plugins/gcov/overview.html +30 -0
  105. data/site-local/plugins/gcov/reportgenerator.html +30 -0
  106. data/site-local/plugins/gcov/reporting.html +30 -0
  107. data/site-local/plugins/gcov/setup.html +30 -0
  108. data/site-local/plugins/gcov/tool-versions.html +30 -0
  109. data/site-local/plugins/gcov/troubleshooting.html +30 -0
  110. data/site-local/plugins/index.html +30 -0
  111. data/site-local/plugins/module-generator.html +30 -0
  112. data/site-local/plugins/report-build-warnings-log.html +30 -0
  113. data/site-local/plugins/report-tests-gtestlike-stdout.html +30 -0
  114. data/site-local/plugins/report-tests-ide-stdout.html +30 -0
  115. data/site-local/plugins/report-tests-log-factory.html +30 -0
  116. data/site-local/plugins/report-tests-pretty-stdout.html +30 -0
  117. data/site-local/plugins/report-tests-raw-output-log.html +30 -0
  118. data/site-local/plugins/report-tests-teamcity-stdout.html +30 -0
  119. data/site-local/plugins/valgrind.html +30 -0
  120. data/site-local/project/release-history.html +30 -0
  121. data/site-local/project/upgrade.html +30 -0
  122. data/site-local/reference/build-directives.html +30 -0
  123. data/site-local/reference/command-line.html +30 -0
  124. data/site-local/reference/environment-vars.html +30 -0
  125. data/site-local/reference/gcov-plugin.html +30 -0
  126. data/site-local/reference/global-collections.html +30 -0
  127. data/site-local/reference/index.html +30 -0
  128. data/site-local/reference/partials-macros.html +30 -0
  129. data/site-local/reference/project-configuration.html +30 -0
  130. data/site-local/sitemap.xml.gz +0 -0
  131. data/site-local/snapshot/examples/cipher_quest/index.html +30 -0
  132. data/site-local/snapshot/examples/temp_sensor/index.html +30 -0
  133. data/site-local/snapshot/examples/wondrous_forest/index.html +30 -0
  134. data/site-local/testing-guide/build-directives.html +30 -0
  135. data/site-local/testing-guide/conventions.html +30 -0
  136. data/site-local/testing-guide/frameworks.html +30 -0
  137. data/site-local/testing-guide/index.html +30 -0
  138. data/site-local/testing-guide/partials/configuration.html +30 -0
  139. data/site-local/testing-guide/partials/conventions.html +30 -0
  140. data/site-local/testing-guide/partials/directives.html +30 -0
  141. data/site-local/testing-guide/partials/example.html +30 -0
  142. data/site-local/testing-guide/partials/index.html +30 -0
  143. data/site-local/testing-guide/partials/overview.html +30 -0
  144. data/site-local/testing-guide/partials/variables.html +30 -0
  145. data/site-local/testing-guide/test-cases.html +30 -0
  146. data/site-local/testing-guide/test-sample.html +30 -0
  147. data/site-local/testing-guide/test-suite-anatomy.html +30 -0
  148. data/spec/support/system/spec_system_helper.rb +25 -0
  149. data/spec/support/system/system_context.rb +15 -0
  150. data/spec/system/deployment_as_gem_spec.rb +14 -0
  151. data/spec/system/deployment_as_vendor_spec.rb +19 -0
  152. data/spec/system/encoding_stress_spec.rb +4 -4
  153. data/spec/system/example_wondrous_forest_spec.rb +2 -2
  154. data/spec/system/support/common_test_cases.rb +227 -0
  155. data/spec/units/c_extractor/c_extractor_declarations_spec.rb +27 -4
  156. data/spec/units/c_extractor/c_extractor_functions_spec.rb +1 -11
  157. data/spec/units/c_extractor/c_extractor_integration_spec.rb +18 -11
  158. data/spec/units/c_extractor/c_extractor_spec.rb +57 -1
  159. data/spec/units/config/configurator_setup_spec.rb +61 -0
  160. data/spec/units/configurator_spec.rb +45 -0
  161. data/spec/units/file_path_utils_spec.rb +17 -0
  162. data/spec/units/generators/generator_helper_spec.rb +34 -7
  163. data/spec/units/generators/generator_partials_spec.rb +120 -12
  164. data/spec/units/generators/generator_test_results_backtrace_spec.rb +248 -41
  165. data/spec/units/generators/generator_test_runner_spec.rb +26 -2
  166. data/spec/units/includes/include_spec.rb +30 -18
  167. data/spec/units/includes/includes_spec.rb +100 -10
  168. data/spec/units/partials/partializer_spec.rb +113 -1
  169. data/spec/units/partials/partializer_utils_spec.rb +11 -0
  170. data/spec/units/preprocess/preprocessinator_includes_handler_spec.rb +96 -7
  171. data/spec/units/system_wrapper_spec.rb +72 -0
  172. data/spec/units/test_context_extractor_spec.rb +3 -3
  173. metadata +20 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70deeef4f895489e967caec64bb020696e41fa327c83785eed4fa553a1c7b8bb
4
- data.tar.gz: a3f48f487a174c6710601b693a44273542ca3934ae072d622994a19dd9d64884
3
+ metadata.gz: d8c20196572fb2d9730237fb04f7ab5d18869180b185e14649d1212669b1fd3f
4
+ data.tar.gz: b363d61a395c3a788fbe4566196d2ce6f6c49e5a8b00423f49c4df3fc2e3f2e1
5
5
  SHA512:
6
- metadata.gz: 8dcd78f2672ac8afcf375314ae458c0a734b000b0edae3aee34614492072aa2e53c5751ffbc15703b90e82527b1f740800a52231bf7922749df881c00aa3ed81
7
- data.tar.gz: 29bb2ceace5a9f6d20fbf0d3546a708c1a07677aa558681c95ba3cf7c4991a487edf29e58226a084d169ee700a290c09695aed9f8a8d04923eb39aac9ba90449
6
+ metadata.gz: 1c30b50264e5a459a19c0fca20b57fdc1e2e3cc6282b504f5789c2cec47fd9dc11d49cd05c5ecb8e09c47c6e1bb9b7029d74ce7714249abc9e00456ead5d1002
7
+ data.tar.gz: a83eddeb44b9049e361f94ef0280809f157f304c96631ef75ee7341302a34faed50ed4e616d1744e220dccad496872e0c2282b8f7d5e6c4c1e58c5be28fddf32
data/GIT_COMMIT_SHA CHANGED
@@ -1 +1 @@
1
- 6f17bf8
1
+ e44173e
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Ceedling ![CI](https://github.com/ThrowTheSwitch/Ceedling/workflows/CI/badge.svg)
2
2
  ========
3
3
 
4
- **Ceedling 1.1.2** is the latest and greatest.
4
+ **Ceedling 1.1.4** is the latest and greatest.
5
5
 
6
6
  See [_Release Notes_][release-notes], [_Changelog_](docs/Changelog.md),
7
7
  [_Breaking Changes_][breaking-changes], and [_Known Issues_][known-issues].
@@ -0,0 +1,14 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ # Deliberately ignores the real test executable path it's given and never runs it --
9
+ # simulates a custom :test_fixture wrapper whose own crash-detection machinery (e.g. a
10
+ # sanitizer's halt_on_error) kills the process before Unity ever gets to print its
11
+ # summary. Exists to reproduce issue #1198 without needing a real sanitizer toolchain:
12
+ # a diagnostic backtrace retry left at its default configuration runs the real
13
+ # executable directly instead, unaffected by this fixture, and legitimately passes.
14
+ exit 1
@@ -0,0 +1,11 @@
1
+ #ifndef PARTIAL_ALL_MODULE_H
2
+ #define PARTIAL_ALL_MODULE_H
3
+
4
+ void PartialAllModule_Init(int value);
5
+
6
+ static inline int PartialAllModule_DoubleValue(int value)
7
+ {
8
+ return value * 2;
9
+ }
10
+
11
+ #endif
@@ -0,0 +1,15 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ # Enables UBSan's halt-on-error, then execs the real test executable in this script's
9
+ # own place rather than as a child process -- this process's PID becomes the test
10
+ # executable's PID, so the real Process::Status Ceedling observes is the test
11
+ # executable's own. Regression fixture for issue #1198: a diagnostic backtrace retry
12
+ # runs through a separate, unwrapped default tool that never sees this setting, so it
13
+ # can legitimately recover from the same undefined behavior instead of halting on it.
14
+ ENV['UBSAN_OPTIONS'] = 'halt_on_error=1'
15
+ exec(*ARGV)
@@ -0,0 +1,4 @@
1
+ #include "same_dir_pairing_module_func.h"
2
+
3
+ void SameDirPairingModuleInit(void) {
4
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef SAME_DIR_PAIRING_MODULE_H
2
+ #define SAME_DIR_PAIRING_MODULE_H
3
+
4
+ typedef struct {
5
+ int value;
6
+ } same_dir_pairing_module_t;
7
+
8
+ #endif
@@ -0,0 +1,6 @@
1
+ #ifndef SAME_DIR_PAIRING_MODULE_FUNC_H
2
+ #define SAME_DIR_PAIRING_MODULE_FUNC_H
3
+
4
+ void SameDirPairingModuleInit(void);
5
+
6
+ #endif
@@ -0,0 +1,4 @@
1
+ #include "same_dir_pairing_other.h"
2
+
3
+ void SameDirPairingOtherThing(void) {
4
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef SAME_DIR_PAIRING_OTHER_H
2
+ #define SAME_DIR_PAIRING_OTHER_H
3
+
4
+ #include "same_dir_pairing_module.h"
5
+
6
+ void SameDirPairingOtherThing(void);
7
+
8
+ #endif
@@ -0,0 +1,32 @@
1
+ /* =========================================================================
2
+ Ceedling - Test-Centered Build System for C
3
+ ThrowTheSwitch.org
4
+ Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ SPDX-License-Identifier: MIT
6
+ ========================================================================= */
7
+
8
+ #include <signal.h>
9
+ #include "unity.h"
10
+ #include "example_file.h"
11
+
12
+
13
+ void setUp(void) {}
14
+ void tearDown(void) {}
15
+
16
+ void test_add_numbers_will_fail(void) {
17
+ // Platform-independent way of forcing a crash
18
+ // NOTE: Avoid `nullptr` as it is a keyword in C23
19
+ uint32_t* a_null_pointer = (void*)0;
20
+ uint32_t i = *a_null_pointer;
21
+ TEST_ASSERT_EQUAL_INT(2, add_numbers(i,2));
22
+ }
23
+
24
+ // Regression coverage for issue #1185: a parameterized test defined after a
25
+ // crashing test in the same file must still report its own real PASS/FAIL
26
+ // results rather than being swept up as "crashed" alongside the actual crash.
27
+ TEST_CASE(5, 3, 2)
28
+ TEST_CASE(10, 4, 6)
29
+ TEST_CASE(0, 0, 0)
30
+ void test_difference_between_numbers_is_correct(int a, int b, int expected) {
31
+ TEST_ASSERT_EQUAL_INT(expected, difference_between_numbers(a, b));
32
+ }
@@ -0,0 +1,22 @@
1
+ /* =========================================================================
2
+ Ceedling - Test-Centered Build System for C
3
+ ThrowTheSwitch.org
4
+ Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ SPDX-License-Identifier: MIT
6
+ ========================================================================= */
7
+
8
+ #include <stdint.h>
9
+
10
+ #include "unity.h"
11
+
12
+ void setUp(void) {}
13
+ void tearDown(void) {}
14
+
15
+ /* Left-shifting a value past its type's bit width is undefined behavior --
16
+ UBSan's -fsanitize=undefined flags it at runtime without a real crash
17
+ occurring at the OS level. */
18
+ void test_shift_overflow(void) {
19
+ volatile uint8_t value = 128;
20
+ volatile uint32_t result = value << 24;
21
+ (void)result;
22
+ }
@@ -0,0 +1,16 @@
1
+ #include "unity.h"
2
+ #include "ceedling.h"
3
+
4
+ #include MOCK_PARTIAL_ALL_MODULE(partial_all_module)
5
+
6
+ void setUp(void) {}
7
+ void tearDown(void) {}
8
+
9
+ void test_all_module_should_mock_both_a_plain_prototype_and_a_static_inline_function(void)
10
+ {
11
+ PartialAllModule_Init_Expect(3);
12
+ PartialAllModule_Init(3);
13
+
14
+ PartialAllModule_DoubleValue_ExpectAndReturn(3, 6);
15
+ TEST_ASSERT_EQUAL_INT(6, PartialAllModule_DoubleValue(3));
16
+ }
@@ -0,0 +1,23 @@
1
+ /* =========================================================================
2
+ Ceedling - Test-Centered Build System for C
3
+ ThrowTheSwitch.org
4
+ Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ SPDX-License-Identifier: MIT
6
+ ========================================================================= */
7
+
8
+ // `same_dir_pairing_other.h` transitively includes `same_dir_pairing_module.h` (types
9
+ // only), which shares a filename stem with `same_dir_pairing_module.c` -- the same
10
+ // source file that implements the differently-named header mocked below. Auto
11
+ // source-pairing must not pull that real source file into this build alongside its mock.
12
+
13
+ #include "unity.h"
14
+ #include "mock_same_dir_pairing_module_func.h"
15
+ #include "same_dir_pairing_other.h"
16
+
17
+ void setUp(void) {}
18
+ void tearDown(void) {}
19
+
20
+ void test_SameDirPairingOtherThing_should_not_explode(void) {
21
+ SameDirPairingOtherThing();
22
+ TEST_PASS();
23
+ }
@@ -13,16 +13,17 @@ class ActionsWrapper
13
13
  include Thor::Base
14
14
  include Thor::Actions
15
15
 
16
- JUNK_FILE_EXCLUDE_REGEX =
16
+ JUNK_FILE_EXCLUDE_REGEX = /(\.DS_Store)|(thumbs\.db)/
17
17
 
18
18
  # Most important mixin method is Thor::Actions class method `source_root()` we call externally
19
19
 
20
20
  def _directory(src, *args)
21
- # Insert exclusion of macOS and Windows preview junk files if an exclude pattern is not present
22
- # Thor's use of args is an array of call arguments, some of which can be single key/value hash options
23
- if !args.any? {|h| h.class != Hash ? false : !h[:exclude_pattern].nil?}
24
- args << {:exclude_pattern => /(\.DS_Store)|(thumbs\.db)/}
25
- end
21
+ # Build a single trailing options hash -- Thor's directory() only reads
22
+ # the last argument as options, so any caller-supplied hash (e.g.
23
+ # :force) and this default :exclude_pattern must live in the same hash.
24
+ options = args.last.is_a?(Hash) ? args.pop : {}
25
+ options[:exclude_pattern] ||= JUNK_FILE_EXCLUDE_REGEX
26
+ args << options
26
27
 
27
28
  directory( src, *args )
28
29
  end
data/docs/Changelog.md CHANGED
@@ -1,4 +1,4 @@
1
- # 🌱 Ceedling Changelog
1
+ p# 🌱 Ceedling Changelog
2
2
 
3
3
  This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
@@ -10,6 +10,34 @@ This changelog is complemented by three other documents:
10
10
 
11
11
  ---
12
12
 
13
+ # [1.1.4] — 2026-08-13
14
+
15
+ ## 💪 Fixed
16
+
17
+ - [#1198](https://github.com/ThrowTheSwitch/Ceedling/issues/1198) Fixed a crash that could go unnoticed. If a test crashed but `:use_backtrace`'s diagnostic retry ran cleanly instead of reproducing the crash, Ceedling trusted that clean retry over the real crash and reported the test as passing, with a successful exit code.
18
+ - [#1197](https://github.com/ThrowTheSwitch/Ceedling/issues/1197) Fixed edge case of includes extraction where header files in the same directory as a file being preprocessed were erroneously discovered as depth 0 `#include`s in the preprocessed file. The cause is a quirk of GCC search path defaults. The impact was greatest on certain test file organizations.
19
+
20
+ ### Partials
21
+
22
+ - [#1203](https://github.com/ThrowTheSwitch/Ceedling/issues/1203) Fixed `MOCK_PARTIAL_ALL_MODULE()` (and `MOCK_PARTIAL_PUBLIC_MODULE()`/`MOCK_PARTIAL_PRIVATE_MODULE()`) silently omitting a function from the mock interface in certain cases where no function body could be found in the module.
23
+ - [#1189](https://github.com/ThrowTheSwitch/Ceedling/issues/1189)/[#1187](https://github.com/ThrowTheSwitch/Ceedling/issues/1187) Fixed `const`/`volatile`/`restrict` qualifiers stripped from a Partial's generated `extern` declaration and definition for a promoted variable.
24
+ - Fixed C variable extraction discarding a pointer's own qualifier (e.g. the second `const` in `const uint8_t* const ptr;`) whenever the same qualifier keyword also led the declaration.
25
+ - [#1190](https://github.com/ThrowTheSwitch/Ceedling/issues/1190)/[#1187](https://github.com/ThrowTheSwitch/Ceedling/issues/1187) Fixed a module's typedefs and aggregate (struct/enum/union) definitions being generated into both its Test Partial and Mock Partial headers, causing a redefinition error when a test file uses both for the same module. Such content is now generated once into a shared header with unique include guard that both Partial headers, in turn, include.
26
+ - [#1188](https://github.com/ThrowTheSwitch/Ceedling/issues/1188)/[#1187](https://github.com/ThrowTheSwitch/Ceedling/issues/1187) Fixed a long C declaration silently vanishing from a Partial (and everything textually after it in the same file) once it exceeded an internal, fixed sized buffer length. Refactored to rely on a different dynamically resized buffer with a configurable size ceiling (new `:partials` ↳ `:max_extraction_length`). C feature extraction now raises a clear error if the limit is exceeded.
27
+ - [#1194](https://github.com/ThrowTheSwitch/Ceedling/issues/1194) Fixed generated Partials stripping directory components from system include directives (e.g. `<sys/stat.h>` becoming `<stat.h>`).
28
+
29
+ ---
30
+
31
+ # [1.1.3] — 2026-08-06
32
+
33
+ ## 💪 Fixed
34
+ - [#1185](https://github.com/ThrowTheSwitch/Ceedling/issues/1185) Fixed / improved crash handling for parameterized Unity test cases.
35
+ - [#1186](https://github.com/ThrowTheSwitch/Ceedling/issues/1186) Fixed `gcc` version lookup for the Gcov plugin running on Windows.
36
+ - Ensure compilation symbols needed for Partials are injected when `:preprocess` defines are configured.
37
+ - Fixed use of Thor’s Actions#directory to ensure a single options hash.
38
+
39
+ ---
40
+
13
41
  # [1.1.2] — 2026-07-27
14
42
 
15
43
  ## 💪 Fixed
@@ -26,6 +26,13 @@ All top-level keys of the Ceedling project configuration file, each on its own p
26
26
 
27
27
  Assembly file support for test suite builds.
28
28
 
29
+ - :material-book-open-variant: **[`:partials` — Partials Settings][ref-partials]**
30
+
31
+ ---
32
+
33
+ Bound how large a single C construct may grow during extraction before
34
+ Partial generation fails outright rather than searching indefinitely.
35
+
29
36
  - :material-book-open-variant: **[`:release_build` — Release Build Settings][ref-release-build]**
30
37
 
31
38
  ---
@@ -150,6 +157,7 @@ All top-level keys of the Ceedling project configuration file, each on its own p
150
157
  [ref-project]: project.md
151
158
  [ref-mixins]: mixins.md
152
159
  [ref-test-build]: test-build.md
160
+ [ref-partials]: partials.md
153
161
  [ref-release-build]: release-build.md
154
162
  [ref-paths]: paths.md
155
163
  [ref-files]: files.md
@@ -0,0 +1,38 @@
1
+ # `:partials`
2
+
3
+ **Configuring C feature extraction for Partials**
4
+
5
+ ## Example `:partials` YAML
6
+
7
+ ```yaml
8
+ :partials:
9
+ # Ceiling of 1000 character blocks for buffer growth
10
+ # 8000 = a max buffer growth to 8,000,000 characters
11
+ :max_extraction_length: 8000
12
+ ```
13
+
14
+ ## `:max_extraction_length`
15
+
16
+ Notes:
17
+ - The default should be sufficient for nearly all test builds. Modification should only be necessary on error.
18
+ - This configuration option is only available in Ceedling 1.1.4+.
19
+
20
+ Building a Partial requires Ceedling to extract each C construct — a
21
+ variable declaration, a function, a macro, and so on — from your source
22
+ files one at a time. Extraction reads a construct into a growing buffer
23
+ until it finds that construct's natural end (a terminating `;`, a closing
24
+ `}`, etc.). This setting bounds how large that buffer may grow before
25
+ extraction fails outright, rather than continuing to search indefinitely
26
+ into whatever else follows in the file.
27
+
28
+ The value is a multiplier of 1000 characters, not a raw character count —
29
+ `8000` means 8,000,000 characters. It must be a whole number no smaller
30
+ than `10` (10,000 characters).
31
+
32
+ Raise this value if Ceedling reports an extraction failure for a
33
+ legitimately large single construct in your codebase — a sizable generated
34
+ lookup table, for instance. There's ordinarily no reason to lower it.
35
+
36
+ **Default**: 5000 (5,000,000 characters)
37
+
38
+ <br/><br/>
@@ -9,8 +9,9 @@
9
9
  #include "LightSensor.h"
10
10
  #include "SensorHal.h"
11
11
 
12
- static uint32 s_lux_value;
13
- static uint32 s_nighttime_threshold_lux;
12
+ static uint32 s_lux_value;
13
+ static uint32 s_nighttime_threshold_lux;
14
+ static LightLevel_t s_light_level;
14
15
 
15
16
  /* Full-scale 4095 counts = 100 000 lux. */
16
17
  PRIVATE uint32 LightSensor__ConvertRawToLux(uint16 raw_counts)
@@ -23,10 +24,20 @@ PRIVATE_INLINE bool LightSensor__IsNighttime(uint32 lux)
23
24
  return lux < s_nighttime_threshold_lux;
24
25
  }
25
26
 
27
+ /* Three-way classification of a lux reading, coarser than the raw value itself
28
+ * and handy for display or logging without exposing the underlying threshold math. */
29
+ PRIVATE LightLevel_t LightSensor__ClassifyLux(uint32 lux)
30
+ {
31
+ if (lux < 50u) { return LIGHT_LEVEL_DARK; }
32
+ if (lux < 5000u) { return LIGHT_LEVEL_DIM; }
33
+ return LIGHT_LEVEL_BRIGHT;
34
+ }
35
+
26
36
  void LightSensor_Init(uint32 nighttime_threshold_lux)
27
37
  {
28
38
  s_lux_value = 0u;
29
39
  s_nighttime_threshold_lux = nighttime_threshold_lux;
40
+ s_light_level = LIGHT_LEVEL_DARK;
30
41
  SensorHal_StartConversion(SENSOR_CHANNEL_LIGHT);
31
42
  }
32
43
 
@@ -34,8 +45,9 @@ bool LightSensor_Sample(void)
34
45
  {
35
46
  if (!SensorHal_IsChannelReady(SENSOR_CHANNEL_LIGHT)) { return false; }
36
47
 
37
- uint16 raw = SensorHal_ReadChannel(SENSOR_CHANNEL_LIGHT);
38
- s_lux_value = LightSensor__ConvertRawToLux(raw);
48
+ uint16 raw = SensorHal_ReadChannel(SENSOR_CHANNEL_LIGHT);
49
+ s_lux_value = LightSensor__ConvertRawToLux(raw);
50
+ s_light_level = LightSensor__ClassifyLux(s_lux_value);
39
51
  SensorHal_StartConversion(SENSOR_CHANNEL_LIGHT);
40
52
  return true;
41
53
  }
@@ -49,3 +61,8 @@ bool LightSensor_IsNighttime(void)
49
61
  {
50
62
  return LightSensor__IsNighttime(s_lux_value);
51
63
  }
64
+
65
+ LightLevel_t LightSensor_GetLightLevel(void)
66
+ {
67
+ return s_light_level;
68
+ }
@@ -10,9 +10,17 @@
10
10
 
11
11
  #include "Types.h"
12
12
 
13
- void LightSensor_Init(uint32 nighttime_threshold_lux);
14
- bool LightSensor_Sample(void);
15
- uint32 LightSensor_GetLux(void);
16
- bool LightSensor_IsNighttime(void);
13
+ typedef enum
14
+ {
15
+ LIGHT_LEVEL_DARK = 0,
16
+ LIGHT_LEVEL_DIM = 1,
17
+ LIGHT_LEVEL_BRIGHT = 2
18
+ } LightLevel_t;
19
+
20
+ void LightSensor_Init(uint32 nighttime_threshold_lux);
21
+ bool LightSensor_Sample(void);
22
+ uint32 LightSensor_GetLux(void);
23
+ bool LightSensor_IsNighttime(void);
24
+ LightLevel_t LightSensor_GetLightLevel(void);
17
25
 
18
26
  #endif /* LIGHT_SENSOR_H */
@@ -6,10 +6,13 @@
6
6
  ========================================================================= */
7
7
 
8
8
  /* Partials pattern: TEST_PARTIAL_PUBLIC_MODULE + MOCK_PARTIAL_PRIVATE_MODULE
9
- * Tests the public interface (LightSensor_Sample, GetLux, IsNighttime)
10
- * while mocking the private helpers LightSensor__ConvertRawToLux() and
11
- * LightSensor__IsNighttime(). SensorHal is mocked traditionally.
12
- * This demonstrates testing public behavior while isolating private logic. */
9
+ * Tests the public interface (LightSensor_Sample, GetLux, IsNighttime,
10
+ * GetLightLevel) while mocking the private helpers LightSensor__ConvertRawToLux(),
11
+ * LightSensor__IsNighttime(), and LightSensor__ClassifyLux(). SensorHal is mocked
12
+ * traditionally. This demonstrates testing public behavior while isolating private
13
+ * logic. LightSensor.h's LightLevel_t enum is needed by both a tested public
14
+ * function's return type and a mocked private function's return type, so this
15
+ * module also exercises a type shared between the generated test and mock headers. */
13
16
 
14
17
  #include "unity.h"
15
18
  #include "ceedling.h"
@@ -48,6 +51,7 @@ void test_Sample_CallsConvertHelperAndStoresResult(void)
48
51
  SensorHal_IsChannelReady_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, true);
49
52
  SensorHal_ReadChannel_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, 2000u);
50
53
  LightSensor__ConvertRawToLux_ExpectAndReturn(2000u, 48840u);
54
+ LightSensor__ClassifyLux_ExpectAndReturn(48840u, LIGHT_LEVEL_BRIGHT);
51
55
  SensorHal_StartConversion_Expect(SENSOR_CHANNEL_LIGHT);
52
56
 
53
57
  TEST_ASSERT_TRUE(LightSensor_Sample());
@@ -59,6 +63,7 @@ void test_IsNighttime_ReturnsTrueWhenPrivateHelperReturnsTrue(void)
59
63
  SensorHal_IsChannelReady_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, true);
60
64
  SensorHal_ReadChannel_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, 10u);
61
65
  LightSensor__ConvertRawToLux_ExpectAndReturn(10u, 244u);
66
+ LightSensor__ClassifyLux_ExpectAndReturn(244u, LIGHT_LEVEL_DIM);
62
67
  SensorHal_StartConversion_Expect(SENSOR_CHANNEL_LIGHT);
63
68
  LightSensor_Sample();
64
69
 
@@ -71,9 +76,34 @@ void test_IsNighttime_ReturnsFalseWhenPrivateHelperReturnsFalse(void)
71
76
  SensorHal_IsChannelReady_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, true);
72
77
  SensorHal_ReadChannel_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, 3000u);
73
78
  LightSensor__ConvertRawToLux_ExpectAndReturn(3000u, 73260u);
79
+ LightSensor__ClassifyLux_ExpectAndReturn(73260u, LIGHT_LEVEL_BRIGHT);
74
80
  SensorHal_StartConversion_Expect(SENSOR_CHANNEL_LIGHT);
75
81
  LightSensor_Sample();
76
82
 
77
83
  LightSensor__IsNighttime_ExpectAndReturn(73260u, false);
78
84
  TEST_ASSERT_FALSE(LightSensor_IsNighttime());
79
85
  }
86
+
87
+ void test_Sample_ClassifiesLuxAsDark(void)
88
+ {
89
+ SensorHal_IsChannelReady_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, true);
90
+ SensorHal_ReadChannel_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, 1u);
91
+ LightSensor__ConvertRawToLux_ExpectAndReturn(1u, 20u);
92
+ LightSensor__ClassifyLux_ExpectAndReturn(20u, LIGHT_LEVEL_DARK);
93
+ SensorHal_StartConversion_Expect(SENSOR_CHANNEL_LIGHT);
94
+
95
+ TEST_ASSERT_TRUE(LightSensor_Sample());
96
+ TEST_ASSERT_EQUAL(LIGHT_LEVEL_DARK, LightSensor_GetLightLevel());
97
+ }
98
+
99
+ void test_Sample_ClassifiesLuxAsBright(void)
100
+ {
101
+ SensorHal_IsChannelReady_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, true);
102
+ SensorHal_ReadChannel_ExpectAndReturn(SENSOR_CHANNEL_LIGHT, 4000u);
103
+ LightSensor__ConvertRawToLux_ExpectAndReturn(4000u, 97680u);
104
+ LightSensor__ClassifyLux_ExpectAndReturn(97680u, LIGHT_LEVEL_BRIGHT);
105
+ SensorHal_StartConversion_Expect(SENSOR_CHANNEL_LIGHT);
106
+
107
+ TEST_ASSERT_TRUE(LightSensor_Sample());
108
+ TEST_ASSERT_EQUAL(LIGHT_LEVEL_BRIGHT, LightSensor_GetLightLevel());
109
+ }
@@ -18,7 +18,7 @@ class CExtractor
18
18
  include CExtractorConstants
19
19
  include CExtractorTypes
20
20
 
21
- constructor :c_extractor_code_text, :c_extractor_functions, :c_extractor_declarations, :c_extractor_preprocessing, :c_extractor_definitions
21
+ constructor :c_extractor_code_text, :c_extractor_functions, :c_extractor_declarations, :c_extractor_preprocessing, :c_extractor_definitions, :configurator, :loginator
22
22
 
23
23
  attr_writer :chunk_size, :max_buffer_length
24
24
 
@@ -31,7 +31,7 @@ class CExtractor
31
31
  @definitions = @c_extractor_definitions
32
32
 
33
33
  @chunk_size = DEFAULT_CHUNK_SIZE
34
- @max_buffer_length = DEFAULT_MAX_FUNCTION_LENGTH
34
+ @max_buffer_length = default_max_buffer_length
35
35
  end
36
36
 
37
37
  # Extract C module contents from a source file on disk.
@@ -58,26 +58,36 @@ class CExtractor
58
58
  # Parameters:
59
59
  # content: String containing C source code to extract from
60
60
  # chunk_size: (Optional) Size of chunks to read at a time (default: 16 KB)
61
- # max_buffer_length: (Optional) Maximum allowed function size (default: 5 MB)
62
- # max_line_length: (Optional) Maximum allowed line length (default: 1000 chars)
61
+ # max_buffer_length: (Optional) Maximum allowed feature size in characters. Defaults to
62
+ # whatever setup() already established (project configuration if
63
+ # available, otherwise the built-in default) rather than a literal
64
+ # value here, so an explicit-override-free call doesn't clobber that.
63
65
  #
64
66
  # Returns: CModule struct containing all features extracted.
65
67
  def from_string(
66
68
  content:,
67
69
  chunk_size: DEFAULT_CHUNK_SIZE,
68
- max_buffer_length: DEFAULT_MAX_FUNCTION_LENGTH,
69
- max_line_length: DEFAULT_MAX_LINE_LENGTH
70
+ max_buffer_length: nil
70
71
  )
71
72
  @chunk_size = chunk_size
72
- @max_buffer_length = max_buffer_length
73
- @functions.max_line_length = max_line_length
74
- @declarations.max_line_length = max_line_length
73
+ @max_buffer_length = max_buffer_length unless max_buffer_length.nil?
75
74
 
76
75
  return extract_contents( StringIO.new( content ), nil )
77
76
  end
78
77
 
79
78
  private
80
79
 
80
+ # `:configurator` is absent for direct/test construction of this class (only Ceedling's
81
+ # DI container supplies it in production), so this falls back to the built-in default in
82
+ # that case rather than requiring every caller to know about project configuration.
83
+ # The configured value is a small integer multiplier of 1000 characters (project-file
84
+ # ergonomics -- `5000` reads more clearly than `5000000`), so it's scaled up here to the
85
+ # actual character count this class works in internally.
86
+ def default_max_buffer_length()
87
+ return DEFAULT_MAX_FUNCTION_LENGTH unless @configurator.respond_to?(:partials_max_extraction_length)
88
+ return @configurator.partials_max_extraction_length * 1000
89
+ end
90
+
81
91
  # Extracts all C code features from the given IO source.
82
92
  #
83
93
  # Parameters:
@@ -276,9 +286,25 @@ class CExtractor
276
286
  # Expand the buffer with the new chunk
277
287
  buffer << chunk
278
288
 
279
- # Safety check -- don't let buffer grow indefinitely
289
+ # Safety check -- don't let buffer grow indefinitely. This is the single ceiling for every
290
+ # feature type (directives, typedefs, functions, variable declarations, etc.) -- individual
291
+ # extractors don't enforce their own separate, smaller limits, since any of them scanning
292
+ # to the end of an ever-growing buffer without finding a terminator is exactly this same
293
+ # condition and belongs to this one check.
294
+ #
295
+ # Which of the several extractors tried at this file position is active when this fires
296
+ # isn't reported: extract_contents tries each one in a fixed order at every position, and
297
+ # an extractor that rejects content outright (e.g. text not starting with '#' for a
298
+ # directive) rejects it the same way regardless of how much more the buffer grows, so the
299
+ # first extractor in that fixed order is always the one still running when the buffer
300
+ # finally crosses this ceiling -- naming it here would misattribute the failure to it
301
+ # rather than to whatever construct actually caused the overrun.
280
302
  if buffer.length > max_length
281
- raise CeedlingException.new("Feature extraction exceeded maximum length of #{max_length} characters")
303
+ @loginator.log(
304
+ "Extraction starting at file position #{chunk_start_pos} exceeded maximum length of #{max_length} characters",
305
+ Verbosity::DEBUG
306
+ ) if @loginator
307
+ raise CeedlingException.new("Extraction exceeded maximum length of #{max_length} characters, starting at file position #{chunk_start_pos}")
282
308
  end
283
309
 
284
310
  # Create a new scanner for the current buffer
@@ -6,9 +6,6 @@
6
6
  # =========================================================================
7
7
 
8
8
  module CExtractorConstants
9
- # 1000 character safety limit
10
- DEFAULT_MAX_LINE_LENGTH = 1000
11
-
12
9
  # 16 KB -- enough for most functions
13
10
  DEFAULT_CHUNK_SIZE = (16 * 1024)
14
11