#!/usr/bin/env perl # # su-filter.pl # use strict; my $in_su = 0; my $indent = 0; my $out; my $braces = 0; my $arrcnt; my $data; my $tststr; my $incomm = 0; while(<>) { $tststr = $_; $incomm++ while $tststr =~ /\/\*/g; $incomm-- while $tststr =~ /\*\//g; if($in_su == 1) { if(/}(.*);/) { $out .= $_; do_output($out); $in_su = 0; } elsif(/^ *\} [^\s]+(\[\d*\])* = \{/) { $tststr = $1; $arrcnt = 0; $arrcnt++ while $tststr =~ /\[/g; $in_su++; $braces = 1; /^(.* = \{)(.*)$/; $data = $2; $out .= $1."\n"; } else { $out .= $_; } } elsif($in_su == 2) { $data .= $_; if(/};$/) { #$data = "\n$data"; $data =~ s/\n */\n/g; $data =~ s/};\n?//s; my @strucdata = structureData($data); $out .= displayData($indent, 0, \@strucdata); $out .= "\n$indent};\n"; do_output($out); $in_su = 0; } } elsif($incomm <= 0 && /( *)(static )?(const )?(union|struct) ([^\s]+ )?\{/) { $in_su = 1; $indent = $1; $out = $_; next; } else { do_output($_); } } sub structureData { my $data = $_[0]; my @datalist = split(/(\{|\}|,|"|#|\n|\/\*|\*\/|\(|\))/, $data); my $item; my $dataitem = ""; my @struclist = (); my $substruc; my $inquote = 0; my $inbrace = 0; my $preproc = 0; my $comment = 0; my $inparen = 0; foreach $item (@datalist) { if($comment) { if($item eq "*/") { $comment = 0; $dataitem .= "*/"; push @struclist, $dataitem; $dataitem = ""; next; } $dataitem .= $item; next; } if($inquote) { $dataitem .= $item; if($item eq "\"") { $inquote--; } next; } if($preproc) { if($item eq "\n") { $preproc = 0; push @struclist, $dataitem; $dataitem = ""; next; } $dataitem .= $item; next; } if($inbrace) { if($item eq "}") { $inbrace --; if(!$inbrace) { $substruc = structureData($dataitem); $dataitem = $substruc; next; } } elsif($item eq "{") { $inbrace++; } elsif ($item eq "\"") { $inquote++; } $dataitem .= $item; next; } if($inparen) { if($item eq ")") { $inparen--; } $dataitem .= $item; next; } if($item eq "\n") { next; } if($item eq "#") { $preproc = 1; push @struclist, $dataitem; $dataitem = "#"; next; } if($item eq "/*") { $comment = 1; push @struclist, $dataitem; $dataitem= "/*"; next; } if($item eq "\"") { $dataitem .= $item; $inquote++; next; } if($item eq "{") { $inbrace++; next; } if($item eq ",") { push @struclist, $dataitem; $dataitem = ""; next; } if($item eq "(") { $dataitem .= $item; $inparen++; next; } if($item =~ /^\s*$/) { next; } if(ref $dataitem eq 'ARRAY') { push @struclist, $dataitem; $dataitem = ""; } $dataitem .= $item; } push @struclist, $dataitem; return \@struclist; } sub displayData { my $indent = shift; my $depth = shift; my $data = shift; my $item; my $out = ""; my $currline = ""; my $first = 1; my $prevpreproc = 0; my $prevcomment = 0; foreach $item (@{$data}) { if($item =~ /^\/\*/) { #Comment $item =~ s/\n/\n$indent/g; if($out =~ /\n\s*$/s) { $out .= $item."\n".$indent; } else { $out .= "\n".$indent.$item."\n".$indent; } $currline = $indent; $prevcomment = 1; next; } $item =~ s/^\s+//; if($item =~ /^#/) { #Pre-processor directive if($out =~ /\n\s*$/s) { $out =~ s/\n\s*$/\n/; $out .= $item."\n".$indent; } else { $out .= "\n".$item."\n".$indent; } $currline = $indent; $prevpreproc = 1; next; } if($first) { $first = 0; if($depth != 0) { $out .= $indent; $currline = $indent; } } else { if(!$prevpreproc && !$prevcomment) { $out .= ", "; $currline .= ", "; if($depth == 1) { $out .= "\n"; $currline = ""; } if($depth == 1) { $out .= $indent; $currline .= $indent; } } } $prevpreproc = 0; $prevcomment = 0; if (ref $item eq 'ARRAY') { if($depth == 0) { $out .= displayData("$indent ", $depth+1, $item); } else { $out .= "{\n".displayData("$indent ", $depth+1, $item)."\n".$indent."}"; $currline = $indent."}"; } } else { if(length $currline.$item > 79) { $currline = $indent; $out .= "\n$indent"; } $out .= $item; $currline .= $item; } } return $out; } sub do_output { my $out = shift; # Strip any trailing whitespace $out =~ s/\s+\n/\n/g; print $out; }