How to pass arguments to tcl script in Vivado GUI tcl console - tcl

I am trying to execute a tcl script in Vivado GUI Tcl Console and my script takes an argument to decide which type of run (synth, impl, bitgen etc.) has to be configured.
I know that, using -tclargs one could pass arguments if the script is executed in Vivado command-line mode. Something like:
vivado -mode batch -source <filename> -tclargs <arguments>
I tried the same in Vivado gui mode and got an error.
ERROR: [Common 17-170] Unknown option '-tclargs', please type 'source -help' for usage info.
Running 'source -help':
Syntax:
source [-encoding <arg>] [-notrace] [-quiet] [-verbose] <file>
Usage:
Name Description
------------------------
[-encoding] specify the encoding of the data stored in filename
[-notrace] disable tracing of sourced commands
[-quiet] Ignore command errors
[-verbose] Suspend message limits during command execution
<file> script to source
By looking at -help I am getting a feeling that it is not possible to do so. Also, I can't find any documents for doing so. I would like to know if there is any way of achieving this.

The source command doesn't set up the arguments; it's more like C's #include than anything else really. Because of that, if the script that you are sourceing expects argv and argc to be set — as if the script was run as a program — then you should just set them before the source. They are ordinary variables as far as Tcl's concerned; they just happen to be set up by default.
You might also need to set argv0 to the script. Some programs expect that when running in non-interactive mode.
set argv [list "a b c" foo bar 123]
set argc [llength $argv]
set argv0 theScript.tcl
source $argv0

Related

Loading tcl extension from tclsh

