XMake: Add automatic header order fix
This commit is contained in:
parent
f491ee1e38
commit
66206868cd
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef NAZARA_OPENGLRENDERER_WRAPPER_COREFUNCTIONS_HPP
|
||||
#define NAZARA_OPENGLRENDERER_WRAPPER_COREFUNCTIONS_HPP
|
||||
|
||||
// no include reordering
|
||||
|
||||
#define GL_GLES_PROTOTYPES 0
|
||||
#include <GLES3/gl32.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
||||
|
||||
// no include reordering
|
||||
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GL/wgl.h>
|
||||
#include <GL/wglext.h>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
||||
|
||||
// no include reordering
|
||||
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GL/wgl.h>
|
||||
#include <GL/wglext.h>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,42 @@ local function CompareLines(referenceLines, lines, firstLine, lineCount)
|
|||
return true
|
||||
end
|
||||
|
||||
local function ComputeHeaderFile(filePath)
|
||||
local headerPath = filePath:gsub("[\\/]", "/")
|
||||
headerPath = headerPath:sub(headerPath:find("Nazara/"), -1)
|
||||
headerPath = headerPath:sub(1, headerPath:find("%..+$") - 1) .. ".hpp"
|
||||
|
||||
return headerPath
|
||||
end
|
||||
|
||||
local systemHeaders = {
|
||||
["fcntl.h"] = true,
|
||||
["mstcpip"] = true,
|
||||
["netdb.h"] = true,
|
||||
["poll.h"] = true,
|
||||
["process.h"] = true,
|
||||
["pthread.h"] = true,
|
||||
["unistd.h"] = true,
|
||||
["windows.h"] = true,
|
||||
["winsock2"] = true,
|
||||
}
|
||||
|
||||
local function IsSystemHeader(header)
|
||||
if systemHeaders[header] then
|
||||
return true
|
||||
end
|
||||
|
||||
if header:match("netinet/.*") then
|
||||
return true
|
||||
end
|
||||
|
||||
if header:match("sys/.*") then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
on_run(function ()
|
||||
import("core.base.option")
|
||||
|
||||
|
|
@ -281,10 +317,7 @@ on_run(function ()
|
|||
for _, filePath in pairs(files) do
|
||||
local lines = GetFile(filePath)
|
||||
|
||||
local headerPath = filePath:gsub("[\\/]", "/")
|
||||
headerPath = headerPath:sub(headerPath:find("Nazara/"), -1)
|
||||
headerPath = headerPath:sub(1, headerPath:find("%..+$") - 1) .. ".hpp"
|
||||
|
||||
local headerPath = ComputeHeaderFile(filePath)
|
||||
if os.isfile("include/" .. headerPath) or os.isfile("src/" .. headerPath) then
|
||||
local inclusions = {}
|
||||
|
||||
|
|
@ -296,7 +329,7 @@ on_run(function ()
|
|||
break
|
||||
end
|
||||
|
||||
local includeMode, includePath = lines[i]:match("^%s*#%s*include%s*([<\"])(.+)[>\"]")
|
||||
local includeMode, includePath = lines[i]:match("^#include%s*([<\"])(.+)[>\"]")
|
||||
if includeMode then
|
||||
table.insert(inclusions, {
|
||||
line = i,
|
||||
|
|
@ -307,36 +340,24 @@ on_run(function ()
|
|||
end
|
||||
|
||||
if #inclusions > 0 then
|
||||
local increment = 0
|
||||
|
||||
-- Add corresponding header
|
||||
local headerInclude
|
||||
for i = 1, #inclusions do
|
||||
if inclusions[i].path == headerPath then
|
||||
headerInclude = i
|
||||
if i ~= 1 then
|
||||
print(filePath .. " doesn't include corresponding header first")
|
||||
|
||||
local currentInclusion = inclusions[i]
|
||||
table.insert(fixes, {
|
||||
File = filePath,
|
||||
Func = function (lines)
|
||||
table.remove(lines, currentInclusion.line)
|
||||
local firstHeaderLine = inclusions[1].line
|
||||
table.insert(lines, firstHeaderLine, "#include <" .. headerPath .. ">")
|
||||
|
||||
return lines
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Check debug headers
|
||||
local debugIncludeModule = moduleName ~= "Math" and moduleName or "Core"
|
||||
|
||||
local debugInclude
|
||||
local debugIncludeOff
|
||||
for i = 1, #inclusions do
|
||||
local module, off = inclusions[i].path:match("Nazara/(.+)/Debug(O?f?f?).hpp")
|
||||
local module, off = inclusions[i].path:match("^Nazara/(.+)/Debug(O?f?f?).hpp$")
|
||||
if module then
|
||||
if off == "Off" then
|
||||
debugIncludeOff = i
|
||||
|
|
@ -361,8 +382,7 @@ on_run(function ()
|
|||
end
|
||||
end
|
||||
|
||||
local increment = 0
|
||||
|
||||
-- Add header inclusion if it's missing
|
||||
if not headerInclude then
|
||||
print(filePath .. " is missing corresponding header inclusion")
|
||||
|
||||
|
|
@ -392,7 +412,7 @@ on_run(function ()
|
|||
end
|
||||
|
||||
if path.extension(filePath) == ".inl" then
|
||||
if not debugInclude then
|
||||
if not debugIncludeOff then
|
||||
print(filePath .. ": has missing DebugOff include")
|
||||
table.insert(fixes, {
|
||||
File = filePath,
|
||||
|
|
@ -413,6 +433,153 @@ on_run(function ()
|
|||
end
|
||||
})
|
||||
|
||||
-- Reorder includes and remove duplicates
|
||||
table.insert(checks, {
|
||||
Name = "inclusion order",
|
||||
Check = function (moduleName)
|
||||
local files = table.join(
|
||||
os.files("include/Nazara/" .. moduleName .. "/**.hpp"),
|
||||
os.files("include/Nazara/" .. moduleName .. "/**.inl"),
|
||||
os.files("src/Nazara/" .. moduleName .. "/**.hpp"),
|
||||
os.files("src/Nazara/" .. moduleName .. "/**.inl"),
|
||||
os.files("src/Nazara/" .. moduleName .. "/**.cpp")
|
||||
)
|
||||
|
||||
local fixes = {}
|
||||
for _, filePath in pairs(files) do
|
||||
local lines = GetFile(filePath)
|
||||
|
||||
local headerPath = ComputeHeaderFile(filePath)
|
||||
|
||||
local inclusions = {}
|
||||
|
||||
-- Retrieve all inclusions from the first inclusion block
|
||||
for i = 1, #lines do
|
||||
if lines[i] == "// no include reordering" then
|
||||
-- ignore file
|
||||
inclusions = {}
|
||||
break
|
||||
end
|
||||
|
||||
local includeMode, includePath = lines[i]:match("^#include%s*([<\"])(.+)[>\"]")
|
||||
if includeMode then
|
||||
table.insert(inclusions, {
|
||||
line = i,
|
||||
mode = includeMode,
|
||||
path = includePath
|
||||
})
|
||||
elseif #inclusions > 0 then
|
||||
-- Stop when outside the inclusion block
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local debugIncludeModule = moduleName ~= "Math" and moduleName or "Core"
|
||||
|
||||
local includeList = {}
|
||||
local shouldReorder = false
|
||||
for i = 1, #inclusions do
|
||||
local order
|
||||
if inclusions[i].path == headerPath or inclusions[i].path == "Nazara/Prerequisites.hpp" then
|
||||
order = 0 -- own include comes first
|
||||
elseif inclusions[i].path == "Nazara/" .. debugIncludeModule .. "/Debug.hpp" then
|
||||
order = 5 -- debug include
|
||||
elseif inclusions[i].path:match("^Nazara/") then
|
||||
order = 1 -- engine includes
|
||||
elseif IsSystemHeader(inclusions[i].path) then
|
||||
order = 4 -- system includes
|
||||
elseif inclusions[i].path:match(".+%.hp?p?") then
|
||||
order = 2 -- thirdparty includes
|
||||
else
|
||||
order = 3 -- standard includes
|
||||
end
|
||||
|
||||
table.insert(includeList, {
|
||||
order = order,
|
||||
path = inclusions[i].path,
|
||||
content = lines[inclusions[i].line]
|
||||
})
|
||||
end
|
||||
|
||||
local function compareFunc(a, b)
|
||||
if a.order == b.order then
|
||||
local moduleA = a.path:match("^Nazara/(.-)/")
|
||||
local moduleB = b.path:match("^Nazara/(.-)/")
|
||||
if moduleA ~= moduleB then
|
||||
return moduleA < moduleB
|
||||
end
|
||||
|
||||
local _, folderCountA = a.path:gsub("/", "")
|
||||
local _, folderCountB = b.path:gsub("/", "")
|
||||
if folderCountA == folderCountB then
|
||||
return a.path < b.path
|
||||
else
|
||||
return folderCountA < folderCountB
|
||||
end
|
||||
else
|
||||
return a.order < b.order
|
||||
end
|
||||
end
|
||||
|
||||
local isOrdered = true
|
||||
for i = 2, #includeList do
|
||||
if includeList[i - 1].path == includeList[i].path then
|
||||
-- duplicate found
|
||||
print(filePath .. ": include list has duplicates")
|
||||
isOrdered = false
|
||||
break
|
||||
end
|
||||
|
||||
if not compareFunc(includeList[i - 1], includeList[i]) then
|
||||
print(filePath .. ": include list is not ordered")
|
||||
isOrdered = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not isOrdered then
|
||||
table.sort(includeList, compareFunc)
|
||||
|
||||
table.insert(fixes, {
|
||||
File = filePath,
|
||||
Func = function (lines)
|
||||
-- Reorder includes
|
||||
local newInclusions = {}
|
||||
for i = 1, #inclusions do
|
||||
lines[inclusions[i].line] = includeList[i].content
|
||||
table.insert(newInclusions, {
|
||||
content = includeList[i].content,
|
||||
path = includeList[i].path,
|
||||
line = inclusions[i].line
|
||||
})
|
||||
end
|
||||
|
||||
-- Remove duplicates
|
||||
table.sort(newInclusions, function (a, b) return a.line > b.line end)
|
||||
|
||||
for i = 2, #newInclusions do
|
||||
local a = newInclusions[i - 1]
|
||||
local b = newInclusions[i]
|
||||
|
||||
if a.path == b.path then
|
||||
if #a.content > #b.content then -- keep longest line (for comments)
|
||||
table.remove(lines, b.line)
|
||||
else
|
||||
table.remove(lines, a.line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return lines
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return fixes
|
||||
end
|
||||
})
|
||||
|
||||
-- Check copyright date and format
|
||||
table.insert(checks, {
|
||||
Name = "copyright",
|
||||
|
|
|
|||
Loading…
Reference in New Issue