diff --git a/Rakefile b/Rakefile index 1382a5afa..7679fa4bc 100644 --- a/Rakefile +++ b/Rakefile @@ -53,6 +53,7 @@ require_relative "rake.d/library" require_relative "rake.d/format_string_verifier" require_relative "rake.d/pch" require_relative "rake.d/po" +require_relative "rake.d/source_tests" require_relative "rake.d/tarball" require_relative 'rake.d/gtest' if $have_gtest @@ -857,6 +858,11 @@ namespace :tests do task :products do run "cd tests && ./run.rb" end + + desc "Run built-in tests on source code files" + task :source do + Mtx::SourceTests.test_include_guards + end end # diff --git a/rake.d/source_tests.rb b/rake.d/source_tests.rb new file mode 100644 index 000000000..9825a2179 --- /dev/null +++ b/rake.d/source_tests.rb @@ -0,0 +1,69 @@ +# coding: utf-8 + +module Mtx::SourceTests + def self.collect_header_files + ui_file_names = FileList["src/**/*.ui"] + ui_header_file_names = ui_file_names.collect { |file_name| file_name.ext 'h' }.to_a + header_file_names = FileList["src/**/*.h"].to_a.sort + + header_file_names - ui_header_file_names + end + + def self.expected_guard_name file_name + "MTX_" + file_name. + gsub(%r{.*src/}, ''). + gsub(%r{[/.]}, '_'). + upcase + end + + def self.test_include_guard_for_file file_name, lines + guard_line_idx = (0...lines.size).select { |idx| %r{^#ifndef +MTX_}.match(lines[idx]) }[0] + + if !guard_line_idx + puts "#{file_name}:1: error: no include guard line found" + return false + end + + ok = true + guard_line = lines[guard_line_idx].chomp + guard_name = guard_line.gsub(%r{^#ifndef +}, '').gsub(%r{ .*}, '') + expected_name = self.expected_guard_name file_name + + if guard_name != expected_name + puts "#{file_name}:#{guard_line_idx + 1}: error: wrong guard name: #{guard_name}; should be: #{expected_name}" + ok = false + end + + guard_def_line = lines[guard_line_idx + 1].chomp + expected_def_line = "#define #{expected_name}" + + if guard_def_line != expected_def_line + puts "#{file_name}:#{guard_line_idx + 2}: error: guard definition line wrong or not found; should be: #{expected_def_line}" + ok = false + end + + guard_end_line = lines.last + expected_end_re = "^\\#endif \\s+ // \\s+ #{expected_name} $" + + if !%r(#{expected_end_re})x.match(guard_end_line) + puts "#{file_name}:#{lines.size}: error: guard end line wrong or not found; should match RE: #{expected_end_re}" + ok = false + end + + ok + end + + def self.test_include_guards + file_names = self.collect_header_files + content = read_files file_names + ok = true + + file_names.each do |file_name| + if !self.test_include_guard_for_file(file_name, content[file_name]) + ok = false + end + end + + exit 1 if !ok + end +end