I have a C extension to Tcl where command mytest is defined. The extension is compiled correctly (I am on Linux, extension is *.so). For example, I can start tclsh and use it like this:
$ tclsh
% load /path/extension.so
% mytest abc
...
But, if I create a file myscript.tcl with the following content:
load /path/extension.so
mytest abc
then I get error:
$ tclsh myscript.tcl
invalid command name "mytest"
while executing
"mytest abc"
(file "myscript.tcl" line 2)
I am using bash on Ubuntu 14.04. Tcl 8.6.
EDIT 1: My question/problem is that I want to use tclsh with a script as an argument - this script should properly load extensions in such a way that mytest and other implemented functions are working without error.
EDIT 2: Uhh, If I use command "source myscript.tcl" inside tcl shell the result is the same. If I use absolute path for myscript.tcl the error is still the same --- "load" executes without warning but I am not sure about it because I get invalid command name "mytest". Maybe the problem is with scope, but it is working correctly when tclsh is used interactively.
If you are using the full path of the extension library in both cases, that part should work identically. It probably is doing though; if it couldn't load it, it would generate an error (which might or might not be helpful, as some of the ways that things fail give very little information; Tcl reports what it has got, but that's sometimes not enough, as it is dependent on the OS to tell it some things). Instead, the problem is probably elsewhere.
The main difference between interactive use and scripted use is that in interactive use, the unknown command will expand unknown command names to Tcl commands that the thing you typed is an unambiguous prefix of. This is convenient, but when converting to a script, you should always use the full command name. OK, not the full full command name — you mostly don't want or need the :: namespace on the front — but without abbreviation, so don't use lappe for lappend. (In interactive use, Tcl will also exec things as external programs without requiring you to type the exec explicitly; again, that's turned off in scripts as it is rather fragile.)
Could it be that this is what is going on? You can check by setting the global variable tcl_interactive to 0 before typing in your code (I recommend using cut-n-paste for that typing, so that you know exactly what is going in). If that fails, it's the interactive-mode helpfulness that is tripping you up. Check what commands you might have as an expansion for a prefix with info commands (after the load, of course):
info commands mytest*
If that just reports mytest, my theory is wrong. (Well, if it does that and the length of that string is 6; there could theoretically be extra invisible characters have been put on the command name, which would be legal Tcl but very nasty and DON'T DO THAT!)

Tcl interact after sourcing a file.tcl

I want to interact after sourcing a file in Tcl prompt.
i.e.,
]$ tclsh myCode.tcl
// execute my code
% // Enters Interact mode within myCode.tcl
The simplest way of doing this is to use the commandloop command from the TclX extension.
package require Tclx
#... define things and run things...
# Let the user issue commands
commandloop
The wiki page linked above discusses how to do this without using TclX.
I'm afraid I may be reading too little into this, or over-simplifying it, but... isn't what you need the interact command?
If you want Tcl/Expect to do something, then yield control back to the user, pls check out the interact command in the man page link below:
http://www.tcl.tk/man/expect5.31/expect.1.html
If you'd rather do it in pure tcl without any external packages, the simplest implementation of a tclsh prompt is very simple indeed. Just put this at the end of myCode.tcl:
fileevent stdin readable {
puts [eval [gets stdin]]
}
vwait forever
You can even implement this as a standalone program that sources your other tcl scripts.
Of course, the example code above is so simple it doesn't even print a prompt or handle things like multiline commands but it's a good starting point for you to modify and customize.
You may try tkcon, an interactive tclsh which creates a separate window. I wrote a small shell script mytclsh with the first line
#!/usr/bin/tkcon myscript.tcl
and made it executable (chmod 755 mytclsh). This executes myscript.tcl and then goes interactive. Here's more information on tkcon: https://wuhrr.wordpress.com/2011/01/13/a-solution-for-tclsh-editing-woes/

How to disable a modified tclsh interpreter interactive mode?

Run tclsh command without any tcl file, the interpreter will go into interactive mode.
Can I simply disable this feature by modifying the tclsh source code ?
I can't imagine why you would want to bother doing this, given that supplying any script file will turn off interactive mode. The script you supply will have full access to the additional arguments passed in (a list in the global argv variable) and the standard IO channels (stdin, stdout and stderr). It can exit when it is done. Literally anything you want can be done at that point; you've just got to write a script to do it.
If you're including Tcl in your own program, the behaviour of tclsh is implemented in the C function Tcl_Main. If you never call that — instead just using Tcl_FindExecutable, Tcl_CreateInterp and Tcl_Eval/Tcl_EvalFile — then you never get any of that interactive behaviour. While theoretically you could modify the Tcl source itself to do what you want — it's all open source — why would you bother when you could just not call that code in the first place?

Weird TCL quirk

So I am very new and inexperienced to the ways of TCL programming. I wrote a script that calls a proc written by someone else, first removing the output file. It then does some additional logic I wrote.
I moved the logic into a second proc and instantly a bunch of it broke (namely the rm commands).
From what I can tell, the first program on a line inside the central execution (the text following proc definitions) executes normally without an "exec" command. However, if you move it inside a proc, it now needs an "exec" command.
Can anyone explain to me why TCL behaves this way?
e.g.
proc helloworld {} {
puts "hi"
}
#works
rm my_file
helloworld
..
proc helloworld {} {
#doesn't work
rm my_file
puts "hi"
}
helloworld
..
proc helloworld {} {
#works
eval rm my_file
puts "hi"
}
helloworld
..
proc helloworld {} {
#works
file delete my_file
puts "hi"
}
helloworld
*Note this weird behavior may be specific to the program I'm feeding the script to vmd, which has its own built in TCL behavior. Perhaps in your responses you can indicate if this is standard for other interpreters as well?
An interactive tclsh session will try to exec an unknown command (such as rm). You cannot count on this behaviour in non-interactive script execution or, as you've discovered, in procs.
I can't see that this is documented in the tclsh man page, but the unknown man page does. See also the tclsh page on the Tcl wiki. In an interactive tclsh session, you can see what unknown does by typing:
info body unknown
[update]
Quoting from "Practical Programming in Tcl and Tk":
The unknown command provides a few other conveniences. These are used only when you typing commands directly. They are disabled once execution enters a procedure or if the Tcl shell is not being used interactively. The convenience features are automatic execution of programs, command history, and command abbreviation. These options are tried, in order, if a command implementation cannot be loaded from a script library.
Note this is programatically testable too, via the variable tcl_interactive, which is "1" if the Tcl is being run via an interactive shell, and "0" if not. The variable is also settable, so one could start an interactive shell, then [set tcl_interactive 0], and continue on. At this point, one loses such features as the % command prompt proc name / command name completion (i.e.: can't type [pu "xyz"] and get the effect of typing [puts "xyz"], like an interactive shell)automatic "shell-out" to have external commands complete a request (like the "rm" in this original question)and perhaps others...

Can PowerShell autoconvert error output into exceptions?

In my PowerShell script I'm calling some command line tools (not cmdlets) that may output error text and set errorlevel nonzero on error conditions. I'd like any error from any of these tools to abort my script.
What's the best way to do this?
Is there a way to have PowerShell automatically check $? and stderr after every command and throw an exception? I was thinking something along the lines of "on error" that 4NT or VBScript has - a global watch. Not very object-orienty, so I was hoping PowerShell had something better.
[Edit: last couple questions moved to here.]
You will need to either write a function to do this or within the script constantly check for the errorlevel.
Some information on a function to do this is at:
http://www.eggheadcafe.com/conversation.aspx?messageid=31829234&threadid=31829225
and other useful information can be found on the windows powershell blog.