ceedling 1.1.4 β†’ 1.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8c20196572fb2d9730237fb04f7ab5d18869180b185e14649d1212669b1fd3f
4
- data.tar.gz: b363d61a395c3a788fbe4566196d2ce6f6c49e5a8b00423f49c4df3fc2e3f2e1
3
+ metadata.gz: a54ad80f099a4117063db064305062de3ef308e0d6a34f5285ad616540c21239
4
+ data.tar.gz: aad1cd6bf73dc6710908593a9ec0c493404f13c1ecce8d7f285c2cd537b41b7f
5
5
  SHA512:
6
- metadata.gz: 1c30b50264e5a459a19c0fca20b57fdc1e2e3cc6282b504f5789c2cec47fd9dc11d49cd05c5ecb8e09c47c6e1bb9b7029d74ce7714249abc9e00456ead5d1002
7
- data.tar.gz: a83eddeb44b9049e361f94ef0280809f157f304c96631ef75ee7341302a34faed50ed4e616d1744e220dccad496872e0c2282b8f7d5e6c4c1e58c5be28fddf32
6
+ metadata.gz: 0ee2a51402a1ca62a0e42f5c9c0b7cfb47871b4723fd33096ef22d90c0dc5ae7c7eb7944833e354a745c9d1123192ed6b92fb195537a8c9d69bd9c81e0330530
7
+ data.tar.gz: 2bfd96e070e2fa703f08e85587296690a930734a5eb409c709fd5bca2cd2875aa0b9eb8cb1dca9484852ab37ffc668f9d387fce1ed0c05fc90cd69507982dbcd
data/GIT_COMMIT_SHA CHANGED
@@ -1 +1 @@
1
- e44173e
1
+ 57b6a98
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.4** is the latest and greatest.
4
+ **Ceedling 1.1.5** 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].
data/docs/Changelog.md CHANGED
@@ -10,6 +10,17 @@ This changelog is complemented by three other documents:
10
10
 
11
11
  ---
12
12
 
