0

I have two tcl scripts, one of which calls the other. The second script, 'version.tcl' is in a sub-directory ('synthesis') of the working directory.

I currently have it set up and working in the following fashion:

cd ./synthesis
source version.tcl
cd ../

I would like to condense that to one command which can source the script without having to change directories, something along the lines of:

source [file join [file join [[pwd] synthesis] version.tcl]]

Or

source ./synthesis/version.tcl

Unfortunately neither one of the above commands works. I know this should be an easy fix for someone with more familiarity with tcl than me, so any help would be greatly appreciated.

8
  • What makes you think it doesn't work? source ./syntheses/version.tcl works fine. Perhaps in the "main" script, your pwd isn't what you think it is. Commented Jun 13, 2022 at 21:44
  • FYI, you don't need to nest file join calls: this is fine: file join [pwd] synthesis version.tcl Commented Jun 13, 2022 at 21:45
  • @glennjackman thanks for the replies! I also thought that maybe I wasn't where I thought I was in the 'main' directory, but since the cd ./synthesis approach worked, I'm fairly certain I am in the 'main' directory Commented Jun 13, 2022 at 21:54
  • @glennjackman Also, the source ./synthesis/version.tcl doesn't work when I try it. I'm running on a windows 10 if that makes any difference. I had expected it to work when I originally tried it but no luck??? Commented Jun 13, 2022 at 21:55
  • Maybe version.tcl makes (incorrect) assumptions about the working directory too. But in general source ./synthesis/version.tcl works. If you need more help, describe in more detail how it doesn't work (error message etc). Commented Jun 13, 2022 at 22:16

1 Answer 1

3

The source command reads files in other directories just fine; it uses almost exactly the same machinery as open to handle filenames (and that's little more than just "give it to the OS"). We know that it works; it's tested and it is something that very many people have used across many platforms.

What's going wrong is almost certainly that the code inside that file expects to have the current directory be the one that contains the script. Your options to fix that are

  1. Do what you're currently doing, or a slightly more robust version of it:

    proc sourceInDir {directory scriptName} {
        set pwd [pwd]
        cd $directory
        try {
            uplevel 1 [list source $scriptName]
        } finally {
            cd $pwd
        }
    }
    
  2. Update the code that you call so it accesses resources relative to the script, not to the current directory:

    # Put this at the top of the script, OUTSIDE procedures but INSIDE namespace eval
    variable baseDir [file dirname [file normalize [info script]]]
    
    # Then can access relative to that with, say:
    open [file join $baseDir foo.txt]
    
Sign up to request clarification or add additional context in comments.

1 Comment

The second is the better code style overall, but the first is much less work when you don't control the code that you're calling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.