summaryrefslogtreecommitdiff
path: root/fix_for_loops.pl
diff options
context:
space:
mode:
authormaxim nikonov <maxim.nikonov@hqo.co>2026-02-06 18:12:40 +0500
committermaxim nikonov <maxim.nikonov@hqo.co>2026-02-06 18:12:40 +0500
commitb4995f979d127cea667b4e2b71c91e9db4ab52ef (patch)
treefbebc775e10932bace8d6a7c3481b1ba200c64db /fix_for_loops.pl
parent9575eb0a1ffa8150f70f88b5f6b55f342c3c0088 (diff)
wip
Diffstat (limited to 'fix_for_loops.pl')
-rw-r--r--fix_for_loops.pl81
1 files changed, 81 insertions, 0 deletions
diff --git a/fix_for_loops.pl b/fix_for_loops.pl
new file mode 100644
index 000000000..200867e17
--- /dev/null
+++ b/fix_for_loops.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+# Transform for-loop variable declarations from:
+# for (int i = 0; i < n; i++)
+# to:
+# int i;
+# for (i = 0; i < n; i++)
+#
+# Tracks declared variables per-scope (approximated by function boundaries)
+# to avoid duplicate declarations.
+
+use strict;
+use warnings;
+
+my %declared; # Track declared variables in current scope
+
+while (<>) {
+ # Reset scope tracking when we see a function definition start
+ # Pattern 1: identifier followed by ( ... ) { at end of line (single line)
+ # Pattern 2: standalone { on a line (for K&R style function defs)
+ if ((/^\w.*\)\s*(const)?\s*\{\s*$/ && !/^\s*(for|if|while|switch|else)\b/) ||
+ /^\{\s*$/) {
+ %declared = ();
+ }
+
+ # Skip lines that are comments
+ if (/^\s*\/\//) {
+ print;
+ next;
+ }
+
+ # Skip problematic patterns where we can't simply insert a declaration before
+ if (/\}\s*for\s*\(/ || /else\s*\{?\s*for\s*\(/) {
+ print;
+ next;
+ }
+
+ # Pattern: for (TYPE WHITESPACE [*] VAR = INIT; ...)
+ if (/^(\s*)(.*?)\bfor\s*\(\s*(const\s+)?(unsigned\s+)?(\w+)(\s*\*{1,2}\s*|\s+)(\w+)\s*=\s*/) {
+ my $indent = $1;
+ my $prefix = $2;
+ my $const = $3 // '';
+ my $unsigned = $4 // '';
+ my $type = $5;
+ my $starsep = $6;
+ my $var = $7;
+
+ # Skip if already transformed or invalid
+ next if $type eq $var;
+
+ # Skip if prefix contains control flow
+ if ($prefix =~ /\b(if|else|while|switch)\s*\(.*\)\s*$/ || $prefix =~ /\belse\s*$/) {
+ print;
+ next;
+ }
+
+ # Extract stars from starsep
+ my $stars = '';
+ if ($starsep =~ /(\*+)/) {
+ $stars = $1;
+ }
+
+ # Build full type string
+ my $fulltype = "${const}${unsigned}${type} ${stars}";
+ $fulltype =~ s/\s+/ /g;
+
+ # Check if this exact variable (by name) was already declared in this scope
+ my $key = $var;
+ if (!exists $declared{$key}) {
+ # First occurrence - add declaration
+ print "${indent}${fulltype}${var};\n";
+ $declared{$key} = 1;
+ }
+ # Always modify the for loop
+ if ($prefix ne '') {
+ s/\bfor\s*\(\s*(const\s+)?(unsigned\s+)?(\w+)(\s*\*{1,2}\s*|\s+)(\w+)\s*=/for (${var} =/;
+ } else {
+ s/^(\s*)for\s*\(\s*(const\s+)?(unsigned\s+)?(\w+)(\s*\*{1,2}\s*|\s+)(\w+)\s*=/${1}for (${var} =/;
+ }
+ }
+ print;
+}