Say I have defined proc f1 proc f2 and proc f3. Now I want to create a TCL interpreter, source the code of proc f1 proc f2 and proc f3 into that interpreter and restrict all commands other than f1, f2 and f3 are within that interpreter. How I can do that?
EDIT:
If a command other that f1, f2 and f3 are called within the interpreter I have created an error message should be issued and execution of the code sourced in the interpreter (assume that this another code which is sourced in the same interpreter, after sourcing the code with f1, f2 and f3 procs) should be stopped.
You can't quite do that, but you can do something that's similar enough for most purposes.
What you should do is create the commands f1, f2 and f3 in an interpreter normally, then create a sub-interpreter that has no Tcl commands at all, and alias the commands that you do want to expose in that sub-interpreter to the commands in the parent.
# First define f1-f3 in whatever way you want
# Now make the context; we'll use a safe interpreter for good measure...
set slave [interp create -safe]
# Scrub namespaces, then global vars, then commands
foreach ns [$slave eval namespace children ::] {
$slave eval namespace delete $ns
}
foreach v [$slave eval info vars] {
$slave eval unset $v
}
foreach cmd [$slave eval info commands] {
# Note: we're hiding, not completely removing
$slave hide $cmd
}
# Make the aliases for the things we want
foreach cmd {f1 f2 f3} {
$slave alias $cmd $cmd
}
# And evaluate the untrusted script in it
catch {$slave invokehidden source $theScript}
# Finally, kill the untrusted interpreter
interp delete $slave
Here is a simple solution: read input line by line. If the the first token is f1, f2, or f3, then execute the command, hit Control+C or type exit
to exit the loop:
proc f1 {args} { puts "f1:$args" }
proc f2 {args} { puts "f2:$args" }
proc f3 {args} { puts "f3:$args" }
while 1 {
puts -nonewline ">"
flush stdout
gets stdin line
set firstToken [lindex $line 0]
if {[lsearch {f1 f2 f3 exit} $firstToken] != -1} {
eval $line
}
}
There are several problems with this solution:
Despite these drawbacks, the solution is very simple to implement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With