diff --git a/lib/cmock_file_writer.rb b/lib/cmock_file_writer.rb index 8e1de00..b21ed4b 100644 --- a/lib/cmock_file_writer.rb +++ b/lib/cmock_file_writer.rb @@ -16,6 +16,17 @@ class CMockFileWriter require 'fileutils' FileUtils.mkdir_p "#{@config.mock_path}/" unless Dir.exist?("#{@config.mock_path}/") FileUtils.mkdir_p "#{@config.mock_path}/#{"#{subdir}/" if subdir}" if subdir && !Dir.exist?("#{@config.mock_path}/#{"#{subdir}/" if subdir}") + rescue SystemCallError => e + raise "Unable to create mock output directory: #{e.message}. Check :mock_path ('#{@config.mock_path}') configuration." + end + + def create_skeleton_subdir(subdir) + require 'fileutils' + base = effective_skeleton_path + FileUtils.mkdir_p base + FileUtils.mkdir_p "#{base}/#{subdir}" if subdir + rescue SystemCallError => e + raise "Unable to create skeleton output directory: #{e.message}. Check :skeleton_path ('#{base}') configuration." end def create_file(filename, subdir) @@ -27,6 +38,27 @@ class CMockFileWriter yield(file, filename) end update_file(full_file_name_done, full_file_name_temp) + rescue SystemCallError => e + raise "Unable to write mock file '#{full_file_name_done}': #{e.message}. Check :mock_path ('#{@config.mock_path}') and :subdir ('#{subdir}') configuration." + end + + def create_skeleton_file(filename, subdir) + raise "Where's the block of data to create?" unless block_given? + + base = effective_skeleton_path + full_file_name_temp = "#{base}/#{"#{subdir}/" if subdir}#{filename}.new" + full_file_name_done = "#{base}/#{"#{subdir}/" if subdir}#{filename}" + File.open(full_file_name_temp, 'w') do |file| + yield(file, filename) + end + update_file(full_file_name_done, full_file_name_temp) + rescue SystemCallError => e + raise "Unable to write skeleton file '#{full_file_name_done}': #{e.message}. Check :skeleton_path ('#{base}') and :subdir ('#{subdir}') configuration." + end + + def skeleton_file_path(filename, subdir) + base = effective_skeleton_path + "#{base}/#{"#{subdir}/" if subdir}#{filename}" end def append_file(filename, subdir) @@ -40,6 +72,11 @@ class CMockFileWriter private ################################### + def effective_skeleton_path + path = @config.skeleton_path + path.nil? || path.empty? ? @config.mock_path : path + end + def update_file(dest, src) require 'fileutils' FileUtils.rm(dest, :force => true) diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index dd0b9b1..516599a 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -85,6 +85,7 @@ class CMockGenerator :skeleton => true } + @file_writer.create_skeleton_subdir(@subdir) create_skeleton_source_file(mock_project) end @@ -133,9 +134,9 @@ class CMockGenerator end def create_skeleton_source_file(mock_project) - filename = "#{@config.mock_path}/#{"#{@subdir}/" if @subdir}#{mock_project[:module_name]}.c" + filename = @file_writer.skeleton_file_path("#{mock_project[:module_name]}.c", @subdir) existing = File.exist?(filename) ? File.read(filename) : '' - @file_writer.create_file("#{mock_project[:module_name]}.c", @subdir) do |file, fullname| + @file_writer.create_skeleton_file("#{mock_project[:module_name]}.c", @subdir) do |file, fullname| blank_project = mock_project.clone blank_project[:parsed_stuff] = { :functions => [] } if existing.empty? @@ -210,24 +211,30 @@ class CMockGenerator def create_source_header_section(file, filename, mock_project) header_file = (mock_project[:folder] || '') + filename.sub(/.*\K\.c/, mock_project[:module_ext]) - file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless mock_project[:parsed_stuff][:functions].empty? - file << "#include \n" - file << "#include \n" - unless @exclude_setjmp_h - file << "#include \n" - end - file << "#include \"cmock.h\"\n" - @includes_c_pre_header.each { |inc| file << "#include #{inc}\n" } - file << "#include \"#{header_file}\"\n" - @includes_c_post_header.each { |inc| file << "#include #{inc}\n" } - file << "\n" - strs = [] - mock_project[:parsed_stuff][:functions].each do |func| - strs << func[:name] - func[:args].each { |arg| strs << arg[:name] } - end - strs.uniq.sort.each do |str| - file << "static const char* CMockString_#{str} = \"#{str}\";\n" + if mock_project[:skeleton] + @includes_c_pre_header.each { |inc| file << "#include #{inc}\n" } + file << "#include \"#{header_file}\"\n" + @includes_c_post_header.each { |inc| file << "#include #{inc}\n" } + else + file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless mock_project[:parsed_stuff][:functions].empty? + file << "#include \n" + file << "#include \n" + unless @exclude_setjmp_h + file << "#include \n" + end + file << "#include \"cmock.h\"\n" + @includes_c_pre_header.each { |inc| file << "#include #{inc}\n" } + file << "#include \"#{header_file}\"\n" + @includes_c_post_header.each { |inc| file << "#include #{inc}\n" } + file << "\n" + strs = [] + mock_project[:parsed_stuff][:functions].each do |func| + strs << func[:name] + func[:args].each { |arg| strs << arg[:name] } + end + strs.uniq.sort.each do |str| + file << "static const char* CMockString_#{str} = \"#{str}\";\n" + end end file << "\n" end diff --git a/test/system/test_compilation/parsing.h b/test/system/test_compilation/parsing.h index d75d490..665ab1f 100644 --- a/test/system/test_compilation/parsing.h +++ b/test/system/test_compilation/parsing.h @@ -18,6 +18,16 @@ typedef struct _POINT_T int y; } POINT_T; +/* The comments in the following enum are important, as are the newlines and commas */ +/* This combination caused a curious bug when used together. Make sure it doesn't come back. */ +typedef enum +{ + MY_ERROR_ID = -18,/**< Driver not ready */ + MY_OTHER_ID = -19 /**< Node-id is in LSS unconfigured + state. If objects are handled properly, + his may not be an error. */ +} MY_STATE_ID_T; + /* typedef edge case; not ANSI C but it has been done and will break cmock if not handled */ typedef void VOID_TYPE_CRAZINESS;