From 279cb91bc6dead615f669281cf6459736bc010f2 Mon Sep 17 00:00:00 2001
From: Niels Thykier <niels@thykier.net>
Date: Sun, 4 Sep 2011 11:08:18 +0200
Subject: [PATCH] Added simple variable tracker in checks/rules

---
 checks/rules                                       |   46 ++++++++++++++++++++
 t/tests/rules-variable-targets/debian/debian/rules |    9 ++++
 t/tests/rules-variable-targets/desc                |    5 ++
 3 files changed, 60 insertions(+), 0 deletions(-)
 create mode 100644 t/tests/rules-variable-targets/debian/debian/rules
 create mode 100644 t/tests/rules-variable-targets/desc
 create mode 100644 t/tests/rules-variable-targets/tags

diff --git a/checks/rules b/checks/rules
index dddbd23..076373e 100644
--- a/checks/rules
+++ b/checks/rules
@@ -154,6 +154,7 @@ my %rules_per_target;
 my %debhelper_group;
 my $maybe_skipping;
 my $uses_makefile_pl = 0;
+my %variables;
 while (<RULES>) {
     next if /^\s*\#/;
     if (m/^\s*[s-]?include\s+(\S++)/o){
@@ -201,6 +202,14 @@ while (<RULES>) {
         tag 'debian-rules-makemaker-prefix-is-deprecated', "line $.";
     }
 
+    # General assignment - save the variable
+    if (/^\s*(?:\S+\s+)*?(\S+)\s*([:\?\+])?=\s*(.*+)?$/o) {
+        # This is far too simple from a theoratical PoV, but should do
+        # rather well.
+        my ($var, $atype, $value) = ($1, $2, $3);
+        $variables{$var} = $value;
+    }
+
     # Keep track of whether this portion of debian/rules may be optional
     if (/^ifn?(?:eq|def)\s/) {
         $maybe_skipping++;
@@ -227,10 +236,29 @@ while (<RULES>) {
     # requirement.
     if (/^(?:[^:]+\s)?\.PHONY(?:\s[^:]+)?:(.+)/) {
         my @targets = split (' ', $1);
+        local $_;
         for (@targets) {
+            # Is it $(VAR) ?
+            if (m/^\$[\(\{]([^\)\}]++)[\)\}]$/) {
+                my $name = $1;
+                my $val = $variables{$name};
+                if ($val) {
+                    # we think we know what it will expand to - note
+                    # we ought to "delay" it was a "=" variable rather
+                    # than ":=" or "+=".
+                    $val =~ s/\s++$//o;
+                    for (split m/\s++/o, $val) {
+                        $seen{$_}++ if $required{$_};
+                        $seen{$_}++ if $recommended{$_};
+                    }
+                    last;
+                }
+                # We don't know, so just mark the target as seen.
+            }
             $seen{$_}++ if $required{$_};
             $seen{$_}++ if $recommended{$_};
         }
+        next; #.PHONEY implies the rest will not match
     }
 
     if (!/^ifn?(?:eq|def)\s/ && m/^([^\s:][^:]*):+(.*)/) {
@@ -251,6 +279,24 @@ while (<RULES>) {
                     $seen{$recommended}++ if $recommended =~ m/$pattern/;
                 }
             } else {
+                # Is it $(VAR) ?
+                if ($target =~ m/^\$[\(\{]([^\)\}]++)[\)\}]$/) {
+                    my $name = $1;
+                    my $val = $variables{$name};
+                    if ($val) {
+                        # we think we know what it will expand to - note
+                        # we ought to "delay" it was a "=" variable rather
+                        # than ":=" or "+=".
+                        $val =~ s/\s++$//o;
+                        local $_;
+                        for (split m/\s++/o, $val) {
+                            $seen{$_}++ if $required{$_};
+                            $seen{$_}++ if $recommended{$_};
+                        }
+                        last;
+                    }
+                    # We don't know, so just mark the target as seen.
+                }
                 $seen{$target}++ if $required{$target};
                 $seen{$target}++ if $recommended{$target};
             }
diff --git a/t/tests/rules-variable-targets/debian/debian/rules b/t/tests/rules-variable-targets/debian/debian/rules
new file mode 100644
index 0000000..9520c78
--- /dev/null
+++ b/t/tests/rules-variable-targets/debian/debian/rules
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+
+  TARGETS := build clean binary binary-arch binary-indep build-arch build-indep
+
+$(TARGETS):
+	dh $@
+
+.PHONEY: $(TARGETS)
+
diff --git a/t/tests/rules-variable-targets/desc b/t/tests/rules-variable-targets/desc
new file mode 100644
index 0000000..a7bc41d
--- /dev/null
+++ b/t/tests/rules-variable-targets/desc
@@ -0,0 +1,5 @@
+Testname: rules-variable-targets
+Sequence: 6000
+Version: 1.0
+Description: Test against missing targets in debian/rules
+Test-Against: debian-rules-missing-recommended-target
diff --git a/t/tests/rules-variable-targets/tags b/t/tests/rules-variable-targets/tags
new file mode 100644
index 0000000..e69de29
-- 
1.7.5.4

