checkpatch: Add warnings for unexpected struct names
authorSimon Glass <sjg@chromium.org>
Thu, 3 Dec 2020 23:55:24 +0000 (16:55 -0700)
committerSimon Glass <sjg@chromium.org>
Sun, 13 Dec 2020 23:51:09 +0000 (16:51 -0700)
As a way of keeping the driver declarations more consistent, add a warning
if the struct used does not end with _priv or _plat.

Signed-off-by: Simon Glass <sjg@chromium.org>
scripts/checkpatch.pl
tools/patman/test_checkpatch.py

index 4ed7e12..01ab570 100755 (executable)
@@ -2320,6 +2320,23 @@ sub get_raw_comment {
        return $comment;
 }
 
+# Args:
+#   line: Patch line to check
+#   auto: Auto variable name, e.g. "per_child_auto"
+#   suffix: Suffix to expect on member, e.g. "_priv"
+#   warning: Warning name, e.g. "PRIV_AUTO"
+sub u_boot_struct_name {
+       my ($line, $auto, $suffix, $warning) = @_;
+
+       # Use _priv as a suffix for the device-private data struct
+       if ($line =~ /^\+\s*\.${auto}\s*=\s*sizeof\(struct\((\w+)\).*/) {
+               my $struct_name = $1;
+               if ($struct_name !~ /^\w+${suffix}/) {
+                       WARN($warning, "struct \'$struct_name\' should have a ${suffix} suffix");
+               }
+       }
+}
+
 # Checks specific to U-Boot
 sub u_boot_line {
        my ($realfile, $line, $rawline, $herecurr) = @_;
@@ -2371,6 +2388,27 @@ sub u_boot_line {
                ERROR("CONFIG_IS_ENABLED_CONFIG",
                      "CONFIG_IS_ENABLED() takes values without the CONFIG_ prefix\n" . $herecurr);
        }
+
+       # Use _priv as a suffix for the device-private data struct
+       if ($line =~ /^\+\s*\.priv_auto\s*=\s*sizeof\(struct\((\w+)\).*/) {
+               my $struct_name = $1;
+               if ($struct_name !~ /^\w+_priv/) {
+                       WARN("PRIV_AUTO", "struct \'$struct_name\' should have a _priv suffix");
+               }
+       }
+
+       # Check struct names for the 'auto' members of struct driver
+       u_boot_struct_name($line, "priv_auto", "_priv", "PRIV_AUTO");
+       u_boot_struct_name($line, "plat_auto", "_plat", "PLAT_AUTO");
+       u_boot_struct_name($line, "per_child_auto", "_priv", "CHILD_PRIV_AUTO");
+       u_boot_struct_name($line, "per_child_plat_auto", "_plat",
+               "CHILD_PLAT_AUTO");
+
+       # Now the ones for struct uclass, skipping those in common with above
+       u_boot_struct_name($line, "per_device_auto", "_priv",
+               "DEVICE_PRIV_AUTO");
+       u_boot_struct_name($line, "per_device_plat_auto", "_plat",
+               "DEVICE_PLAT_AUTO");
 }
 
 sub process {
index 1f7c38c..a4fec1d 100644 (file)
@@ -411,6 +411,34 @@ index 0000000..2234c87
         pm.add_line('common/main.c', 'if (CONFIG_IS_ENABLED(CONFIG_CLK))')
         self.checkSingleMessage(pm, 'CONFIG_IS_ENABLED_CONFIG', 'error')
 
+    def check_struct(self, auto, suffix, warning):
+        """Check one of the warnings for struct naming
+
+        Args:
+            auto: Auto variable name, e.g. 'per_child_auto'
+            suffix: Suffix to expect on member, e.g. '_priv'
+            warning: Warning name, e.g. 'PRIV_AUTO'
+        """
+        pm = PatchMaker()
+        pm.add_line('common/main.c', '.%s = sizeof(struct(fred)),' % auto)
+        pm.add_line('common/main.c', '.%s = sizeof(struct(mary%s)),' %
+                    (auto, suffix))
+        self.checkSingleMessage(
+            pm, warning, "struct 'fred' should have a %s suffix" % suffix)
+
+    def testDmDriverAuto(self):
+        """Check for the correct suffix on 'struct driver' auto members"""
+        self.check_struct('priv_auto', '_priv', 'PRIV_AUTO')
+        self.check_struct('plat_auto', '_plat', 'PLAT_AUTO')
+        self.check_struct('per_child_auto', '_priv', 'CHILD_PRIV_AUTO')
+        self.check_struct('per_child_plat_auto', '_plat', 'CHILD_PLAT_AUTO')
+
+    def testDmUclassAuto(self):
+        """Check for the correct suffix on 'struct uclass' auto members"""
+        # Some of these are omitted since they match those from struct driver
+        self.check_struct('per_device_auto', '_priv', 'DEVICE_PRIV_AUTO')
+        self.check_struct('per_device_plat_auto', '_plat', 'DEVICE_PLAT_AUTO')
+
 
 if __name__ == "__main__":
     unittest.main()