mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-13 04:06:52 +07:00
131 lines
4.3 KiB
Python
Executable File
131 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
#
|
|
#
|
|
#
|
|
|
|
EMPTY_MATCHER = re.compile(r'^\s*$')
|
|
C_COMMENT_MATCHER = re.compile(r'^/\*.*\*/', re.S)
|
|
|
|
IFDEF_MATCHER = re.compile(r'#\s*if')
|
|
ENDDEF_MATCHER = re.compile(r'#\s*endif')
|
|
|
|
USER_INCLUDE_MATCHER = re.compile(r'#\s*include\s*\"(.*)\"')
|
|
SYSTEM_INCLUDE_MATCHER = re.compile(r'#\s*include\s*<(.*)>')
|
|
PRAGMA_ONCE_MATCHER = re.compile(r'#\s*pragma\s+once')
|
|
|
|
#
|
|
#
|
|
#
|
|
|
|
def CollectLicenseComment(headerPath):
|
|
with open(headerPath, "r") as headerStream:
|
|
headerContent = headerStream.read().strip()
|
|
commentMatch = re.match(C_COMMENT_MATCHER, headerContent)
|
|
return commentMatch.group() if commentMatch else ""
|
|
|
|
def CollectSystemIncludes(headerPath, parsedHeaders = set()):
|
|
with open(headerPath, "r") as headerStream:
|
|
headerContent = headerStream.read().strip()
|
|
|
|
if PRAGMA_ONCE_MATCHER.search(headerContent) and headerPath in parsedHeaders:
|
|
return set()
|
|
|
|
ifdefScopeLevel = 0
|
|
headerIncludes = set()
|
|
|
|
parsedHeaders.add(headerPath)
|
|
headerLines = headerContent.split('\n')
|
|
|
|
for headerLine in headerLines:
|
|
if IFDEF_MATCHER.match(headerLine):
|
|
ifdefScopeLevel += 1
|
|
elif ENDDEF_MATCHER.match(headerLine):
|
|
ifdefScopeLevel -= 1
|
|
|
|
includeMatch = USER_INCLUDE_MATCHER.findall(headerLine)
|
|
if includeMatch and ifdefScopeLevel == 0:
|
|
internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0]))
|
|
headerIncludes = headerIncludes.union(CollectSystemIncludes(internalHeaderPath, parsedHeaders))
|
|
|
|
includeMatch = SYSTEM_INCLUDE_MATCHER.findall(headerLine)
|
|
if includeMatch and ifdefScopeLevel == 0:
|
|
headerIncludes.add(includeMatch[0])
|
|
|
|
return headerIncludes
|
|
|
|
def ParseHeader(headerPath, parsedHeaders = set()):
|
|
with open(headerPath, "r") as headerStream:
|
|
headerContent = headerStream.read().strip()
|
|
headerContent = re.sub(C_COMMENT_MATCHER, '', headerContent)
|
|
|
|
if PRAGMA_ONCE_MATCHER.search(headerContent) and headerPath in parsedHeaders:
|
|
return ""
|
|
|
|
parsedHeaders.add(headerPath)
|
|
headerLines = headerContent.split('\n')
|
|
|
|
outputContent = ""
|
|
ifdefScopeLevel = 0
|
|
shouldSkipNextEmptyLines = True
|
|
|
|
for headerLine in headerLines:
|
|
if EMPTY_MATCHER.match(headerLine) and shouldSkipNextEmptyLines:
|
|
continue
|
|
|
|
if PRAGMA_ONCE_MATCHER.match(headerLine):
|
|
shouldSkipNextEmptyLines = True
|
|
continue
|
|
|
|
if IFDEF_MATCHER.match(headerLine):
|
|
ifdefScopeLevel += 1
|
|
elif ENDDEF_MATCHER.match(headerLine):
|
|
ifdefScopeLevel -= 1
|
|
|
|
includeMatch = USER_INCLUDE_MATCHER.findall(headerLine)
|
|
if includeMatch and ifdefScopeLevel == 0:
|
|
internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0]))
|
|
internalHeaderContent = ParseHeader(internalHeaderPath, parsedHeaders)
|
|
|
|
outputContent += internalHeaderContent
|
|
shouldSkipNextEmptyLines = True
|
|
continue
|
|
|
|
includeMatch = SYSTEM_INCLUDE_MATCHER.findall(headerLine)
|
|
if includeMatch and ifdefScopeLevel == 0:
|
|
shouldSkipNextEmptyLines = True
|
|
continue
|
|
|
|
shouldSkipNextEmptyLines = False
|
|
outputContent += "{}\n".format(headerLine)
|
|
|
|
return "{}\n".format(outputContent)
|
|
|
|
#
|
|
#
|
|
#
|
|
|
|
inputHeaderPath = os.path.abspath(sys.argv[1])
|
|
outputHeaderPath = os.path.abspath(sys.argv[2])
|
|
|
|
os.makedirs(os.path.dirname(outputHeaderPath), exist_ok=True)
|
|
|
|
with open(outputHeaderPath, "w") as outputHeaderStream:
|
|
licenseComment = CollectLicenseComment(inputHeaderPath)
|
|
systemIncludes = CollectSystemIncludes(inputHeaderPath)
|
|
|
|
outputHeaderStream.write("{}\n".format(licenseComment))
|
|
outputHeaderStream.write("\n")
|
|
|
|
for systemInclude in sorted(systemIncludes):
|
|
outputHeaderStream.write("#include <{}>\n".format(systemInclude))
|
|
outputHeaderStream.write("\n")
|
|
|
|
outputHeaderStream.write(ParseHeader(inputHeaderPath).strip())
|
|
outputHeaderStream.write("\n")
|