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
|
#ifndef NAZARA_OPENGLRENDERER_WRAPPER_COREFUNCTIONS_HPP
|
||||||
#define NAZARA_OPENGLRENDERER_WRAPPER_COREFUNCTIONS_HPP
|
#define NAZARA_OPENGLRENDERER_WRAPPER_COREFUNCTIONS_HPP
|
||||||
|
|
||||||
|
// no include reordering
|
||||||
|
|
||||||
#define GL_GLES_PROTOTYPES 0
|
#define GL_GLES_PROTOTYPES 0
|
||||||
#include <GLES3/gl32.h>
|
#include <GLES3/gl32.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
||||||
|
|
||||||
|
// no include reordering
|
||||||
|
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <GL/wgl.h>
|
#include <GL/wgl.h>
|
||||||
#include <GL/wglext.h>
|
#include <GL/wglext.h>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
#undef WIN32_LEAN_AND_MEAN //< Redefined by wgl.h header (ty Khronos)
|
||||||
|
|
||||||
|
// no include reordering
|
||||||
|
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <GL/wgl.h>
|
#include <GL/wgl.h>
|
||||||
#include <GL/wglext.h>
|
#include <GL/wglext.h>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,42 @@ local function CompareLines(referenceLines, lines, firstLine, lineCount)
|
||||||
return true
|
return true
|
||||||
end
|
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 ()
|
on_run(function ()
|
||||||
import("core.base.option")
|
import("core.base.option")
|
||||||
|
|
||||||
|
|
@ -281,10 +317,7 @@ on_run(function ()
|
||||||
for _, filePath in pairs(files) do
|
for _, filePath in pairs(files) do
|
||||||
local lines = GetFile(filePath)
|
local lines = GetFile(filePath)
|
||||||
|
|
||||||
local headerPath = filePath:gsub("[\\/]", "/")
|
local headerPath = ComputeHeaderFile(filePath)
|
||||||
headerPath = headerPath:sub(headerPath:find("Nazara/"), -1)
|
|
||||||
headerPath = headerPath:sub(1, headerPath:find("%..+$") - 1) .. ".hpp"
|
|
||||||
|
|
||||||
if os.isfile("include/" .. headerPath) or os.isfile("src/" .. headerPath) then
|
if os.isfile("include/" .. headerPath) or os.isfile("src/" .. headerPath) then
|
||||||
local inclusions = {}
|
local inclusions = {}
|
||||||
|
|
||||||
|
|
@ -296,7 +329,7 @@ on_run(function ()
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
local includeMode, includePath = lines[i]:match("^%s*#%s*include%s*([<\"])(.+)[>\"]")
|
local includeMode, includePath = lines[i]:match("^#include%s*([<\"])(.+)[>\"]")
|
||||||
if includeMode then
|
if includeMode then
|
||||||
table.insert(inclusions, {
|
table.insert(inclusions, {
|
||||||
line = i,
|
line = i,
|
||||||
|
|
@ -307,36 +340,24 @@ on_run(function ()
|
||||||
end
|
end
|
||||||
|
|
||||||
if #inclusions > 0 then
|
if #inclusions > 0 then
|
||||||
|
local increment = 0
|
||||||
|
|
||||||
|
-- Add corresponding header
|
||||||
local headerInclude
|
local headerInclude
|
||||||
for i = 1, #inclusions do
|
for i = 1, #inclusions do
|
||||||
if inclusions[i].path == headerPath then
|
if inclusions[i].path == headerPath then
|
||||||
headerInclude = i
|
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
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check debug headers
|
||||||
local debugIncludeModule = moduleName ~= "Math" and moduleName or "Core"
|
local debugIncludeModule = moduleName ~= "Math" and moduleName or "Core"
|
||||||
|
|
||||||
local debugInclude
|
local debugInclude
|
||||||
local debugIncludeOff
|
local debugIncludeOff
|
||||||
for i = 1, #inclusions do
|
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 module then
|
||||||
if off == "Off" then
|
if off == "Off" then
|
||||||
debugIncludeOff = i
|
debugIncludeOff = i
|
||||||
|
|
@ -361,8 +382,7 @@ on_run(function ()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local increment = 0
|
-- Add header inclusion if it's missing
|
||||||
|
|
||||||
if not headerInclude then
|
if not headerInclude then
|
||||||
print(filePath .. " is missing corresponding header inclusion")
|
print(filePath .. " is missing corresponding header inclusion")
|
||||||
|
|
||||||
|
|
@ -392,7 +412,7 @@ on_run(function ()
|
||||||
end
|
end
|
||||||
|
|
||||||
if path.extension(filePath) == ".inl" then
|
if path.extension(filePath) == ".inl" then
|
||||||
if not debugInclude then
|
if not debugIncludeOff then
|
||||||
print(filePath .. ": has missing DebugOff include")
|
print(filePath .. ": has missing DebugOff include")
|
||||||
table.insert(fixes, {
|
table.insert(fixes, {
|
||||||
File = filePath,
|
File = filePath,
|
||||||
|
|
@ -413,6 +433,153 @@ on_run(function ()
|
||||||
end
|
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
|
-- Check copyright date and format
|
||||||
table.insert(checks, {
|
table.insert(checks, {
|
||||||
Name = "copyright",
|
Name = "copyright",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue