Storing Tcl source code encoded, and running via your own C program
Archive - Originally posted on "The Horse's Mouth" - 2011-09-02 23:09:56 - Graham EllisTcl is a language. And Tcl is also a C library. How's that?
Tcl originates from a requirement to provide a taioring capability within C programs that could be accessed in a program-like style. And the program-like style that was implemented actually had the full capabilities of a programming language. That means that you can write a piece of Tcl to run within your C program if it has appropriate hooks, and you can also write a piece of Tcl to run within a C program such as tclsh which is provided with Tcl as a shell in which Tcl can run - basically, tclsh is a C program with the hooks to run Tcl and not much more.
On some Tcl courses (where it's relevant to any of the delegates) we demonstrate how a Tcl interpretter can be embedded into a C program, and how C code can be added to a Tcl program to allow for processor-intensive tasks and ready written C functionallity. And there are examples [here] and [here] on our web site. Also see [here] for the extended piece of Tcl that calls the C.
The fact that Tcl is a true scripting language, in which the program is run directly from source code, really worries some users. They're concerned that their source code could be ripped off by users. And they're concerned that the source code could be modified, and then not do what was intended. We have an example in our notes in which the Tcl program source is actually embedded within the C program - that's [here] - but of course that doesn't make for an editable system, nor an elegant one. What's really wanted is a way in which an obfurscated / encoded source code can be kept in one file - useless except to the specific program that it's set up to run in, and rendered useless by attempts to edit it.
This concern came up today, and I found myself - long after the course would normally have been finished on a Friday afternoon - writing C code! My C program reads in a file of mixed-up Tcl, adding all the lines into a character array held in memory that's allocated via realloc to make sure that any length of code can be handled. It then decodes the Tcl program which looked like this when loaded:
p
or csaukes rp{orpm}t{
lgbolar
zp tu sn-noweilen" p$orpm?t"
lfsu htsodtu
es tzr[ egsts dtni
]r teru nr$
z}
into this:
proc askuser {prompt} {
global rz
puts -nonewline "$prompt? "
flush stdout
set rz [gets stdin]
return $rz
}
and then ran it via the Tcl library. Full source - [here].