mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
We don't need anything in this release, but I think it doesn't hurt to just stay up to date. The new version has a new include file, stl.h. To keep things clean and separated, move the imported files to a new sub-directory. This requires a small change in gdb/check-include-guards.py, to be able to ignore the whole new directory. Change-Id: Ic8c5d0dd5ea8b6691c99975d6ca78f637175ef42 Approved-By: Tom Tromey <tom@tromey.com>
139 lines
4.4 KiB
Python
Executable File
139 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (C) 2024-2025 Free Software Foundation, Inc.
|
|
#
|
|
# This file is part of GDB.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# This is intended to be run from pre-commit. You can also run it by
|
|
# hand by passing repository-relative filenames to it, like:
|
|
# ./gdb/check-include-guards.py [--update] gdb/*.h
|
|
# When --update is used, rewrite the files in place as needed.
|
|
|
|
|
|
import fnmatch
|
|
import re
|
|
import sys
|
|
from typing import List
|
|
|
|
DEF = re.compile("^#ifndef ([A-Za-z0-9_]+)\n")
|
|
OLDDEF = re.compile("^#if !defined *\\(([A-Za-z0-9_]+)\\)\n")
|
|
|
|
# Some headers -- in particular, ones that aren't maintained by gdb --
|
|
# should be excluded from the checks.
|
|
#
|
|
# This is interpreted as a list of patterns as interpreted by fnmatch.
|
|
EXCLUDED = ("gdbsupport/unordered_dense/*",)
|
|
|
|
|
|
# See if
|
|
write_files = False
|
|
args = sys.argv[1:]
|
|
if len(args) > 0 and args[0] == "--update":
|
|
write_files = True
|
|
args = args[1:]
|
|
|
|
|
|
def failure(filename: str, ndx: int, text: str):
|
|
print(filename + ":" + str(ndx + 1) + ": " + text, file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def skip_comments_and_blanks(ndx: int, contents: List[str]):
|
|
while ndx < len(contents) and contents[ndx].startswith("/*"):
|
|
while ndx < len(contents):
|
|
ndx += 1
|
|
if contents[ndx - 1].endswith("*/\n"):
|
|
break
|
|
# Skip blank lines.
|
|
while ndx < len(contents):
|
|
if contents[ndx].strip() != "":
|
|
break
|
|
ndx += 1
|
|
return ndx
|
|
|
|
|
|
def write_header(filename: str, contents: List[str]):
|
|
with open(filename, "w") as f:
|
|
f.writelines(contents)
|
|
|
|
|
|
def check_header(filename: str):
|
|
for pat in EXCLUDED:
|
|
if fnmatch.fnmatch(filename, pat):
|
|
return
|
|
|
|
# Turn x/y-z.h into X_Y_Z_H.
|
|
assert filename.endswith(".h")
|
|
expected = filename.replace("-", "_")
|
|
expected = expected.replace(".", "_")
|
|
expected = expected.replace("/", "_")
|
|
expected = expected.upper()
|
|
with open(filename) as f:
|
|
contents = list(f)
|
|
if len(contents) == 0:
|
|
# Empty file -- pathological but we can just ignore rather
|
|
# than crashing.
|
|
return
|
|
if "THIS FILE IS GENERATED" in contents[0]:
|
|
# Ignore.
|
|
return
|
|
if not contents[0].startswith("/*"):
|
|
failure(filename, 0, "header should start with comment")
|
|
i = skip_comments_and_blanks(0, contents)
|
|
if i == len(contents):
|
|
failure(filename, i, "unterminated intro comment or missing body")
|
|
m = DEF.match(contents[i])
|
|
force_rewrite = False
|
|
if not m:
|
|
m = OLDDEF.match(contents[i])
|
|
if not m:
|
|
failure(filename, i, "no header guard")
|
|
force_rewrite = True
|
|
symbol = m.group(1)
|
|
# Either None or a tuple like (LINE, TEXT) that describes a needed
|
|
# update.
|
|
updated = None
|
|
if symbol != expected:
|
|
force_rewrite = True
|
|
if force_rewrite:
|
|
contents[i] = "#ifndef " + expected + "\n"
|
|
updated = (i, "wrong symbol in ifndef")
|
|
i += 1
|
|
if i == len(contents):
|
|
failure(filename, i, "premature EOF")
|
|
if not contents[i].startswith("#define "):
|
|
failure(filename, i, "no define of header guard")
|
|
if contents[i] != "#define " + expected + "\n":
|
|
contents[i] = "#define " + expected + "\n"
|
|
if updated is None:
|
|
updated = (i, "wrong symbol in define")
|
|
i = len(contents) - 1
|
|
if not contents[i].startswith("#endif"):
|
|
failure(filename, i, "no trailing endif")
|
|
if contents[i] != "#endif /* " + expected + " */\n":
|
|
contents[i] = "#endif /* " + expected + " */\n"
|
|
if updated is None:
|
|
updated = (i, "wrong endif line")
|
|
if updated is not None:
|
|
if write_files:
|
|
write_header(filename, contents)
|
|
else:
|
|
failure(filename, *updated)
|
|
|
|
|
|
for filename in args:
|
|
check_header(filename)
|