ceedling 1.1.3 → 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.
- checksums.yaml +4 -4
- data/GIT_COMMIT_SHA +1 -1
- data/README.md +1 -1
- data/assets/fake_crash_test_fixture.rb +14 -0
- data/assets/partial_all_module.h +11 -0
- data/assets/run_with_ubsan.rb +15 -0
- data/assets/same_dir_pairing_module.c +4 -0
- data/assets/same_dir_pairing_module.h +8 -0
- data/assets/same_dir_pairing_module_func.h +6 -0
- data/assets/same_dir_pairing_other.c +4 -0
- data/assets/same_dir_pairing_other.h +8 -0
- data/assets/test_example_file_ub_shift_overflow.c +22 -0
- data/assets/test_partial_all_module.c +16 -0
- data/assets/test_same_dir_pairing.c +23 -0
- data/docs/Changelog.md +21 -1
- data/docs/mkdocs/configuration/reference/index.md +8 -0
- data/docs/mkdocs/configuration/reference/partials.md +38 -0
- data/examples/wondrous_forest/src/LightSensor.c +21 -4
- data/examples/wondrous_forest/src/LightSensor.h +12 -4
- data/examples/wondrous_forest/test/TestLightSensor.c +34 -4
- data/lib/ceedling/c_extractor/c_extractor.rb +37 -11
- data/lib/ceedling/c_extractor/c_extractor_constants.rb +0 -3
- data/lib/ceedling/c_extractor/c_extractor_declarations.rb +26 -25
- data/lib/ceedling/c_extractor/c_extractor_functions.rb +5 -12
- data/lib/ceedling/config/configurator.rb +1 -0
- data/lib/ceedling/config/configurator_setup.rb +26 -0
- data/lib/ceedling/defaults.rb +8 -0
- data/lib/ceedling/file_path_utils.rb +7 -0
- data/lib/ceedling/file_wrapper.rb +8 -0
- data/lib/ceedling/generators/generator.rb +15 -0
- data/lib/ceedling/generators/generator_helper.rb +25 -6
- data/lib/ceedling/generators/generator_partials.rb +84 -3
- data/lib/ceedling/generators/generator_test_results_backtrace.rb +183 -83
- data/lib/ceedling/includes/includes.rb +66 -11
- data/lib/ceedling/objects.yml +5 -0
- data/lib/ceedling/partials/partializer.rb +18 -3
- data/lib/ceedling/partials/partializer_utils.rb +6 -1
- data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +43 -16
- data/lib/ceedling/test_invoker/test_build_executor.rb +19 -8
- data/lib/version.rb +1 -1
- data/mkdocs.yml +1 -0
- data/site-local/404.html +30 -0
- data/site-local/configuration/environment-vars.html +30 -0
- data/site-local/configuration/global-collections.html +30 -0
- data/site-local/configuration/index.html +30 -0
- data/site-local/configuration/loading.html +30 -0
- data/site-local/configuration/mixins.html +30 -0
- data/site-local/configuration/parallel-builds.html +30 -0
- data/site-local/configuration/project-file.html +30 -0
- data/site-local/configuration/reference/cexception.html +30 -0
- data/site-local/configuration/reference/cmock.html +30 -0
- data/site-local/configuration/reference/defines.html +30 -0
- data/site-local/configuration/reference/environment.html +30 -0
- data/site-local/configuration/reference/extension.html +30 -0
- data/site-local/configuration/reference/files.html +30 -0
- data/site-local/configuration/reference/flags.html +30 -0
- data/site-local/configuration/reference/index.html +36 -0
- data/site-local/configuration/reference/libraries.html +30 -0
- data/site-local/configuration/reference/mixins.html +30 -0
- data/site-local/configuration/reference/partials.html +4257 -0
- data/site-local/configuration/reference/paths.html +30 -0
- data/site-local/configuration/reference/plugins.html +30 -0
- data/site-local/configuration/reference/project.html +30 -0
- data/site-local/configuration/reference/release-build.html +31 -1
- data/site-local/configuration/reference/test-build.html +31 -1
- data/site-local/configuration/reference/test-runner.html +30 -0
- data/site-local/configuration/reference/tools.html +30 -0
- data/site-local/configuration/reference/unity.html +30 -0
- data/site-local/configuration/which-ceedling.html +30 -0
- data/site-local/development/index.html +30 -0
- data/site-local/development/plugins/configuration.html +30 -0
- data/site-local/development/plugins/index.html +30 -0
- data/site-local/development/plugins/plugin-subclass.html +30 -0
- data/site-local/development/plugins/rake-tasks.html +30 -0
- data/site-local/development/workflow.html +30 -0
- data/site-local/getting-started/command-line.html +30 -0
- data/site-local/getting-started/example-projects/cipher-quest.html +30 -0
- data/site-local/getting-started/example-projects/index.html +30 -0
- data/site-local/getting-started/example-projects/temp-sensor.html +30 -0
- data/site-local/getting-started/example-projects/wondrous-forest.html +30 -0
- data/site-local/getting-started/index.html +30 -0
- data/site-local/getting-started/installation.html +30 -0
- data/site-local/getting-started/quick-start.html +30 -0
- data/site-local/help.html +30 -0
- data/site-local/index.html +30 -0
- data/site-local/overview/build-system.html +30 -0
- data/site-local/overview/index.html +30 -0
- data/site-local/overview/test-environments.html +30 -0
- data/site-local/overview/tools-and-frameworks.html +30 -0
- data/site-local/plugins/beep.html +30 -0
- data/site-local/plugins/bullseye.html +30 -0
- data/site-local/plugins/command-hooks.html +30 -0
- data/site-local/plugins/compile-commands-json-db.html +30 -0
- data/site-local/plugins/cppcheck.html +30 -0
- data/site-local/plugins/dependencies.html +30 -0
- data/site-local/plugins/fff.html +30 -0
- data/site-local/plugins/gcov/examples.html +30 -0
- data/site-local/plugins/gcov/gcovr.html +30 -0
- data/site-local/plugins/gcov/index.html +30 -0
- data/site-local/plugins/gcov/overview.html +30 -0
- data/site-local/plugins/gcov/reportgenerator.html +30 -0
- data/site-local/plugins/gcov/reporting.html +30 -0
- data/site-local/plugins/gcov/setup.html +30 -0
- data/site-local/plugins/gcov/tool-versions.html +30 -0
- data/site-local/plugins/gcov/troubleshooting.html +30 -0
- data/site-local/plugins/index.html +30 -0
- data/site-local/plugins/module-generator.html +30 -0
- data/site-local/plugins/report-build-warnings-log.html +30 -0
- data/site-local/plugins/report-tests-gtestlike-stdout.html +30 -0
- data/site-local/plugins/report-tests-ide-stdout.html +30 -0
- data/site-local/plugins/report-tests-log-factory.html +30 -0
- data/site-local/plugins/report-tests-pretty-stdout.html +30 -0
- data/site-local/plugins/report-tests-raw-output-log.html +30 -0
- data/site-local/plugins/report-tests-teamcity-stdout.html +30 -0
- data/site-local/plugins/valgrind.html +30 -0
- data/site-local/project/release-history.html +30 -0
- data/site-local/project/upgrade.html +30 -0
- data/site-local/reference/build-directives.html +30 -0
- data/site-local/reference/command-line.html +30 -0
- data/site-local/reference/environment-vars.html +30 -0
- data/site-local/reference/gcov-plugin.html +30 -0
- data/site-local/reference/global-collections.html +30 -0
- data/site-local/reference/index.html +30 -0
- data/site-local/reference/partials-macros.html +30 -0
- data/site-local/reference/project-configuration.html +30 -0
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/examples/cipher_quest/index.html +30 -0
- data/site-local/snapshot/examples/temp_sensor/index.html +30 -0
- data/site-local/snapshot/examples/wondrous_forest/index.html +30 -0
- data/site-local/testing-guide/build-directives.html +30 -0
- data/site-local/testing-guide/conventions.html +30 -0
- data/site-local/testing-guide/frameworks.html +30 -0
- data/site-local/testing-guide/index.html +30 -0
- data/site-local/testing-guide/partials/configuration.html +30 -0
- data/site-local/testing-guide/partials/conventions.html +30 -0
- data/site-local/testing-guide/partials/directives.html +30 -0
- data/site-local/testing-guide/partials/example.html +30 -0
- data/site-local/testing-guide/partials/index.html +30 -0
- data/site-local/testing-guide/partials/overview.html +30 -0
- data/site-local/testing-guide/partials/variables.html +30 -0
- data/site-local/testing-guide/test-cases.html +30 -0
- data/site-local/testing-guide/test-sample.html +30 -0
- data/site-local/testing-guide/test-suite-anatomy.html +30 -0
- data/spec/support/system/spec_system_helper.rb +25 -0
- data/spec/system/deployment_as_gem_spec.rb +12 -0
- data/spec/system/deployment_as_vendor_spec.rb +17 -0
- data/spec/system/encoding_stress_spec.rb +4 -4
- data/spec/system/example_wondrous_forest_spec.rb +2 -2
- data/spec/system/support/common_test_cases.rb +137 -0
- data/spec/units/c_extractor/c_extractor_declarations_spec.rb +27 -4
- data/spec/units/c_extractor/c_extractor_functions_spec.rb +1 -11
- data/spec/units/c_extractor/c_extractor_integration_spec.rb +18 -11
- data/spec/units/c_extractor/c_extractor_spec.rb +57 -1
- data/spec/units/config/configurator_setup_spec.rb +61 -0
- data/spec/units/file_path_utils_spec.rb +17 -0
- data/spec/units/generators/generator_helper_spec.rb +34 -7
- data/spec/units/generators/generator_partials_spec.rb +120 -12
- data/spec/units/generators/generator_test_results_backtrace_spec.rb +200 -37
- data/spec/units/includes/include_spec.rb +30 -18
- data/spec/units/includes/includes_spec.rb +100 -10
- data/spec/units/partials/partializer_spec.rb +113 -1
- data/spec/units/partials/partializer_utils_spec.rb +11 -0
- data/spec/units/preprocess/preprocessinator_includes_handler_spec.rb +96 -7
- data/spec/units/system_wrapper_spec.rb +72 -0
- metadata +19 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d8c20196572fb2d9730237fb04f7ab5d18869180b185e14649d1212669b1fd3f
|
|
4
|
+
data.tar.gz: b363d61a395c3a788fbe4566196d2ce6f6c49e5a8b00423f49c4df3fc2e3f2e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c30b50264e5a459a19c0fca20b57fdc1e2e3cc6282b504f5789c2cec47fd9dc11d49cd05c5ecb8e09c47c6e1bb9b7029d74ce7714249abc9e00456ead5d1002
|
|
7
|
+
data.tar.gz: a83eddeb44b9049e361f94ef0280809f157f304c96631ef75ee7341302a34faed50ed4e616d1744e220dccad496872e0c2282b8f7d5e6c4c1e58c5be28fddf32
|
data/GIT_COMMIT_SHA
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
e44173e
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Ceedling 
|
|
2
2
|
========
|
|
3
3
|
|
|
4
|
-
**Ceedling 1.1.
|
|
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,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,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
|
+
}
|
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,24 @@ 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
|
+
|
|
13
31
|
# [1.1.3] — 2026-08-06
|
|
14
32
|
|
|
15
33
|
## 💪 Fixed
|
|
@@ -18,6 +36,8 @@ This changelog is complemented by three other documents:
|
|
|
18
36
|
- Ensure compilation symbols needed for Partials are injected when `:preprocess` defines are configured.
|
|
19
37
|
- Fixed use of Thor’s Actions#directory to ensure a single options hash.
|
|
20
38
|
|
|
39
|
+
---
|
|
40
|
+
|
|
21
41
|
# [1.1.2] — 2026-07-27
|
|
22
42
|
|
|
23
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
|
|
13
|
-
static uint32
|
|
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
|
|
38
|
-
s_lux_value
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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()
|
|
11
|
-
* LightSensor__IsNighttime(). SensorHal is mocked
|
|
12
|
-
* This demonstrates testing public behavior while isolating private
|
|
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 =
|
|
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
|
|
62
|
-
#
|
|
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:
|
|
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
|
-
|
|
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
|
|
@@ -16,12 +16,9 @@ class CExtractorDeclarations
|
|
|
16
16
|
|
|
17
17
|
constructor :c_extractor_code_text
|
|
18
18
|
|
|
19
|
-
attr_writer :max_line_length
|
|
20
|
-
|
|
21
19
|
def setup()
|
|
22
20
|
# Aliases
|
|
23
|
-
@code_text
|
|
24
|
-
@max_line_length = DEFAULT_MAX_LINE_LENGTH
|
|
21
|
+
@code_text = @c_extractor_code_text
|
|
25
22
|
end
|
|
26
23
|
|
|
27
24
|
# Attempts to extract a complete variable declaration from the scanner
|
|
@@ -58,11 +55,14 @@ class CExtractorDeclarations
|
|
|
58
55
|
# On failure: Resets scanner position to starting position
|
|
59
56
|
#
|
|
60
57
|
# Safety:
|
|
61
|
-
#
|
|
58
|
+
# A declaration with no terminating semicolon runs the scan to the end of
|
|
59
|
+
# whatever buffer the caller (CExtractor#extract_next_feature) has grown so
|
|
60
|
+
# far; that caller is the one place enforcing an overall length ceiling,
|
|
61
|
+
# since only it knows how much more of the file remains to try growing into.
|
|
62
62
|
def try_extract_variable(scanner)
|
|
63
63
|
start_pos = scanner.pos
|
|
64
64
|
|
|
65
|
-
# Tracks paren, bracket, and brace depth simultaneously with inline string state machine
|
|
65
|
+
# Tracks paren, bracket, and brace depth simultaneously with an inline string state machine — not suitable for collect_balanced()
|
|
66
66
|
paren_depth = 0
|
|
67
67
|
bracket_depth = 0
|
|
68
68
|
brace_depth = 0
|
|
@@ -74,12 +74,6 @@ class CExtractorDeclarations
|
|
|
74
74
|
until scanner.eos?
|
|
75
75
|
char = scanner.peek(1)
|
|
76
76
|
|
|
77
|
-
# Safety check -- prevent infinite loops on malformed input
|
|
78
|
-
if (scanner.pos - start_pos) > @max_line_length
|
|
79
|
-
scanner.pos = start_pos
|
|
80
|
-
return [false, nil]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
77
|
# Handle string literals
|
|
84
78
|
if in_string
|
|
85
79
|
if char == '\\'
|
|
@@ -302,8 +296,8 @@ class CExtractorDeclarations
|
|
|
302
296
|
#
|
|
303
297
|
# Returns: CVariableDeclaration
|
|
304
298
|
def parse_declaration(individual_text, original_text)
|
|
305
|
-
decorators
|
|
306
|
-
clean_text =
|
|
299
|
+
decorators, remaining = extract_decorators(individual_text)
|
|
300
|
+
clean_text = normalize_declaration_whitespace(remaining)
|
|
307
301
|
# Strip compiler extensions for name/type/array_suffix extraction only;
|
|
308
302
|
# clean_text (stored as .text) retains attributes for correct compilation.
|
|
309
303
|
extraction_text = @code_text.strip_compiler_extensions(clean_text)
|
|
@@ -321,9 +315,17 @@ class CExtractorDeclarations
|
|
|
321
315
|
)
|
|
322
316
|
end
|
|
323
317
|
|
|
324
|
-
#
|
|
318
|
+
# Storage-class specifiers and base-type qualifiers precede a C declaration's type as a
|
|
319
|
+
# contiguous run of keywords -- `static`, `extern`, and a `const`/`volatile` that qualifies
|
|
320
|
+
# the type itself all appear here (e.g. `static const int MAX;`). A qualifier bound to a
|
|
321
|
+
# pointer level instead, such as the second `const` in `char * const p;`, sits after the
|
|
322
|
+
# type and its `*` tokens rather than in this leading run, so it is grammatically part of
|
|
323
|
+
# the declarator, not a decorator. Peeling keywords off one at a time from the front, and
|
|
324
|
+
# stopping at the first non-keyword token, naturally separates the two: the same keyword
|
|
325
|
+
# (e.g. `const`) can appear once here and again later in the declarator without the two
|
|
326
|
+
# occurrences being confused with each other, since only the leading run is ever consumed.
|
|
325
327
|
#
|
|
326
|
-
# Returns: Array<String> ordered decorator keywords found at start of text
|
|
328
|
+
# Returns: [Array<String> ordered decorator keywords found at start of text, String remaining text after that run]
|
|
327
329
|
def extract_decorators(text)
|
|
328
330
|
decorators = []
|
|
329
331
|
remaining = text.strip
|
|
@@ -339,18 +341,17 @@ class CExtractorDeclarations
|
|
|
339
341
|
end
|
|
340
342
|
break unless matched
|
|
341
343
|
end
|
|
342
|
-
decorators
|
|
344
|
+
[decorators, remaining]
|
|
343
345
|
end
|
|
344
346
|
|
|
345
|
-
#
|
|
347
|
+
# A declaration with its leading decorator run already removed (see extract_decorators)
|
|
348
|
+
# still carries whatever whitespace and line breaks appeared in the source between its
|
|
349
|
+
# remaining tokens. This collapses that whitespace to single spaces and guarantees a
|
|
350
|
+
# trailing semicolon, so `.text` is stable, single-line C ready to compile.
|
|
346
351
|
#
|
|
347
|
-
# Returns: String with
|
|
348
|
-
def
|
|
349
|
-
result =
|
|
350
|
-
decorators.each do |kw|
|
|
351
|
-
result.gsub!(/\b#{Regexp.escape(kw)}\b\s*/, '')
|
|
352
|
-
end
|
|
353
|
-
# Normalize whitespace but preserve semicolon
|
|
352
|
+
# Returns: String with whitespace normalized, semicolon retained
|
|
353
|
+
def normalize_declaration_whitespace(remaining)
|
|
354
|
+
result = remaining.dup
|
|
354
355
|
result.gsub!(/\r\n|\r|\n|\t/, ' ')
|
|
355
356
|
result.gsub!(/\s+/, ' ')
|
|
356
357
|
result.strip!
|