Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Tcl to update version number

Status
Not open for further replies.

wtr

Full Member level 5
Joined
May 1, 2014
Messages
299
Helped
29
Reputation
58
Reaction score
25
Trophy points
1,308
Activity points
4,108
Hello all,

Previous on a different machine in a land far far away I've implemented this.

However I can't recall how to do it. The ; was previously attached to the number which made it even more complicated.

I would like to take this line
constant FIRMWARE_VERSION_C : integer := 71 ;
and turn it into the following
constant FIRMWARE_VERSION_C : integer := 72 ;


Code TCL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
set filename "./hdl/FWKS_PIU_PKG.vhd"
set filename2 "./hdl/FWKS_PIU_PKG_temp.vhd"
 
set f [open $filename]
set f2 [open $filename2 w]
set content [read $f]
 
set lines [split $content "\n"]
 
foreach line $lines {
    if [regexp "FIRMWARE_VERSION_C" $line] {
        set a [lindex [split $line] end]
        
        # set b [expr {int($a) +1}]; #kinda works
        # lreplace $line end-1 end-1 $b
        # puts $f2 $line
        puts $f2 $a
 
 
    } else {
        puts $f2 $line
    }
}
# It is important to not lock out the file
 
close $f 
close $f2



When I try the line replacement my tcl compiler in libero is saying "[ Line 12: expected number but got ":=" ]" - which is the foreach line.

- - - Updated - - -

FYI.
Error mentioned above brought about by line in the original file which didn't have space between number and ";"

-- constant FIRMWARE_VERSION_C : integer := 72;

Now it will run but not update the number!

- - - Updated - - -

Solved own question, however would appreciate if anyone knows of a better way of doing this.


Code TCL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
set filename "./hdl/FWKS_PIU_PKG.vhd"
set filename2 "./hdl/FWKS_PIU_PKG_temp.vhd"
 
set f [open $filename]
set f2 [open $filename2 w]
set content [read $f]
close $f 
 
set lines [split $content "\n"]
 
 
foreach line $lines {
 
    if [regexp "FIRMWARE_VERSION_C" $line] {
        set a [lindex [split $line] end-1]
        set b [expr {int($a)+1}]
 
        # set line2 [lreplace $line end-1 end "$b ;"]
        # lreplace $line end-1 end "$b ;"
        # lreplace $line end-1 end {$b ;}
        lreplace $line end-1 end-1 {$b}
        puts $f2 $line
        
    } else {
        puts $f2 $line
    }
}
# It is important to not lock out the file
 
close $f2

 

linux sed utility is by far a best solution to this
 

Unfortunately I'm on a Windows machine. I was thinking maybe using a batch script with string replacement, however ideally I'd like it to all be implemented in my tcl build script
 

Have you tried https://www.cygwin.com/?
It provides tools similar to what you can find on linux. It has the "sed" command and other useful stuff that exist in linux.
 

Have you tried http://www.cygwin.com/?
It provides tools similar to what you can find on linux. It has the "sed" command and other useful stuff that exist in linux.

Actually there are win32 gnu tool ports available for sed and a bunch of other utilities. Unfortunately it doesn't appear to be maintained anymore, but is useful when you don't want to create a linux environment as you are scripting for a tool that is running under windows.
http://gnuwin32.sourceforge.net/

Though in pure Tcl you probably want to use regsub. You use the regexp you originally had to find the FIRMWARE_VERSION_C line then use regsub {\d+} $regexp_result_string "72" to replace the 71.

Code:
set line "constant FIRMWARE_VERSION_C : integer := 71 ;"
if [regexp "FIRMWARE" $line] {
  regsub {\d+} $line "72" newline
}
puts $newline
though if you want to increment thee 71 then you would have to extract the 71 out of the $line first then increment it and put it in place of the "72" in the regsub line.

- - - Updated - - -

This will extract the version number and increment it by 1, it also ignores any white space around the version number.

Code TCL - [expand]
1
2
3
4
5
6
set line "constant FIRMWARE_VERSION_C : integer := 72 ;"
 
if [regexp {.*FIRMWARE_VERSION_C.*?(\d+)} $line matched sub1] {
  regsub {\d+} $line [expr $sub1 + 1] newline
}
puts $newline

The ? makes the .* non-greedy, my original version was missing this and the results were always 2 :shock:
 
Last edited:
  • Like
Reactions: wtr

    wtr

    Points: 2
    Helpful Answer Positive Rating
Thanks Add-ee, this use of \d+ is good, because the way a VHDL signal is declared there should only ever be one digit. However what would you do if the "71 ;" was "71;" (id.est no space)
 

the \d+ means 1 or more digits and it only means digits so 0-9 are extracted whitespace and other characters are ignored.

If you need to deal with lines like:

constant SOME_UGLY_NUMBERED_263_CONSTANT2 : integer :=71;

then the following regex should work (untested):

.*UGLY.*CONSTANT.*:=\s*?(\d+)[ ;].*

which breaks down into, find UGLY followed after some number of other characters by CONSTANT followed by more characters up to the := followed by zero or more whitespace (space or tab, non-greedy), followed by the number you want to extract followed by a space or semi colon.

The stuff after the (\d+) is utterly unnecessary but you asked about detecting if the number is followed by space or ;.

Try playing around with the above expressions on this site:
 
  • Like
Reactions: wtr

    wtr

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top