Add a precommit script to check for missing GObject finalizers

This commit is contained in:
Richard Hughes 2022-07-11 09:04:25 +01:00
parent 3b71918346
commit ab9f27e6db
3 changed files with 69 additions and 0 deletions

View File

@ -41,6 +41,10 @@ repos:
name: check for null / false return mistmatch
language: script
entry: ./contrib/ci/check-null-false-returns.py
- id: check-finalizers
name: check for missing GObject parent finalize
language: script
entry: ./contrib/ci/check-finalizers.py
- id: check-headers
name: check for superfluous includes
language: script

63
contrib/ci/check-finalizers.py Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/python3
# pylint: disable=invalid-name,missing-docstring,consider-using-f-string
# pylint: disable=too-few-public-methods
#
# Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
#
# SPDX-License-Identifier: LGPL-2.1+
import glob
import sys
from typing import List
class ReturnValidator:
def __init__(self):
self.warnings: List[str] = []
def parse(self, fn: str) -> None:
with open(fn, "rb") as f:
infunc = False
has_parent_finalize = False
for line in f.read().decode().split("\n"):
# found the function, but ignore the prototype
if line.find("_finalize(") != -1:
if line.endswith(";"):
continue
infunc = True
continue
# got it
if line.find("->finalize(") != -1:
has_parent_finalize = True
continue
# finalize is done
if infunc and line.startswith("}"):
if not has_parent_finalize:
self.warnings.append(
"{} did not have parent ->finalize()".format(fn)
)
break
def test_files():
# test all C source files
validator = ReturnValidator()
for fn in glob.glob("**/*.c", recursive=True):
if fn.startswith("dist/") or fn.startswith("subprojects/"):
continue
validator.parse(fn)
for warning in validator.warnings:
print(warning)
return 1 if validator.warnings else 0
if __name__ == "__main__":
# all done!
sys.exit(test_files())

View File

@ -508,6 +508,8 @@ fu_corsair_device_finalize(GObject *object)
g_free(self->subdevice_id);
g_object_unref(self->bp);
G_OBJECT_CLASS(fu_corsair_device_parent_class)->finalize(object);
}
static void