diff options
| author | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-06 18:12:40 +0500 |
|---|---|---|
| committer | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-06 18:12:40 +0500 |
| commit | b4995f979d127cea667b4e2b71c91e9db4ab52ef (patch) | |
| tree | fbebc775e10932bace8d6a7c3481b1ba200c64db /fix_for_loops.pl | |
| parent | 9575eb0a1ffa8150f70f88b5f6b55f342c3c0088 (diff) | |
wip
Diffstat (limited to 'fix_for_loops.pl')
| -rw-r--r-- | fix_for_loops.pl | 81 |
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; +} |
