mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-03 15:10:52 +00:00
Make the null-false-returns script also process return type
And fix up the rather disapointing single place we got it wrong...
This commit is contained in:
parent
7619665d74
commit
eb4dcefbc6
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/python3
|
||||
# pylint: disable=invalid-name,missing-docstring,too-many-branches,too-many-statements
|
||||
# pylint: disable=invalid-name,missing-docstring,too-many-branches
|
||||
# pylint: disable=too-many-statements,too-many-return-statements,too-few-public-methods
|
||||
#
|
||||
# Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
#
|
||||
@ -7,158 +8,228 @@
|
||||
|
||||
import glob
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def parse_rvif(line):
|
||||
def _tokenize(line: str) -> List[str]:
|
||||
|
||||
# remove whitespace
|
||||
line = line.strip()
|
||||
line = line.replace("\t", "")
|
||||
line = line.replace(" ", "")
|
||||
line = line.replace(";", "")
|
||||
|
||||
# find value
|
||||
line = line.replace(" ", "|")
|
||||
line = line.replace(",", "|")
|
||||
line = line.replace(")", "|")
|
||||
return line.rsplit("|", maxsplit=2)[1]
|
||||
line = line.replace("(", "|")
|
||||
|
||||
# return empty tokens
|
||||
tokens = []
|
||||
for token in line.rsplit("|"):
|
||||
if token:
|
||||
tokens.append(token)
|
||||
return tokens
|
||||
|
||||
|
||||
def test_rvif(fn, line_num, valid_values, line):
|
||||
class ReturnValidator:
|
||||
def __init__(self):
|
||||
self.warnings: List[str] = []
|
||||
|
||||
# parse "g_return_val_if_fail (SOMETHING (foo), NULL)"
|
||||
value = parse_rvif(line)
|
||||
# internal state
|
||||
self._fn = None
|
||||
self._line_num = None
|
||||
self._value = None
|
||||
self._nret = None
|
||||
self._rvif = None
|
||||
self._line = None
|
||||
|
||||
# enumerated enum, so ignore
|
||||
if value.find("_") != -1:
|
||||
return True
|
||||
@property
|
||||
def _tokens(self) -> List[str]:
|
||||
return _tokenize(self._line)
|
||||
|
||||
# convert alternate forms back to normal
|
||||
if value in ["0x0", "0x00", "0x0000"]:
|
||||
value = "0"
|
||||
if value in ["0xffffffff"]:
|
||||
value = "G_MAXUINT32"
|
||||
if value in ["0xffff"]:
|
||||
value = "G_MAXUINT16"
|
||||
if value in ["0xff"]:
|
||||
value = "G_MAXUINT8"
|
||||
if value in ["G_SOURCE_REMOVE"]:
|
||||
value = "FALSE"
|
||||
if value in ["G_SOURCE_CONTINUE"]:
|
||||
value = "TRUE"
|
||||
if value not in valid_values:
|
||||
print(
|
||||
"{} line {} got {}, expected {}".format(
|
||||
fn, line_num, value, ", ".join(valid_values)
|
||||
@property
|
||||
def _value_relaxed(self) -> str:
|
||||
if self._value in ["0x0", "0x00", "0x0000"]:
|
||||
return "0"
|
||||
if self._value in ["0xffffffff"]:
|
||||
return "G_MAXUINT32"
|
||||
if self._value in ["0xffff"]:
|
||||
return "G_MAXUINT16"
|
||||
if self._value in ["0xff"]:
|
||||
return "G_MAXUINT8"
|
||||
if self._value in ["G_SOURCE_REMOVE"]:
|
||||
return "FALSE"
|
||||
if self._value in ["G_SOURCE_CONTINUE"]:
|
||||
return "TRUE"
|
||||
return self._value
|
||||
|
||||
def _test_rvif(self) -> None:
|
||||
|
||||
# parse "g_return_val_if_fail (SOMETHING (foo), NULL);"
|
||||
self._value = self._tokens[-1]
|
||||
|
||||
# enumerated enum, so ignore
|
||||
if self._value.find("_") != -1:
|
||||
return
|
||||
|
||||
# is invalid
|
||||
if self._rvif and self._value_relaxed not in self._rvif:
|
||||
self.warnings.append(
|
||||
"{} line {} got {}, expected {}".format(
|
||||
self._fn, self._line_num, self._value, ", ".join(self._rvif)
|
||||
)
|
||||
)
|
||||
)
|
||||
return False
|
||||
|
||||
# success
|
||||
return True
|
||||
def _test_return(self) -> None:
|
||||
|
||||
# parse "return 0x0;"
|
||||
self._value = self._tokens[-1]
|
||||
|
||||
def test_file(fn):
|
||||
allokay = True
|
||||
with open(fn) as f:
|
||||
valid_values = None
|
||||
line_num = 0
|
||||
for line in f.readlines():
|
||||
line_num += 1
|
||||
line = line.rstrip()
|
||||
if not line:
|
||||
continue
|
||||
idx = line.find("g_return_val_if_fail")
|
||||
if idx != -1 and valid_values:
|
||||
if not test_rvif(fn, line_num, valid_values, line):
|
||||
allokay = False
|
||||
continue
|
||||
# is invalid
|
||||
if self._nret and self._value_relaxed in self._nret:
|
||||
self.warnings.append(
|
||||
"{} line {} got {}, which is not valid".format(
|
||||
self._fn, self._line_num, self._value
|
||||
)
|
||||
)
|
||||
|
||||
# not a function header
|
||||
if line[0] in ["#", " ", "\t", "{", "}", "/"]:
|
||||
continue
|
||||
def parse(self, fn: str) -> None:
|
||||
|
||||
# label
|
||||
if line.endswith(":"):
|
||||
continue
|
||||
self._fn = fn
|
||||
with open(fn) as f:
|
||||
self._rvif = None
|
||||
self._nret = None
|
||||
self._line_num = 0
|
||||
for line in f.readlines():
|
||||
self._line_num += 1
|
||||
line = line.rstrip()
|
||||
if not line:
|
||||
continue
|
||||
if line.endswith("\\"):
|
||||
continue
|
||||
if line.endswith("&&"):
|
||||
continue
|
||||
self._line = line
|
||||
idx = line.find("g_return_val_if_fail")
|
||||
if idx != -1:
|
||||
self._test_rvif()
|
||||
continue
|
||||
idx = line.find("return")
|
||||
if idx != -1:
|
||||
# continue
|
||||
if len(self._tokens) == 2:
|
||||
self._test_return()
|
||||
continue
|
||||
|
||||
# remove static prefix
|
||||
if line.startswith("static"):
|
||||
line = line[7:]
|
||||
# not a function header
|
||||
if line[0] in ["#", " ", "\t", "{", "}", "/"]:
|
||||
continue
|
||||
|
||||
# a pointer
|
||||
if line.endswith("*"):
|
||||
valid_values = ["NULL"]
|
||||
continue
|
||||
# label
|
||||
if line.endswith(":"):
|
||||
continue
|
||||
|
||||
# not a leading line
|
||||
if line.find(" ") != -1:
|
||||
continue
|
||||
# remove prefixes
|
||||
if line.startswith("static"):
|
||||
line = line[7:]
|
||||
if line.startswith("inline"):
|
||||
line = line[7:]
|
||||
|
||||
# a type we know
|
||||
if line in ["void"]:
|
||||
valid_values = []
|
||||
continue
|
||||
if line in ["gpointer"]:
|
||||
valid_values = ["NULL"]
|
||||
continue
|
||||
if line in ["gboolean"]:
|
||||
valid_values = ["TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["guint32"]:
|
||||
valid_values = ["0", "G_MAXUINT32"]
|
||||
continue
|
||||
if line in ["GQuark", "GType"]:
|
||||
valid_values = ["0"]
|
||||
continue
|
||||
if line in ["guint64"]:
|
||||
valid_values = ["0", "G_MAXUINT64"]
|
||||
continue
|
||||
if line in ["guint16"]:
|
||||
valid_values = ["0", "G_MAXUINT16"]
|
||||
continue
|
||||
if line in ["guint8"]:
|
||||
valid_values = ["0", "G_MAXUINT8"]
|
||||
continue
|
||||
if line in ["gint64"]:
|
||||
valid_values = ["0", "-1", "G_MAXINT64"]
|
||||
continue
|
||||
if line in ["gint32"]:
|
||||
valid_values = ["0", "-1", "G_MAXINT32"]
|
||||
continue
|
||||
if line in ["gint16"]:
|
||||
valid_values = ["0", "-1", "G_MAXINT16"]
|
||||
continue
|
||||
if line in ["gint8"]:
|
||||
valid_values = ["0", "-1", "G_MAXINT8"]
|
||||
continue
|
||||
if line in ["gint", "int"]:
|
||||
valid_values = ["0", "-1", "G_MAXINT"]
|
||||
continue
|
||||
if line in ["guint"]:
|
||||
valid_values = ["0", "G_MAXUINT"]
|
||||
continue
|
||||
if line in ["gulong"]:
|
||||
valid_values = ["0", "G_MAXLONG"]
|
||||
continue
|
||||
if line in ["gsize", "size_t"]:
|
||||
valid_values = ["0", "G_MAXSIZE"]
|
||||
continue
|
||||
if line in ["gssize", "ssize_t"]:
|
||||
valid_values = ["0", "-1", "G_MAXSSIZE"]
|
||||
continue
|
||||
# print('unknown return type {}'.format(line))
|
||||
valid_values = None
|
||||
# a pointer
|
||||
if line.endswith("*"):
|
||||
self._rvif = ["NULL"]
|
||||
self._nret = ["FALSE"]
|
||||
continue
|
||||
|
||||
# global success
|
||||
return allokay
|
||||
# not a leading line
|
||||
if line.find(" ") != -1:
|
||||
continue
|
||||
|
||||
# a type we know
|
||||
if line in ["void"]:
|
||||
self._rvif = []
|
||||
self._nret = []
|
||||
continue
|
||||
if line in ["gpointer"]:
|
||||
self._rvif = ["NULL"]
|
||||
self._nret = ["FALSE"]
|
||||
continue
|
||||
if line in ["gboolean"]:
|
||||
self._rvif = ["TRUE", "FALSE"]
|
||||
self._nret = ["NULL", "0"]
|
||||
continue
|
||||
if line in ["guint32"]:
|
||||
self._rvif = ["0", "G_MAXUINT32"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["GQuark", "GType"]:
|
||||
self._rvif = ["0"]
|
||||
self._nret = ["NULL", "0", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["guint64"]:
|
||||
self._rvif = ["0", "G_MAXUINT64"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["guint16"]:
|
||||
self._rvif = ["0", "G_MAXUINT16"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["guint8"]:
|
||||
self._rvif = ["0", "G_MAXUINT8"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gint64"]:
|
||||
self._rvif = ["0", "-1", "G_MAXINT64"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gint32"]:
|
||||
self._rvif = ["0", "-1", "G_MAXINT32"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gint16"]:
|
||||
self._rvif = ["0", "-1", "G_MAXINT16"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gint8"]:
|
||||
self._rvif = ["0", "-1", "G_MAXINT8"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gint", "int"]:
|
||||
self._rvif = ["0", "-1", "G_MAXINT"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["guint"]:
|
||||
self._rvif = ["0", "G_MAXUINT"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gulong"]:
|
||||
self._rvif = ["0", "G_MAXLONG"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gsize", "size_t"]:
|
||||
self._rvif = ["0", "G_MAXSIZE"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
if line in ["gssize", "ssize_t"]:
|
||||
self._rvif = ["0", "-1", "G_MAXSSIZE"]
|
||||
self._nret = ["NULL", "TRUE", "FALSE"]
|
||||
continue
|
||||
# print('unknown return type {}'.format(line))
|
||||
self._rvif = None
|
||||
self._nret = None
|
||||
|
||||
|
||||
def test_files():
|
||||
|
||||
# test all C source files
|
||||
rc = 0
|
||||
validator = ReturnValidator()
|
||||
for fn in glob.glob("**/*.c", recursive=True):
|
||||
if not test_file(fn):
|
||||
rc = 1
|
||||
return rc
|
||||
validator.parse(fn)
|
||||
for warning in validator.warnings:
|
||||
print(warning)
|
||||
|
||||
return 1 if validator.warnings else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -122,7 +122,7 @@ fu_superio_device_to_string (FuUdevDevice *device, guint idt, GString *str)
|
||||
fu_common_string_append_kx (str, idt, "PM1_IOBAD1", priv->pm1_iobad1);
|
||||
}
|
||||
|
||||
static guint16
|
||||
static gboolean
|
||||
fu_superio_device_check_id (FuSuperioDevice *self, GError **error)
|
||||
{
|
||||
FuSuperioDevicePrivate *priv = GET_PRIVATE (self);
|
||||
|
Loading…
Reference in New Issue
Block a user