From d9d454a037b3342d604e79f67664c0e10e915648 Mon Sep 17 00:00:00 2001
From: Jelte Fennema <github-tech@jeltef.nl>
Date: Mon, 7 Dec 2020 22:15:09 +0100
Subject: [PATCH 3/6] Add script to remove useless declarations

---
 src/tools/remove_useless_declarations.sh | 34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100755 src/tools/remove_useless_declarations.sh

diff --git a/src/tools/remove_useless_declarations.sh b/src/tools/remove_useless_declarations.sh
new file mode 100755
index 0000000000..44cff5c32a
--- /dev/null
+++ b/src/tools/remove_useless_declarations.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+set -eu
+
+cd "$(git rev-parse --show-toplevel)"
+files=$(git ls-tree -r HEAD --name-only | grep '\.c$' | grep -v '/test/expected/')
+while true; do
+    # A visual version of this regex can be seen on https://www.debuggex.com/
+    # by pasting the search string there. This makes it MUCH clearer what the
+    # regex is doing.
+    search='\n\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t)?(?=\b(?P=variable)\b))(?<=\n\t)(?<!:\n\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])'
+    replace='\n$+{code_between}\t$+{type}$+{variable} ='
+    # shellcheck disable=SC2086
+    perl -i -p0e "s/$search/$replace/sg" $files
+    # The following are simply the same regex, but repeated for different
+    # indentation levels, i.e. finding declarations indented using 2, 3, 4, 5
+    # and 6 tabs. More than 6 don't really occur in the wild.
+    # (this is needed because variable sized backtracking is not supported in perl)
+    # shellcheck disable=SC2086
+    perl -i -p0e 's/\n\t\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t\t)?(?=\b(?P=variable)\b))(?<=\n\t\t)(?<!:\n\t\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])/\n$+{code_between}\t\t$+{type}$+{variable} =/sg' $files
+    # shellcheck disable=SC2086
+    perl -i -p0e 's/\n\t\t\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t\t\t)?(?=\b(?P=variable)\b))(?<=\n\t\t\t)(?<!:\n\t\t\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])/\n$+{code_between}\t\t\t$+{type}$+{variable} =/sg' $files
+    # shellcheck disable=SC2086
+    perl -i -p0e 's/\n\t\t\t\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t\t\t\t)?(?=\b(?P=variable)\b))(?<=\n\t\t\t\t)(?<!:\n\t\t\t\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])/\n$+{code_between}\t\t\t\t$+{type}$+{variable} =/sg' $files
+    # shellcheck disable=SC2086
+    perl -i -p0e 's/\n\t\t\t\t\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t\t\t\t\t)?(?=\b(?P=variable)\b))(?<=\n\t\t\t\t\t)(?<!:\n\t\t\t\t\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])/\n$+{code_between}\t\t\t\t\t$+{type}$+{variable} =/sg' $files
+    # shellcheck disable=SC2086
+    perl -i -p0e 's/\n\t\t\t\t\t\t(?!(return|static)\b)(?P<type>(\w+[\t ])+[\t *]*)(?>(?P<variable>\w+)( = [\w>\s\n-]*?)?;\n(?P<code_between>(?>(?P<comment_or_string_or_not_preprocessor>\/\*.*?\*\/|"(?>\\"|.)*?"|(?!goto)[^#]))*?)(\t\t\t\t\t\t)?(?=\b(?P=variable)\b))(?<=\n\t\t\t\t\t\t)(?<!:\n\t\t\t\t\t\t)(?P=variable) =(?![^;]*?[^>_]\b(?P=variable)\b[^_])/\n$+{code_between}\t\t\t\t\t\t$+{type}$+{variable} =/sg' $files
+    # shellcheck disable=SC2086
+    # shellcheck disable=SC2086
+    git diff --quiet $files && break;
+    # shellcheck disable=SC2086
+    git add $files;
+done
-- 
2.17.1

