Fisher
Fisher

Reputation: 422

Tcl: How to replace variable string?

Input file is a tcl script and it looks like:

set PATH /user/abc/path
set PATH2 /user/abc/path2
...
read_verilog ${PATH}/src/vlog/code_1.v
read_verilog $PATH/src/vlog/code_2.v
read_vhdl ${PATH2}/src/vhd/code_3.vh
read_vhdl $PATH2/src/vhd/code_4.vh
[other commands ...]

Need to check if the source file is exist and print out none-exist files. If none of the file is exist, the output looks like:

read_verilog ${PATH}/src/vlog/code_1.v
read_verilog $PATH/src/vlog/code_2.v
read_vhdl ${PATH2}/src/vhd/code_3.vh
read_vhdl $PATH2/src/vhd/code_4.vh

And below is my script:

#!/usr/bin/tclsh
set input_file    "input.tcl"

set input_fpt        [open $input_file r]
set input_lines_all  [read $input_fpt]
set input_lines      [split $input_lines_all "\n"]

set PATH /user/abc/PATH
set PATH /user/dgc/PATH2

foreach line $input_lines {
   if { [string match "read_verilog *" $line] || [string match "read_vhdl*" $line] } {
      regexp {[read_verilog read_vhdl] (.*)} $line matched file

      if { [string match {*[{P]AT[H}]*} $file] } {
         set abs_file [string map {${PATH} /user/abc/PATH} $file]
      } elseif { [string match "*PATH2*" $file] } {
         set abs_file [string map {${PATH2} /user/abc/PATH2} $file]
      } else {
         set abs_file $file
      }

      if { ![file exists $abs_file] } {
         puts $line
      }
   }
}

My script can't check $PATH and not sure if there is a more efficient way to do the job.

Upvotes: 1

Views: 2541

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137787

The simplest way of doing just the substitutions you want is with the string map command. Build up the map piece by piece first, then apply it to your string.

set map {} 
lappend map {$PATH} $PATH
lappend map {${PATH}} $PATH
lappend map {$PATH2} $PATH2
lappend map {${PATH2}} $PATH2

set modified [string map $map $inputString] 

You can apply the map as many times as you want once you have built it, and transform your data either a line at a time or all in one go. However, you might be better off just evaluating the file as a Tcl script. That can be an incredibly useful approach to some types of parsing (especially when used in conjunction with a safe interpreter) if the input is suitable, which yours appears to be.

Upvotes: 1

Related Questions