I am working on a project need Tclsh like support with some self-defined commands. I implemented following code (based on Tcl 8.5):
Tcl_Main(argc, argv, Tcl_AppInit);
And put new commands registration in Tcl_AppInit. Everything looks fine, except that with the new command line interpreter, when I type Tcl built-in command "history", I got :
% history
invalid command name "history"
Other built-in commands work fine, like "puts", "set", etc.
Why ? Do I have to implement my own "history" command instead?
Add my solution here:
It turns out history is part of Tcl script library which needs to be sourced during initialization, either by sourcing $TCL_LIBRARY/init.tcl or calling Tcl_Init(interp).
Related
I need someone to outline how to pass command line arguments to CLion. What I've found so far hasn't worked for me. Specifically I need to know how to pass multiple arguments to the program from the command line.
If you click on Run-Edit Configurations you can create an "Application" configuration that allows you to provide the Program arguments - either in a single line, or in a separate window one argument per line.
I landed on this SO page as I was using CLion with Rust.
For Rust I was able to add the command line arguments to the end of the Run\Edit Configurations\Command. Notice the required --.
I got this tip from Jetbrains.
For C, it was Run\Edit Configurations\Program Arguments, as #Zulan said.
I started learning tcl a few days ago and am currently trying to create a simple password manager gui application. I created two toplevel windows using tcl/tk in separate files than I intend to call from a main tcl file using the source command. I decided to split up the other tcl functions that handled hashing; checking hashes; and file IO in another tcl file. Then I would bind these functions to the gui widgets by "importing the function file". I wanted to import the assorted tcl functions from the same directory as the other tcl file containing the gui code, much like python's import system. However I have experienced differculty creating a package, I have looked up as many guides as I can find and am still confused about the process. I created a namespace in the functions file then added a provided line, then ran pkg_mkIndex . *.tcl in the tclsh shell. Then I added requires function file to the gui widget file and put the lappend auto_path command at the top of the file. However as soon as I run the file I get an annoying can't find package popup. Note: I am using a tcl interperter on windows. Any help would be greatly apperciated and also I am relatively new to programming and tcl in general so any other tips would also be helpful. Thanks in advance!
widget file contains this at header
lappend auto_path "C:\Users\j715c\coding_projects\tcl\tcl_proj\password_manager"
package require FileHandler
Function File contains this
package provide FileHandler $FileHandler::version
package require Tcl 8.5
package require sha256
namespace eval ::FileHandler {
namespace export check_password_attempt load_file check_null_file check_hash hash write_file parse_entries
set version 1.0
set hashedpass ""
}
full code here on github
When I try to generate the pkgIndex.tcl file, I get this error:
$ echo 'pkg_mkIndex -verbose . *.tcl' | tclsh
warning: error while sourcing FileHandler.tcl: can't read "FileHandler::version": no such variable
You're using the version variable before it's defined. Don't forget that Tcl is an interpreted language.
Try this:
namespace eval ::FileHandler { variable version 1.0 }
package provide FileHandler $FileHandler::version
package require Tcl 8.5-
package require sha256
namespace eval ::FileHandler {
namespace export check_password_attempt load_file check_null_file check_hash hash write_file parse_entries
variable hashedpass ""
}
Note the required Tcl version ends with - so that Tcl 8.6 can be used.
Now,
$ echo 'pkg_mkIndex -verbose . *.tcl' | tclsh
successful sourcing of FileHandler.tcl
packages provided were {FileHandler 1.0}
processed FileHandler.tcl
$ cat pkgIndex.tcl
# comments ...
package ifneeded FileHandler 1.0 [list source [file join $dir FileHandler.tcl]]
$ tclsh
% lappend auto_path .
% package req FileHandler
1.0
I need someone to outline how to pass command line arguments to CLion. What I've found so far hasn't worked for me. Specifically I need to know how to pass multiple arguments to the program from the command line.
If you click on Run-Edit Configurations you can create an "Application" configuration that allows you to provide the Program arguments - either in a single line, or in a separate window one argument per line.
I landed on this SO page as I was using CLion with Rust.
For Rust I was able to add the command line arguments to the end of the Run\Edit Configurations\Command. Notice the required --.
I got this tip from Jetbrains.
For C, it was Run\Edit Configurations\Program Arguments, as #Zulan said.
I'm using tclreadline to handle completions in my project, which is written in C/C++ and TCL.
I had to modify some configurations to deal with Readline 6.2, but I managed it.
I have 3 problems:
I defined other commands in the TCL interpreter, like get_ports and get_modules.
If I type get_por, it correctly executes get_ports, but the history says get_por.
If I type get_por -of_objects [get_mod], it correctly executes get_ports -of_objects [get_modules], but the history says get_por -of_objects [get_mod]. So the command is not expanded before adding it to the history. How can I manage this?
If I type get_por -of [get_mod] it doesn't expand -of in -of_objects, because I check for -of_objects inside the command and it doesn't appear. How can I manage INSERT-COMPLETIONS mode of readline? Or alternatively, any kind of INSERT-ALL-COMPLETIONS ?
If I type get_por -ofTAB, tclreadline issues an error of ScriptCompleter, which says that get_por is not a command. It should complete the command, first, and then complete the option, which is defined in a proc complete(get_ports).
I need to make a debug shell inside each c exe(linux enviroment), and my solution is as follows:
Read elf symbols from exe file, build a symbol->address table in
memory;
Run a thread calling readline to accept user input, some thing
like a c function call;
use Lex & yacc to parse the function name and arg list;
Find address of the function in the symbol table;
Call the function with args list;
Every function written can be input as shell command instantly.
I don't think this is a fresh idea, and my question is: Are there any mature codes implemented already?
Thanks for your help!
Sure. If you had working with VxWorks, you'll find WindShell is what you're looking for. I had port a similar shell to Linux. You can download the source from:
https://sourceforge.net/projects/zprj/
Note: don't use the source in commercial products, since they are ported from WindShell. If you do want a shell in commercial fields, then you shall develop one with LEX/YACC.