mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-23 21:43:51 +01:00
With the migration to #pragma once in the core header in #21405, the workaround for the header name check when using #include_next is not necessary anymore and can be dropped.
114 lines
3.5 KiB
Python
Executable File
114 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import sys
|
|
import difflib
|
|
from io import BytesIO, TextIOWrapper
|
|
|
|
_in = "/-."
|
|
_out = "___"
|
|
|
|
transtab = str.maketrans(_in, _out)
|
|
|
|
|
|
def path_to_guardname(filepath):
|
|
res = filepath.upper().translate(transtab)
|
|
if res.startswith("_"):
|
|
res = "PRIV" + res
|
|
return res
|
|
|
|
|
|
def get_guard_name(filepath):
|
|
parts = filepath.split(os.sep)
|
|
start = 0
|
|
found = False
|
|
for i, part in enumerate(parts):
|
|
if part == "include":
|
|
found = True
|
|
start = i + 1
|
|
break
|
|
|
|
if not found:
|
|
start = len(parts) - 1
|
|
|
|
return path_to_guardname(os.path.join(*parts[start:]))
|
|
|
|
|
|
def fix_headerguard(filename):
|
|
supposed = get_guard_name(filename)
|
|
with open(filename, "r", encoding='utf-8', errors='ignore') as f:
|
|
inlines = f.readlines()
|
|
|
|
tmp = TextIOWrapper(BytesIO(), encoding="utf-8", errors="ignore")
|
|
tmp.seek(0)
|
|
|
|
guard_found = 0
|
|
pragma_once_found = 0
|
|
guard_name = ""
|
|
ifstack = 0
|
|
for line in inlines:
|
|
if line.startswith("#pragma once"):
|
|
pragma_once_found += 1
|
|
elif line.lstrip().startswith("#pragma once"):
|
|
# check for lines that have leading whitespaces and add a correction
|
|
pragma_once_found += 1
|
|
line = "#pragma once\n"
|
|
if guard_found == 0:
|
|
if pragma_once_found == 0 and line.startswith("#ifndef"):
|
|
guard_found += 1
|
|
guard_name = line[8:].rstrip()
|
|
line = "#ifndef %s\n" % (supposed)
|
|
elif pragma_once_found != 0 and line.startswith("#ifndef %s" % supposed):
|
|
# check if there is pragma once *and* headerguards, but avoid false
|
|
# positives by narrowing in on the to-be-expected guard
|
|
guard_found += 1
|
|
guard_name = line[8:].rstrip()
|
|
line = ""
|
|
elif guard_found == 1:
|
|
if line.startswith("#define") and line[8:].rstrip() == guard_name:
|
|
line = "#define %s\n" % (supposed)
|
|
guard_found += 1
|
|
else:
|
|
break
|
|
elif guard_found == 2:
|
|
if line.startswith("#if"):
|
|
ifstack += 1
|
|
elif line.startswith("#endif"):
|
|
if ifstack > 0:
|
|
ifstack -= 1
|
|
else:
|
|
guard_found += 1
|
|
line = "#endif /* %s */\n" % supposed
|
|
|
|
tmp.write(line)
|
|
|
|
tmp.seek(0)
|
|
if (pragma_once_found == 0 and guard_found == 3) or \
|
|
(pragma_once_found == 1 and guard_found == 0):
|
|
# Valid cases:
|
|
# - no #pragma once, classic headerguards (#ifndef, #define, #endif)
|
|
# - one #pragma once, no classic headerguards
|
|
for line in difflib.unified_diff(inlines, tmp.readlines(),
|
|
"%s" % filename, "%s" % filename):
|
|
sys.stdout.write(line)
|
|
elif (pragma_once_found == 0 and guard_found == 0):
|
|
print("%s: no header guards found" % filename, file=sys.stderr)
|
|
return False
|
|
elif (pragma_once_found == 1 and guard_found != 0):
|
|
print("%s: #pragma once and classic header guards used in the same file" %
|
|
filename, file=sys.stderr)
|
|
return False
|
|
else:
|
|
print("%s: broken header guard" % filename, file=sys.stderr)
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
error = False
|
|
for filename in sys.argv[1:]:
|
|
if fix_headerguard(filename) is False:
|
|
error = True
|
|
|
|
if error:
|
|
sys.exit(1)
|