How to disable a modified tclsh interpreter interactive mode? - tcl

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?

Related

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

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

Is there a way to undefine a function in emacs lisp?

I have a macro that creates function. It creates interactive functions based on current opened buffer. However, it starts to flood the M-x after a long running section. Is there a way to make a function invalid?
You can use fmakunbound:
(fmakunbound 'my-boring-function)

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/

Passing execution time parameters to TCL scripts from non interactive shell

I am able to run the TCL scripts on the linux server from the Non-interactive shell created by JSch library used in the java program from windows environment. The problem is I have some scripts which needs to pass certain parameters during the execution of the script based on the intermediate output of the script and after the parameters are entered, the script execution continues from there onwards. But as it is non interactive shell, I am not able to pass this parameters during execution. Is there any way where I can make it work ? I thought of an option where, I will pass the parameters as command line argument, but wanted to know any other way.
When you say "parameters", do you mean anything that a user would have entered in an interactive session as an input to prompts presented by the script?
If yes, there are two possibilities:
If the script does not expect the session to be interactive, and just reads its input from its standard input stream (using gets for instance), then just feed this input to the standard input of the tclsh process which interprets your script.
If the script does expect the session to be interactive (and refuses to just accept the data from its input stream), you will have to allocate a pseudo-TTY for the target process.
I'm not familiar with JSch, but this appears to be a question (and an answer) dealing with the making JSch allocate a PTY.