Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
header_includes_audit Namespace Reference

Functions

 strip_comments (text)
 
 read (path)
 
 supplied_by (path)
 
 resolve (inc, from_dir)
 
 closure (header, seen=None)
 
 audit (header)
 
 main ()
 

Variables

 REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
 SRC = os.path.join(REPO, "src")
 
 COMMENT_BLOCK = re.compile(r"/\*.*?\*/", re.S)
 
 COMMENT_LINE = re.compile(r"//[^\n]*")
 
 INCLUDE_LINE = re.compile(r'^\s*#\s*include\s+"([^"]+)"', re.M)
 
list DECLARE
 
 ENUM_MEMBER = re.compile(r"^\s*([A-Z][A-Z0-9_]{2,})\s*(?:=|,|$)")
 
dict NOISE
 

Detailed Description

Check that a header includes only what its own declarations need.

A header that includes more than its signatures require becomes a supply line its consumers
never asked for and cannot see: they compile because something upstream happened to pull in
what they use, and the day anyone tidies that include away the breakage surfaces somewhere
else entirely, in a file that was never touched.

Two findings, opposite directions:

  UNUSED  - the header includes something none of its own declarations reference. Its
            consumers may nonetheless be relying on it; that is the problem, not a reason to
            keep it. Move the include to the .c, and give each consumer what it actually uses.
  MISSING - the header names a type it does not include a definition for, and is getting it
            transitively. It works today and breaks when the chain shortens.

Reported symbol by symbol so each finding can be checked rather than trusted. Matching is
textual -- it cannot see through macros, and it reads one preprocessor branch like every other
tool here -- so treat MISSING as "verify this", and check UNUSED against a build before acting
on it. A platform-only use (`#ifdef _WIN32`) will read as UNUSED on Linux; removing such an
include is how this tree broke its Windows build once already.

Usage:
    tools/header_includes_audit.py src/gui/application.h [more headers...]
    tools/header_includes_audit.py --all          # every header under src/

Function Documentation

◆ audit()

header_includes_audit.audit (   header)

Definition at line 105 of file header_includes_audit.py.

References closure(), read(), resolve(), strip_comments(), and supplied_by().

Referenced by main().

◆ closure()

header_includes_audit.closure (   header,
  seen = None 
)

Definition at line 94 of file header_includes_audit.py.

References closure(), read(), and resolve().

Referenced by audit(), and closure().

◆ main()

header_includes_audit.main ( void  )

Definition at line 144 of file header_includes_audit.py.

References audit(), and main().

Referenced by main().

◆ read()

header_includes_audit.read (   path)

Definition at line 64 of file header_includes_audit.py.

Referenced by audit(), closure(), and supplied_by().

◆ resolve()

header_includes_audit.resolve (   inc,
  from_dir 
)

Definition at line 86 of file header_includes_audit.py.

Referenced by audit(), and closure().

◆ strip_comments()

header_includes_audit.strip_comments (   text)

Definition at line 60 of file header_includes_audit.py.

Referenced by audit(), and supplied_by().

◆ supplied_by()

header_includes_audit.supplied_by (   path)
Identifiers `path` defines.

Definition at line 72 of file header_includes_audit.py.

References read(), and strip_comments().

Referenced by audit().

Variable Documentation

◆ COMMENT_BLOCK

header_includes_audit.COMMENT_BLOCK = re.compile(r"/\*.*?\*/", re.S)

Definition at line 35 of file header_includes_audit.py.

◆ COMMENT_LINE

header_includes_audit.COMMENT_LINE = re.compile(r"//[^\n]*")

Definition at line 36 of file header_includes_audit.py.

◆ DECLARE

list header_includes_audit.DECLARE
Initial value:
1= [
2 re.compile(r"^\s*#\s*define\s+([A-Za-z_]\w*)"),
3 re.compile(r"^\s*}[^;]*?\b([A-Za-z_]\w*)\s*;"), # `} name;` and `} ATTR(..) name;`
4 re.compile(r"^\s*typedef\s+.*?\b([A-Za-z_]\w*)\s*;"),
5 re.compile(r"^\s*typedef\s+.*\‍(\s*\*\s*([A-Za-z_]\w*)\s*\‍)\s*\‍("), # function-pointer typedef
6 re.compile(r"^\s*(?:struct|union|enum)\s+([A-Za-z_]\w*)\s*[;{]"),
7 re.compile(r"^\s*(?:[A-Za-z_][\w \t*]*?[ \t*])([A-Za-z_]\w*)\s*\‍("),
8]

Definition at line 39 of file header_includes_audit.py.

◆ ENUM_MEMBER

header_includes_audit.ENUM_MEMBER = re.compile(r"^\s*([A-Z][A-Z0-9_]{2,})\s*(?:=|,|$)")

Definition at line 47 of file header_includes_audit.py.

◆ INCLUDE_LINE

header_includes_audit.INCLUDE_LINE = re.compile(r'^\s*#\s*include\s+"([^"]+)"', re.M)

Definition at line 37 of file header_includes_audit.py.

◆ NOISE

dict header_includes_audit.NOISE
Initial value:
1= {
2 "if", "for", "while", "switch", "return", "sizeof", "defined", "else", "do",
3 "static", "inline", "const", "struct", "union", "enum", "typedef", "extern",
4 "void", "int", "char", "float", "double", "long", "short", "unsigned", "signed",
5 "gboolean", "gint", "guint", "gchar", "gpointer", "gdouble", "gfloat", "gsize",
6 "TRUE", "FALSE", "NULL",
7}

Definition at line 51 of file header_includes_audit.py.

◆ REPO

header_includes_audit.REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Definition at line 32 of file header_includes_audit.py.

◆ SRC

header_includes_audit.SRC = os.path.join(REPO, "src")

Definition at line 33 of file header_includes_audit.py.