#!/bin/perl
use strict;
use Data::Dumper;
use Tie::File;
use Getopt::Long;
my $opt_infile;
my $opt_nochk;
GetOptions(
"i=s" => \$opt_infile,
"nochk:s" => \$opt_nochk,
) or die "Error in command line arguments\n";
my $tidy_regex = qr/
\s*\/\/
\s*Tidy:
\s*\(
\s*([1-9][0-9]*)
\s*,
\s*([1-9][0-9]*)
\s*\)
/x;
my $identifier_regex = qr/[a-zA-Z][a-zA-Z0-9_]*/;
my $number_regex = qr/[1-9][0-9]*/;
my $range_regex = qr/\[$number_regex:0\]/;
my $port_regex = qr/
(?<dir> input|output)?
(?<type> wire|reg|bit|logic)?
(?<pdim_str> $range_regex*)
(?<id> $identifier_regex)
(?<updim_str> $range_regex*)
;
/x;
my $suffix_regex = qr/;(?<suffix>.*)/;
my @contents;
tie @contents, 'Tie::File', $opt_infile or die "Fail to tie to [$opt_infile]\n";
#------------------------------------------------------------------------------#
my $interval = &traverse;
for (@$interval) {
my $records = &make_records($_);
my $printer = &make_printer($records);
&tidy($printer, $records);
}
#------------------------------------------------------------------------------#
sub traverse {
my $intervals = [];
for (@contents) {
if (/$tidy_regex/) {
push @$intervals, [$1, $2];
}
}
return $intervals;
}
sub make_records {
my $interval = shift;
my @records;
for (my $i = $interval->[0]-1; $i < $interval->[1]; $i++) {
my $record = {};
my $line = $contents[$i];
$record->{lineno} = $i+1;
$line =~ $suffix_regex;
my $suffix = $+{suffix};
$suffix =~ s/^\s*//;
$suffix =~ s/\s*$//;
$record->{suffix} = $suffix;
$line =~ s/\s//g;
my %line_record_tmp;
if ($line =~ $port_regex) {
%line_record_tmp = %+; # copy %+
$record = \%line_record_tmp;
push @records, $record;
}
($record->{pdim}, $record->{pdims}, $record->{pdims_len})
= &proc_dim_str($record->{pdim_str});
($record->{updim}, $record->{updims}, $record->{updims_len})
= &proc_dim_str($record->{updim_str});
}
# print Dumper(\@records);
return \@records;
}
sub make_printer {
my $records = shift;
my %printer = (
dir_w => 0,
type_w => 0,
m_pdim => 0,
m_pdims_len => [],
id_w => 0,
m_updim => 0,
m_updims_len => [],
);
for (@$records) {
my $cur_dir_w = length($_->{dir});
my $cur_type_w = length($_->{type});
my $cur_id_w = length($_->{id});
$printer{dir_w} = $cur_dir_w if ($cur_dir_w > $printer{dir_w});
$printer{type_w} = $cur_type_w if ($cur_type_w > $printer{type_w});
$printer{id_w} = $cur_id_w if ($cur_id_w > $printer{id_w});
$printer{m_pdim} = $_->{pdim} if ($_->{pdim} > $printer{m_pdim});
for (my $i = 0; $i < $_->{pdim}; $i++) {
$printer{m_pdims_len}->[$i] = $_->{pdims_len}->[$i]
if (not defined $printer{m_pdims_len}->[$i] or $_->{pdims_len}->[$i] > $printer{m_pdims_len}->[$i]);
}
$printer{m_updim} = $_->{updim} if ($_->{updim} > $printer{m_updim});
for (my $i = 0; $i < $_->{updim}; $i++) {
$printer{m_updims_len}->[$i] = $_->{updims_len}->[$i]
if (not defined $printer{m_updims_len}->[$i] or $_->{updims_len}->[$i] > $printer{m_updims_len}->[$i]);
}
}
# print Dumper(\%printer);
return \%printer;
}
sub proc_dim_str {
my $dim_str = shift;
$dim_str =~ s/\[//g;
$dim_str =~ s/0\]//g;
my @dims = split ":", $dim_str;
my @dims_len;
for (@dims) {
push @dims_len, length($_);
}
return scalar(@dims), \@dims, \@dims_len;
}
sub tidy {
my ($printer, $records) = (shift, shift);
for (@$records) {
my $fmt = "";
$fmt .= "%-$printer->{dir_w}s";
$fmt .= " " if ($printer->{dir_w} > 0);
$fmt .= "%-$printer->{type_w}s";
$fmt .= " " if ($printer->{type_w} > 0);
for (my $i = 0; $i < $printer->{m_pdim}; $i++) {
if ($i < $_->{pdim}) {
$fmt .= "[%-$printer->{m_pdims_len}->[$i]s:0]";
} else {
my $dummy_len = $printer->{m_pdims_len}->[$i]+4;
$fmt .= " "x$dummy_len;
}
}
$fmt .= " %-$printer->{id_w}s";
for (my $i = 0; $i < $printer->{m_updim}; $i++) {
if ($i < $_->{updim}) {
$fmt .= "[%-$printer->{m_updims_len}->[$i]s:0]";
} else {
my $dummy_len = $printer->{m_updims_len}->[$i]+4;
$fmt .= " "x$dummy_len;
}
}
$fmt .= "; %-s\n";
my $str = sprintf $fmt, $_->{dir}, $_->{type}, @{$_->{pdims}}, $_->{id}, @{$_->{updims}}, $_->{suffix};
print $str;
if (defined $opt_nochk) {
$contents[$_->{lineno}-1] = $str;
}
}
}
tidy sv code port declarations
最新推荐文章于 2024-05-14 23:13:17 发布