From c40a6e08c69b99c68416def593d7b621199e00b5 Mon Sep 17 00:00:00 2001 From: Mark VanderVoord Date: Thu, 28 May 2026 16:48:53 -0400 Subject: [PATCH] Refactored self-tests to use ceedling-formatted tools files --- examples/temp_sensor/rakefile_helper.rb | 37 +++- src/cmock.c | 236 ++++++++++++------------ src/cmock.h | 8 +- src/cmock_internals.h | 64 +++---- test/rakefile | 42 +++-- test/rakefile_helper.rb | 67 ++++--- vendor/unity | 2 +- 7 files changed, 253 insertions(+), 203 deletions(-) diff --git a/examples/temp_sensor/rakefile_helper.rb b/examples/temp_sensor/rakefile_helper.rb index e31a6bf..07f51ab 100644 --- a/examples/temp_sensor/rakefile_helper.rb +++ b/examples/temp_sensor/rakefile_helper.rb @@ -39,24 +39,38 @@ module RakefileHelpers $cfg_file = config_file $proj = load_yaml(File.read('./project.yml')) - unity_target = "../../vendor/unity/test/targets/#{$cfg_file}" + unity_targets_dir = '../../vendor/unity/test/targets' cmock_targets_dir = '../../test/targets' + config_basename = File.basename(config_file) + path_specified = File.dirname(config_file) != '.' + + # Resolve the target file location: + # - path specified → use only that location + # - no path → check current directory first, then vendor unity targets + unity_target = if path_specified + config_file + elsif File.exist?("./#{config_file}") + "./#{config_file}" + else + "#{unity_targets_dir}/#{config_file}" + end if File.exist?(unity_target) puts "Loading Unity target: #{unity_target}" $unity_cfg = load_yaml(File.read(unity_target)) - cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, $cfg_file) + cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, config_basename) if cmock_file puts "Loading CMock overlay: #{cmock_targets_dir}/#{cmock_file}" $cmock_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{cmock_file}")) else - puts "No CMock overlay found for #{$cfg_file}" + puts "No CMock overlay found for #{config_file}" $cmock_cfg = {} end else - puts "Loading CMock-only target: #{cmock_targets_dir}/#{$cfg_file}" - $unity_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{$cfg_file}")) + # CMock-only target (no Unity equivalent); it uses Unity format directly + puts "Loading CMock-only target: #{cmock_targets_dir}/#{config_basename}" + $unity_cfg = load_yaml(File.read("#{cmock_targets_dir}/#{config_basename}")) $cmock_cfg = {} end @@ -133,12 +147,23 @@ module RakefileHelpers end end - # Resolve Unity's argument template tokens into a flat argument string. + # Resolve argument template tokens into a flat argument string. + # Supports Ceedling-style positional tokens and legacy Unity COLLECTION_* tokens. + # ${5} → expands to one arg per include path (toolchain paths + project paths combined) + # ${6} → expands to one arg per define + # ${1} → input file(s) + # ${2} → output file def build_argument_list(raw_args, toolchain_paths, project_paths, defines, input, output) result = [] raw_args.each do |arg| if arg.is_a?(Array) result << arg.join + elsif arg.include?('${5}') + (toolchain_paths + project_paths).each do |p| + result << arg.gsub('${5}', p.is_a?(Array) ? p.join : p.to_s) + end + elsif arg.include?('${6}') + defines.each { |d| result << arg.gsub('${6}', d) } elsif arg.include?('COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE') toolchain_paths.each { |p| result << "-I\"#{p.is_a?(Array) ? p.join : p}\"" } elsif arg.include?('COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR') diff --git a/src/cmock.c b/src/cmock.c index 445028d..28f276f 100644 --- a/src/cmock.c +++ b/src/cmock.c @@ -22,14 +22,14 @@ const char* CMockStringMismatch = "Function called with unexpected argument v /* private variables */ #ifdef CMOCK_MEM_DYNAMIC -static unsigned char* CMock_Guts_Buffer = NULL; -static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE; -static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; + static unsigned char* CMock_Guts_Buffer = NULL; + static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE; + static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; #else -static long long CMock_Guts_Space[(CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE + sizeof(long long) - 1) / sizeof(long long)]; -static unsigned char* CMock_Guts_Buffer = (unsigned char *)CMock_Guts_Space; -static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;//sizeof(CMock_Guts_Space); -static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; + static long long CMock_Guts_Space[(CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE + sizeof(long long) - 1) / sizeof(long long)]; + static unsigned char* CMock_Guts_Buffer = (unsigned char*)CMock_Guts_Space; + static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;//sizeof(CMock_Guts_Space); + static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; #endif /*------------------------------------------------------- @@ -37,41 +37,41 @@ static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size) { - CMOCK_MEM_INDEX_TYPE index; + CMOCK_MEM_INDEX_TYPE index; - /* verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) */ - if (size < 1) - { - return CMOCK_GUTS_NONE; - } + /* verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) */ + if (size < 1) + { + return CMOCK_GUTS_NONE; + } - /* verify we have enough room */ - size = size + CMOCK_MEM_INDEX_SIZE; - if (size & CMOCK_MEM_ALIGN_MASK) - { - size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK; - } - if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size) - { + /* verify we have enough room */ + size = size + CMOCK_MEM_INDEX_SIZE; + if (size & CMOCK_MEM_ALIGN_MASK) + { + size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK; + } + if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size) + { #ifndef CMOCK_MEM_DYNAMIC - return CMOCK_GUTS_NONE; /* nothing we can do; our static buffer is out of memory */ + return CMOCK_GUTS_NONE; /* nothing we can do; our static buffer is out of memory */ #else - /* our dynamic buffer does not have enough room; request more via realloc() */ - CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size; - unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize); - if (new_buffer == NULL) - return CMOCK_GUTS_NONE; /* realloc() failed; out of memory */ - CMock_Guts_Buffer = new_buffer; - CMock_Guts_BufferSize = new_buffersize; + /* our dynamic buffer does not have enough room; request more via realloc() */ + CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size; + unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize); + if (new_buffer == NULL) + return CMOCK_GUTS_NONE; /* realloc() failed; out of memory */ + CMock_Guts_Buffer = new_buffer; + CMock_Guts_BufferSize = new_buffersize; #endif - } + } - /* determine where we're putting this new block, and init its pointer to be the end of the line */ - index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE; - *(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE; - CMock_Guts_FreePtr += size; + /* determine where we're putting this new block, and init its pointer to be the end of the line */ + index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE; + *(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE; + CMock_Guts_FreePtr += size; - return index; + return index; } /*------------------------------------------------------- @@ -79,47 +79,49 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size) *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index) { - CMOCK_MEM_INDEX_TYPE index; - void* root; - void* obj; - void* next; + CMOCK_MEM_INDEX_TYPE index; + void* root; + void* obj; + void* next; - if (root_index == CMOCK_GUTS_NONE) - { - /* if there is no root currently, we return this object as the root of the chain */ - return obj_index; - } - else - { - /* reject illegal nodes */ - if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr)) + if (root_index == CMOCK_GUTS_NONE) { - return CMOCK_GUTS_NONE; + /* if there is no root currently, we return this object as the root of the chain */ + return obj_index; } - if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr)) + else { - return CMOCK_GUTS_NONE; + /* reject illegal nodes */ + if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + + root = (void*)(&CMock_Guts_Buffer[root_index]); + obj = (void*)(&CMock_Guts_Buffer[obj_index]); + + /* find the end of the existing chain and add us */ + next = root; + do + { + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE); + if (index >= CMock_Guts_FreePtr) + { + return CMOCK_GUTS_NONE; + } + if (index > 0) + { + next = (void*)(&CMock_Guts_Buffer[index]); + } + } + while (index > 0); + *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer); + return root_index; } - - root = (void*)(&CMock_Guts_Buffer[root_index]); - obj = (void*)(&CMock_Guts_Buffer[obj_index]); - - /* find the end of the existing chain and add us */ - next = root; - do { - index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE); - if (index >= CMock_Guts_FreePtr) - { - return CMOCK_GUTS_NONE; - } - if (index > 0) - { - next = (void*)(&CMock_Guts_Buffer[index]); - } - } while (index > 0); - *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer); - return root_index; - } } /*------------------------------------------------------- @@ -127,27 +129,27 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_ *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) { - CMOCK_MEM_INDEX_TYPE index; - void* previous_item; + CMOCK_MEM_INDEX_TYPE index; + void* previous_item; - /* There is nothing "next" if the pointer isn't from our buffer */ - if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr)) - { - return CMOCK_GUTS_NONE; - } - previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]); + /* There is nothing "next" if the pointer isn't from our buffer */ + if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]); - /* if the pointer is good, then use it to look up the next index - * (we know the first element always goes in zero, so NEXT must always be > 1) */ - index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE); - if ((index > 1) && (index < CMock_Guts_FreePtr)) - { - return index; - } - else - { - return CMOCK_GUTS_NONE; - } + /* if the pointer is good, then use it to look up the next index + * (we know the first element always goes in zero, so NEXT must always be > 1) */ + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE); + if ((index > 1) && (index < CMock_Guts_FreePtr)) + { + return index; + } + else + { + return CMOCK_GUTS_NONE; + } } /*------------------------------------------------------- @@ -155,17 +157,17 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) { - CMOCK_MEM_INDEX_TYPE index = root_index; - CMOCK_MEM_INDEX_TYPE next_index; + CMOCK_MEM_INDEX_TYPE index = root_index; + CMOCK_MEM_INDEX_TYPE next_index; - for (next_index = root_index; - next_index != CMOCK_GUTS_NONE; - next_index = CMock_Guts_MemNext(index)) - { - index = next_index; - } + for (next_index = root_index; + next_index != CMOCK_GUTS_NONE; + next_index = CMock_Guts_MemNext(index)) + { + index = next_index; + } - return index; + return index; } /*------------------------------------------------------- @@ -173,14 +175,14 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) *-------------------------------------------------------*/ void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) { - if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr)) - { - return (void*)(&CMock_Guts_Buffer[index]); - } - else - { - return NULL; - } + if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr)) + { + return (void*)(&CMock_Guts_Buffer[index]); + } + else + { + return NULL; + } } /*------------------------------------------------------- @@ -188,7 +190,7 @@ void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) { - return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE); + return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE); } /*------------------------------------------------------- @@ -196,7 +198,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) { - return CMock_Guts_BufferSize - CMock_Guts_FreePtr; + return CMock_Guts_BufferSize - CMock_Guts_FreePtr; } /*------------------------------------------------------- @@ -204,7 +206,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) { - return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE; + return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE; } /*------------------------------------------------------- @@ -212,7 +214,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) *-------------------------------------------------------*/ void CMock_Guts_MemFreeAll(void) { - CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; /* skip the very beginning */ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; /* skip the very beginning */ } /*------------------------------------------------------- @@ -220,13 +222,13 @@ void CMock_Guts_MemFreeAll(void) *-------------------------------------------------------*/ void CMock_Guts_MemFreeFinal(void) { - CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; #ifdef CMOCK_MEM_DYNAMIC - if (CMock_Guts_Buffer) - { - free(CMock_Guts_Buffer); - CMock_Guts_Buffer = NULL; - } + if (CMock_Guts_Buffer) + { + free(CMock_Guts_Buffer); + CMock_Guts_Buffer = NULL; + } #endif } diff --git a/src/cmock.h b/src/cmock.h index f0a2bcf..d7b2a5b 100644 --- a/src/cmock.h +++ b/src/cmock.h @@ -17,16 +17,16 @@ /* should be big enough to index full range of CMOCK_MEM_MAX */ #ifndef CMOCK_MEM_INDEX_TYPE -#include -#define CMOCK_MEM_INDEX_TYPE size_t + #include + #define CMOCK_MEM_INDEX_TYPE size_t #endif #define CMOCK_GUTS_NONE (0) #if defined __GNUC__ -# define CMOCK_FUNCTION_ATTR(a) __attribute__((a)) + #define CMOCK_FUNCTION_ATTR(a) __attribute__((a)) #else -# define CMOCK_FUNCTION_ATTR(a) /* ignore */ + #define CMOCK_FUNCTION_ATTR(a) /* ignore */ #endif /*------------------------------------------------------- diff --git a/src/cmock_internals.h b/src/cmock_internals.h index 15ee8d5..3877296 100644 --- a/src/cmock_internals.h +++ b/src/cmock_internals.h @@ -26,61 +26,61 @@ extern const char* CMockStringMismatch; /* define CMOCK_MEM_DYNAMIC to grab memory as needed with malloc * when you do that, CMOCK_MEM_SIZE is used for incremental size instead of total */ #ifdef CMOCK_MEM_STATIC -#undef CMOCK_MEM_DYNAMIC + #undef CMOCK_MEM_DYNAMIC #endif #ifdef CMOCK_MEM_DYNAMIC -#include + #include #endif /* this is used internally during pointer arithmetic. make sure this type is the same size as the target's pointer type */ #ifndef CMOCK_MEM_PTR_AS_INT -#ifdef UNITY_POINTER_WIDTH -#ifdef UNITY_INT_WIDTH -#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH -#define CMOCK_MEM_PTR_AS_INT unsigned int -#endif -#endif -#endif + #ifdef UNITY_POINTER_WIDTH + #ifdef UNITY_INT_WIDTH + #if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH + #define CMOCK_MEM_PTR_AS_INT unsigned int + #endif + #endif + #endif #endif #ifndef CMOCK_MEM_PTR_AS_INT -#ifdef UNITY_POINTER_WIDTH -#ifdef UNITY_LONG_WIDTH -#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH -#define CMOCK_MEM_PTR_AS_INT unsigned long -#endif -#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH -#define CMOCK_MEM_PTR_AS_INT unsigned long long -#endif -#endif -#endif + #ifdef UNITY_POINTER_WIDTH + #ifdef UNITY_LONG_WIDTH + #if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH + #define CMOCK_MEM_PTR_AS_INT unsigned long + #endif + #if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH + #define CMOCK_MEM_PTR_AS_INT unsigned long long + #endif + #endif + #endif #endif #ifndef CMOCK_MEM_PTR_AS_INT -#define CMOCK_MEM_PTR_AS_INT unsigned long + #define CMOCK_MEM_PTR_AS_INT unsigned long #endif /* 0 for no alignment, 1 for 16-bit, 2 for 32-bit, 3 for 64-bit */ #ifndef CMOCK_MEM_ALIGN - #ifdef UNITY_LONG_WIDTH - #if (UNITY_LONG_WIDTH == 16) - #define CMOCK_MEM_ALIGN (1) - #elif (UNITY_LONG_WIDTH == 32) - #define CMOCK_MEM_ALIGN (2) - #elif (UNITY_LONG_WIDTH == 64) - #define CMOCK_MEM_ALIGN (3) + #ifdef UNITY_LONG_WIDTH + #if (UNITY_LONG_WIDTH == 16) + #define CMOCK_MEM_ALIGN (1) + #elif (UNITY_LONG_WIDTH == 32) + #define CMOCK_MEM_ALIGN (2) + #elif (UNITY_LONG_WIDTH == 64) + #define CMOCK_MEM_ALIGN (3) + #else + #define CMOCK_MEM_ALIGN (2) + #endif #else - #define CMOCK_MEM_ALIGN (2) + #define CMOCK_MEM_ALIGN (2) #endif - #else - #define CMOCK_MEM_ALIGN (2) - #endif #endif /* amount of memory to allow cmock to use in its internal heap */ #ifndef CMOCK_MEM_SIZE -#define CMOCK_MEM_SIZE (32768) + #define CMOCK_MEM_SIZE (32768) #endif /* automatically calculated defs for easier reading */ diff --git a/test/rakefile b/test/rakefile index c9ec434..3e2df22 100644 --- a/test/rakefile +++ b/test/rakefile @@ -27,18 +27,22 @@ SYSTEM_TEST_SUPPORT_DIRS.each do |dir| CLOBBER.include(dir) end +$config_file = DEFAULT_CONFIG_FILE +$overlay_file = nil task :prep_system_tests => SYSTEM_TEST_SUPPORT_DIRS - -configure_toolchain(DEFAULT_CONFIG_FILE) - task :default => [:test] task :ci => [:no_color, :default, 'test:examples', 'style:check', 'test:summary'] task :cruise => :ci desc "Load configuration" task :config, [:config_file, :cmock_overlay] do |t, args| - configure_toolchain(args[:config_file], args[:cmock_overlay]) + $config_file = args[:config_file] + $overlay_file = args[:cmock_overlay] +end + +task :config_toolchains do + configure_toolchain($config_file, $overlay_file) end # Still support testing everything with just 'test' but switch default to ceedling-like test:all @@ -46,30 +50,30 @@ task :test => ['test:all'] namespace :test do desc "Run all unit, c, and system tests" - task :all => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] + task :all => [:config_toolchains, :clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] desc "Run Unit Tests" - task :units => [:prep_system_tests] do + task :units => [:config_toolchains, :prep_system_tests] do run_ruby_unit_tests end #individual unit tests FileList['unit/*_test.rb'].each do |test| - Rake::TestTask.new(File.basename(test,'.*').sub('_test','')) do |t| + Rake::TestTask.new(File.basename(test,'.*').sub('_test','') => [:config_toolchains]) do |t| t.pattern = test t.verbose = true end end desc "Run C Unit Tests" - task :c => [:prep_system_tests] do + task :c => [:config_toolchains, :prep_system_tests] do unless (unsupported_tests.include? "C") build_and_test_c_files end end desc "Run System Tests" - task :system => [:clobber, :prep_system_tests] do + task :system => [:config_toolchains, :clobber, :prep_system_tests] do #get a list of all system tests, removing unsupported tests for this compiler sys_unsupported = unsupported_tests.map {|a| 'system/test_interactions/'+a+'.yml'} sys_tests_to_run = FileList['system/test_interactions/*.yml'] - sys_unsupported @@ -88,7 +92,7 @@ namespace :test do end desc "Test cmock examples" - task :examples => [:prep_system_tests] do + task :examples => [:config_toolchains, :prep_system_tests] do run_examples(true) end @@ -96,13 +100,13 @@ namespace :test do FileList['system/test_interactions/*.yml'].each do |test| basename = File.basename(test,'.*') #desc "Run system test #{basename}" - task basename do + task basename => [:config_toolchains] do run_system_test_interactions([test]) end end desc "Profile Mock Generation" - task :profile => [:clobber, :prep_system_tests] do + task :profile => [:config_toolchains, :clobber, :prep_system_tests] do run_system_test_profiles(FileList[SYSTEST_COMPILE_MOCKABLES_PATH + '*.h']) end @@ -119,7 +123,7 @@ end ################### CODING STYLE VALIDATION namespace :style do desc "Check style" - task :check do + task :check => [:config_toolchains] do report "\n" report "--------------------\n" report "VERIFYING RUBY STYLE\n" @@ -129,25 +133,25 @@ namespace :style do end desc "Fix Style of all C Code" - task :c do - run_astyle("../src/*.* ../extras/fixture/src/*.*") + task :c => [:config_toolchains]do + run_astyle("../src/*.*") end desc "Attempt to Autocorrect style" - task :auto => ['style:clean'] do + task :auto => [:config_toolchains, 'style:clean'] do execute("rubocop ../lib ../examples ../config ../scripts --autocorrect --config ../vendor/unity/test/.rubocop.yml", true) report "Autocorrected What We Could." end desc "Update style todo list" - task :todo => ['style:clean'] do + task :todo => [:config_toolchains, 'style:clean'] do execute("rubocop ../lib ../examples ../config ../scripts --auto-gen-config --config ../vendor/unity/test/.rubocop.yml", true) report "Updated Style TODO List." end - task :clean do + task :clean => [:config_toolchains] do File.delete(".rubocop_todo.yml") if File.exist?(".rubocop_todo.yml") end end -task :style => ['style:check'] \ No newline at end of file +task :style => [:config_toolchains, 'style:check'] \ No newline at end of file diff --git a/test/rakefile_helper.rb b/test/rakefile_helper.rb index bfe4d27..0fcdf7e 100644 --- a/test/rakefile_helper.rb +++ b/test/rakefile_helper.rb @@ -46,27 +46,37 @@ module RakefileHelpers $cfg_file = config_file $proj = load_yaml('./project.yml') - unity_target = "../vendor/unity/test/targets/#{$cfg_file}" + unity_targets_dir = '../vendor/unity/test/targets' cmock_targets_dir = './targets' + config_basename = File.basename(config_file) + path_specified = File.dirname(config_file) != '.' - if File.exist?(unity_target) + # Resolve the target file location: + # - path specified → use only that location + # - no path → check current directory first, then vendor unity targets + config_target = if path_specified + config_file + elsif File.exist?("./#{config_file}") + "./#{config_file}" + else + "#{unity_targets_dir}/#{config_file}" + end + + if File.exist?(config_target) # Load Unity base target, then CMock overlay (unsupported list, extra defines) - puts "Loading Unity target: #{unity_target}" - $unity_cfg = load_yaml(unity_target) + puts "Loading Toolchain target: #{config_target}" + $unity_cfg = load_yaml(config_target) - cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, $cfg_file) + cmock_file = cmock_overlay || find_cmock_target(cmock_targets_dir, config_basename) if cmock_file - puts "Loading CMock overlay: #{cmock_targets_dir}/#{cmock_file}" + puts "Loading Toolchain overlay: #{cmock_targets_dir}/#{cmock_file}" $cmock_cfg = load_yaml("#{cmock_targets_dir}/#{cmock_file}") else - puts "No CMock overlay found for #{$cfg_file}" + puts "No Toolchain overlay found for #{config_file}" $cmock_cfg = {} end else - # CMock-only target (no Unity equivalent); it uses Unity format directly - puts "Loading CMock-only target: #{cmock_targets_dir}/#{$cfg_file}" - $unity_cfg = load_yaml("#{cmock_targets_dir}/#{$cfg_file}") - $cmock_cfg = {} + raise "Cannot find Config File #{config_target}" end $colour_output = $proj[:project][:colour] @@ -131,7 +141,7 @@ module RakefileHelpers # Toolchain-specific include paths: Array items in Unity's :paths: :test: # (e.g., IAR compiler include directories encoded as path-concatenation arrays) def toolchain_include_paths - ($unity_cfg[:paths][:test] || []).select { |p| p.is_a?(Array) } + (($unity_cfg[:paths] || {})[:test] || []).select { |p| p.is_a?(Array) } end # Returns the unsupported test list, regardless of whether it came from @@ -140,17 +150,26 @@ module RakefileHelpers $cmock_cfg[:unsupported] || $unity_cfg[:unsupported] || [] end - # Resolve Unity's argument template tokens and produce a flat argument string. - # COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE → -I per toolchain path (Arrays from :paths: :test:) - # COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR → -I per project include path - # COLLECTION_DEFINES_TEST_AND_VENDOR → -D per define + # Resolve argument template tokens and produce a flat argument string. + # Supports Ceedling-style positional tokens and legacy Unity COLLECTION_* tokens. + # ${5} → expands to one arg per include path (toolchain paths + project paths combined) + # ${6} → expands to one arg per define # ${1} → input file(s) # ${2} → output file + # COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE → (legacy) -I per toolchain path + # COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR → (legacy) -I per project include path + # COLLECTION_DEFINES_TEST_AND_VENDOR → (legacy) -D per define def build_argument_list(raw_args, toolchain_paths, project_paths, defines, input, output) result = [] raw_args.each do |arg| if arg.is_a?(Array) result << arg.join + elsif arg.include?('${5}') + (toolchain_paths + project_paths).each do |p| + result << arg.gsub('${5}', p.is_a?(Array) ? p.join : p.to_s) + end + elsif arg.include?('${6}') + defines.each { |d| result << arg.gsub('${6}', d) } elsif arg.include?('COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE') toolchain_paths.each { |p| result << "-I\"#{p.is_a?(Array) ? p.join : p}\"" } elsif arg.include?('COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR') @@ -166,8 +185,8 @@ module RakefileHelpers def compile(file, extra_defines = []) tool = $unity_cfg[:tools][:test_compiler] - ext = $unity_cfg[:extension][:object] - build_root = $proj[:project][:build_root] + ext = $unity_cfg[:extension][:object] || '.o' + build_root = $proj[:project][:build_root] || 'build/' obj_file = build_root + File.basename(file, C_EXTENSION) + ext cmd_str = tackit(tool[:executable]) + ' ' + @@ -181,8 +200,8 @@ module RakefileHelpers end def link_it(exe_name, obj_list) - tool = $unity_cfg[:tools][:test_linker] - ext = $unity_cfg[:extension][:executable] + tool = $unity_cfg[:tools][:test_linker] + ext = $unity_cfg[:extension][:executable] || '' build_root = $proj[:project][:build_root] input_files = obj_list.uniq.map { |obj| build_root + obj }.join(' ') @@ -224,7 +243,7 @@ module RakefileHelpers "--style=allman --indent=spaces=4 --indent-switches --indent-preproc-define --indent-preproc-block " \ "--pad-oper --pad-comma --unpad-paren --pad-header " \ "--align-pointer=type --align-reference=name " \ - "--add-brackets --mode=c --suffix=none " \ + "--mode=c --suffix=none " \ "#{style_what}" execute(command, false) report "Styling C:PASS" @@ -345,7 +364,7 @@ module RakefileHelpers # Execute unit test and generate results file simulator = build_simulator_fields - ext = $unity_cfg[:extension][:executable] + ext = $unity_cfg[:extension][:executable] || '' build_root = $proj[:project][:build_root] executable = build_root + test_base + ext cmd_str = if simulator.nil? @@ -482,7 +501,7 @@ module RakefileHelpers report "----------------\n" report "UNIT TEST C CODE\n" report "----------------\n" - ext = $unity_cfg[:extension][:executable] + ext = $unity_cfg[:extension][:executable] || '' build_root = $proj[:project][:build_root] combined_output = '' FileList.new("c/*.yml").each do |yaml_file| @@ -490,7 +509,7 @@ module RakefileHelpers report "\nTesting #{yaml_file.sub('.yml','')}" report "(#{test[:options].join(', ')})" test[:files].each { |f| compile(f, test[:options]) } - obj_files = test[:files].map { |f| f.gsub!(/.*\//,'').gsub!(C_EXTENSION, $unity_cfg[:extension][:object]) } + obj_files = test[:files].map { |f| f.gsub!(/.*\//,'').gsub!(C_EXTENSION, $unity_cfg[:extension][:object] || '.o') } link_it('TestCMockC', obj_files) simulator = build_simulator_fields executable = build_root + 'TestCMockC' + ext diff --git a/vendor/unity b/vendor/unity index 4fe7d60..444fbda 160000 --- a/vendor/unity +++ b/vendor/unity @@ -1 +1 @@ -Subproject commit 4fe7d60259ff5d18a15c43b26ddfbcbdae9360ae +Subproject commit 444fbda72a77932c3c96aed6c203d96963c1b7bf