13
+ # [1.1.5] β€” 2026-08-19
14
+
15
+ ## πŸ’ͺ Fixed
16
+
17
+ ### Partials
18
+
19
+ - Fixed shared generated Partial types header filename being derived from the test's name rather than partialized module's own name. Two modules Partialized in the same test could silently overwrite each other's content.
20
+ - [#1210](https://github.com/ThrowTheSwitch/Ceedling/issues/1210) Fixed macros missing from shared Partial types header file emitted when two Partials both depend on the same types and related in common.
21
+
22
+ ---
23
+
13
24
  # [1.1.4] β€” 2026-08-13
14
25
 
15
26
  ## πŸ’ͺ Fixed
@@ -14,24 +14,24 @@
14
14
  ## `:max_extraction_length`
15
15
 
16
16
  Notes:
17
+
17
18
  - The default should be sufficient for nearly all test builds. Modification should only be necessary on error.
18
19
  - This configuration option is only available in Ceedling 1.1.4+.
19
20
 
20
21
  Building a Partial requires Ceedling to extract each C construct β€” a
21
22
  variable declaration, a function, a macro, and so on β€” from your source
22
23
  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
+ until it finds that construct’s natural end (a terminating `;`, a closing
24
25
  `}`, 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.
26
+ extraction fails outright.
27
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
28
+ The value is a multiplier of 1000 characters, not a raw character count. For example,
29
+ `8000` means 8,000,000 characters (approx. 7.6MB). It must be a whole number no smaller
30
30
  than `10` (10,000 characters).
31
31
 
32
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.
33
+ legitimately large single construct in your codebase (e.g. a sizable
34
+ lookup table). Ordinarily, there’s no reason to lower it.
35
35
 
36
36
  **Default**: 5000 (5,000,000 characters)
37
37
 
@@ -82,8 +82,27 @@ class GeneratorPartials
82
82
  file << "#define #{guard}\n\n"
83
83
 
84
84
  anything_emitted = false
85
+ pending_macros = []
86
+
85
87
  c_module.element_sequence.each do |item|
86
- next unless item.is_a?(CExtractorTypes::CStatement) && type_defining?(item, c_module)
88
+ next unless item.is_a?(CExtractorTypes::CStatement)
89
+
90
+ if c_module.macro_definitions.include?(item)
91
+ pending_macros << item
92
+ next
93
+ end
94
+
95
+ next unless type_defining?(item, c_module)
96
+
97
+ # A typedef/struct/enum moved here may depend on a macro (e.g. an array-size
98
+ # constant) that preceded it in the original source -- this header is #included
99
+ # before any macro generate_header later emits inline into the non-shared
100
+ # header, so that macro would otherwise be undefined here. Carrying it forward
101
+ # is safe: an identical #define may legally repeat, so generate_header's own
102
+ # unmodified inline copy causes no redefinition conflict.
103
+ pending_macros.each { |macro| file << macro.text << "\n" }
104
+ pending_macros.clear
105
+
87
106
  file << item.text << "\n"
88
107
  anything_emitted = true
89
108
  end
@@ -187,7 +187,9 @@ class TestBuildExecutor
187
187
  # their own includes lists), so a module tested and mocked in the same test file gets
188
188
  # exactly one C definition of each of its typedefs and aggregate types.
189
189
  types_header = @generator.generate_partial_types(
190
- name: name,
190
+ name: config.module, # Module name, not test name -- two modules Partialed
191
+ # in the same test file must not collide on one
192
+ # shared types header filename
191
193
  c_module: module_contents,
192
194
  output_path: testable.paths[:partials]
193
195
  )
data/lib/version.rb CHANGED
@@ -15,7 +15,7 @@
15
15
  module Ceedling
16
16
  module Version
17
17
  # Convenience constants for gem building, etc.
18
- GEM = '1.1.4'
18
+ GEM = '1.1.5'
19
19
  TAG = GEM
20
20
 
21
21
  # If run as a script print Ceedling's version to $stdout
@@ -4162,22 +4162,23 @@
4162
4162
  <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="w"> </span><span class="nt">:max_extraction_length</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">8000</span>
4163
4163
  </code></pre></div>
4164
4164
  <h2 id="max_extraction_length"><code>:max_extraction_length</code></h2>
4165
- <p>Notes:
4166
- - The default should be sufficient for nearly all test builds. Modification should only be necessary on error.
4167
- - This configuration option is only available in Ceedling 1.1.4+.</p>
4165
+ <p>Notes:</p>
4166
+ <ul>
4167
+ <li>The default should be sufficient for nearly all test builds. Modification should only be necessary on error.</li>
4168
+ <li>This configuration option is only available in Ceedling 1.1.4+.</li>
4169
+ </ul>
4168
4170
  <p>Building a Partial requires Ceedling to extract each C construct β€” a
4169
4171
  variable declaration, a function, a macro, and so on β€” from your source
4170
4172
  files one at a time. Extraction reads a construct into a growing buffer
4171
- until it finds that construct's natural end (a terminating <code>;</code>, a closing
4173
+ until it finds that construct’s natural end (a terminating <code>;</code>, a closing
4172
4174
  <code>}</code>, etc.). This setting bounds how large that buffer may grow before
4173
- extraction fails outright, rather than continuing to search indefinitely
4174
- into whatever else follows in the file.</p>
4175
- <p>The value is a multiplier of 1000 characters, not a raw character count β€”
4176
- <code>8000</code> means 8,000,000 characters. It must be a whole number no smaller
4175
+ extraction fails outright.</p>
4176
+ <p>The value is a multiplier of 1000 characters, not a raw character count. For example,
4177
+ <code>8000</code> means 8,000,000 characters (approx. 7.6MB). It must be a whole number no smaller
4177
4178
  than <code>10</code> (10,000 characters).</p>
4178
4179
  <p>Raise this value if Ceedling reports an extraction failure for a
4179
- legitimately large single construct in your codebase β€” a sizable generated
4180
- lookup table, for instance. There's ordinarily no reason to lower it.</p>
4180
+ legitimately large single construct in your codebase (e.g. a sizable
4181
+ lookup table). Ordinarily, there’s no reason to lower it.</p>
4181
4182
  <p><strong>Default</strong>: 5000 (5,000,000 characters)</p>
4182
4183
  <p><br/><br/></p>
4183
4184
 
Binary file
@@ -241,12 +241,13 @@ describe GeneratorPartials do
241
241
  expect(result).to be_nil
242
242
  end
243
243
 
244
- it "writes only the typedefs and aggregate definitions, guarded and in element_sequence order, and returns the bare filename" do
244
+ it "writes the typedefs and aggregate definitions, guarded and in element_sequence order, carrying forward a macro that precedes one of them, and returns the bare filename" do
245
245
  file_contents = <<~CONTENTS
246
246
  #ifndef __CEEDLING_GENERATED_MY_MODULE_TYPES_H__
247
247
  #define __CEEDLING_GENERATED_MY_MODULE_TYPES_H__
248
248
 
249
249
  typedef uint8_t Byte;
250
+ #define FOO 1
250
251
  struct Config { int id; };
251
252
 
252
253
  #endif // __CEEDLING_GENERATED_MY_MODULE_TYPES_H__
@@ -267,13 +268,15 @@ describe GeneratorPartials do
267
268
  .with(expected_filepath, 'wb')
268
269
  .and_yield(buf)
269
270
 
270
- # A macro and a variable sit between the two type-defining statements in
271
- # element_sequence; only the typedef and the aggregate belong in the shared
272
- # types header, in their original relative order, and neither the macro nor
273
- # the variable (which stay behind for generate_header) appear here at all.
271
+ # A variable and a macro sit between the two type-defining statements in
272
+ # element_sequence. The variable (which stays behind for generate_header) is
273
+ # entirely absent here, but the macro precedes the aggregate and is carried
274
+ # forward immediately before it -- the aggregate's definition may depend on it
275
+ # (e.g. an array-size constant), and this header is #included before
276
+ # generate_header's own later, inline copy of that same macro would exist.
274
277
  typedef_stmt = CExtractorTypes::CStatement.new(text: "typedef uint8_t Byte;", line_num: 1)
275
- macro_stmt = CExtractorTypes::CStatement.new(text: "#define FOO 1", line_num: 2)
276
- var_decl = make_var(name: 'counter', type: 'int', text: 'int counter;', line_num: 3)
278
+ var_decl = make_var(name: 'counter', type: 'int', text: 'int counter;', line_num: 2)
279
+ macro_stmt = CExtractorTypes::CStatement.new(text: "#define FOO 1", line_num: 3)
277
280
  aggregate_stmt = CExtractorTypes::CStatement.new(text: "struct Config { int id; };", line_num: 4)
278
281
 
279
282
  c_module = CExtractorTypes::CModule.new(
@@ -281,7 +284,7 @@ describe GeneratorPartials do
281
284
  macro_definitions: [macro_stmt],
282
285
  variable_declarations: [var_decl],
283
286
  aggregate_definitions: [aggregate_stmt],
284
- element_sequence: [typedef_stmt, macro_stmt, var_decl, aggregate_stmt]
287
+ element_sequence: [typedef_stmt, var_decl, macro_stmt, aggregate_stmt]
285
288
  )
286
289
 
287
290
  result = @generator.generate_types(
@@ -294,6 +297,106 @@ describe GeneratorPartials do
294
297
  expect(@file_wrapper).to have_received(:open).with(expected_filepath, 'wb')
295
298
  expect(result).to eq(header_filename)
296
299
  end
300
+
301
+ it "carries a macro forward directly before the single typedef it immediately precedes" do
302
+ output_path = '/path/to/output'
303
+ name = 'my_module'
304
+ header_filename = 'my_module_types.h'
305
+ expected_filepath = File.join(output_path, header_filename)
306
+
307
+ allow(@file_path_utils).to receive(:form_partial_types_header_filename).and_return(header_filename)
308
+
309
+ buf = StringIO.new()
310
+ allow(@file_wrapper).to receive(:open).and_yield(buf)
311
+
312
+ macro_stmt = CExtractorTypes::CStatement.new(text: "#define LOCAL_CAPACITY 4", line_num: 1)
313
+ typedef_stmt = CExtractorTypes::CStatement.new(text: "typedef struct { int values[LOCAL_CAPACITY]; } Context;", line_num: 3)
314
+
315
+ c_module = CExtractorTypes::CModule.new(
316
+ type_definitions: [typedef_stmt],
317
+ macro_definitions: [macro_stmt],
318
+ element_sequence: [macro_stmt, typedef_stmt]
319
+ )
320
+
321
+ @generator.generate_types(name: name, c_module: c_module, output_path: output_path)
322
+
323
+ expect( buf.string ).to include( "#define LOCAL_CAPACITY 4\ntypedef struct { int values[LOCAL_CAPACITY]; } Context;\n" )
324
+ end
325
+
326
+ it "carries forward multiple macros preceding one type-defining item, in their own original relative order" do
327
+ output_path = '/path/to/output'
328
+ name = 'my_module'
329
+ header_filename = 'my_module_types.h'
330
+
331
+ allow(@file_path_utils).to receive(:form_partial_types_header_filename).and_return(header_filename)
332
+
333
+ buf = StringIO.new()
334
+ allow(@file_wrapper).to receive(:open).and_yield(buf)
335
+
336
+ macro_a = CExtractorTypes::CStatement.new(text: "#define WIDTH 4", line_num: 1)
337
+ macro_b = CExtractorTypes::CStatement.new(text: "#define HEIGHT 8", line_num: 2)
338
+ typedef_stmt = CExtractorTypes::CStatement.new(text: "typedef int Grid[WIDTH][HEIGHT];", line_num: 3)
339
+
340
+ c_module = CExtractorTypes::CModule.new(
341
+ type_definitions: [typedef_stmt],
342
+ macro_definitions: [macro_a, macro_b],
343
+ element_sequence: [macro_a, macro_b, typedef_stmt]
344
+ )
345
+
346
+ @generator.generate_types(name: name, c_module: c_module, output_path: output_path)
347
+
348
+ expect( buf.string ).to include( "#define WIDTH 4\n#define HEIGHT 8\ntypedef int Grid[WIDTH][HEIGHT];\n" )
349
+ end
350
+
351
+ it "carries a macro forward only once, before the first type-defining item it precedes, not before a later one too" do
352
+ output_path = '/path/to/output'
353
+ name = 'my_module'
354
+ header_filename = 'my_module_types.h'
355
+
356
+ allow(@file_path_utils).to receive(:form_partial_types_header_filename).and_return(header_filename)
357
+
358
+ buf = StringIO.new()
359
+ allow(@file_wrapper).to receive(:open).and_yield(buf)
360
+
361
+ macro_stmt = CExtractorTypes::CStatement.new(text: "#define FOO 1", line_num: 1)
362
+ typedef_stmt = CExtractorTypes::CStatement.new(text: "typedef int Foo;", line_num: 2)
363
+ aggregate_stmt = CExtractorTypes::CStatement.new(text: "struct Bar { int x; };", line_num: 3)
364
+
365
+ c_module = CExtractorTypes::CModule.new(
366
+ type_definitions: [typedef_stmt],
367
+ macro_definitions: [macro_stmt],
368
+ aggregate_definitions: [aggregate_stmt],
369
+ element_sequence: [macro_stmt, typedef_stmt, aggregate_stmt]
370
+ )
371
+
372
+ @generator.generate_types(name: name, c_module: c_module, output_path: output_path)
373
+
374
+ expect( buf.string.scan("#define FOO 1").length ).to eq(1)
375
+ end
376
+
377
+ it "does not carry a macro into the shared header when it appears only after every type-defining item" do
378
+ output_path = '/path/to/output'
379
+ name = 'my_module'
380
+ header_filename = 'my_module_types.h'
381
+
382
+ allow(@file_path_utils).to receive(:form_partial_types_header_filename).and_return(header_filename)
383
+
384
+ buf = StringIO.new()
385
+ allow(@file_wrapper).to receive(:open).and_yield(buf)
386
+
387
+ typedef_stmt = CExtractorTypes::CStatement.new(text: "typedef int Foo;", line_num: 1)
388
+ macro_stmt = CExtractorTypes::CStatement.new(text: "#define FOO 1", line_num: 2)
389
+
390
+ c_module = CExtractorTypes::CModule.new(
391
+ type_definitions: [typedef_stmt],
392
+ macro_definitions: [macro_stmt],
393
+ element_sequence: [typedef_stmt, macro_stmt]
394
+ )
395
+
396
+ @generator.generate_types(name: name, c_module: c_module, output_path: output_path)
397
+
398
+ expect( buf.string ).to_not include("#define FOO 1")
399
+ end
297
400
  end
298
401
 
299
402
  context "#generate_header (private method)" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ceedling
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark VanderVoord
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2026-08-14 00:00:00.000000000 Z
13
+ date: 2026-08-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake