Re: File re-alignment



On May 19, 6:23 pm, nivparsons <kevparsons.gro...@xxxxxxxxxxxx> wrote:
I have some VHDL files thatI'd like to "tidy up".
The VHDL code has several (many) lines with "PORT MAP" in it, followed by code
such as;

fred <= fred,
george <= george,
whatever <= whatever,
nim <= nim,

etc etc

I'd like to read down to the first instance of PORT MAP, then read all the lines with  <= in them, but only up to the next PORT MAP, then find the longest string before <= and rewrite all line out with that length before the <=, so all the <= line up.
Then do it all again for every occurenc of PORT MAP to the file end.

I've donea simple one that reads the whole file and realigns, but I feel this could be done better by doing in sections.

Any help most welcome, I'm only an occasional Tcl dabbler!

The trick is to define a proc doing the hard work (I call it
"doflush"), and call it repeatedly on each "PORT MAP" header for the
previous section, and also once at the end. Notice also how I allow
non-arrow lines to keep their original indentation. Season to taste.

-Alex


proc doflush {} {
set max 0
foreach {ty li} $::l {
if {!$ty} continue
set n [string length [lindex $li 0]]
if {$n>$max} {set max $n}
}
set fmt %${max}s
foreach {ty li} $::l {
if {!$ty} {puts $li;continue}
puts "[format $fmt [lindex $li 0]] => [lindex $li 1]"
}
set ::l {}
}

set l {}
while {[gets stdin line]>=0} {
if {[regexp {PORT MAP} $line]} doflush
if {[regexp {^(.*?)<=(.*)$} $line -> head tail]} {
lappend l 1 [list [string trim $head] $tail]
} else {
lappend l 0 $line
}
}
doflush
.