Reputation:
I have a simple c/c++ app that has an optional TCL interpreter with the function wrappers generated using SWIG. For several of the functions all the arguments are optional. How is this typically handled? I'd like to support a TCL command like this, where any of the arguments are optional but the C function takes fixed arguments:
//TCL command
get_list [options] filename
-opt1
-opt2
-opt3 arg1
-opt4 arg2
filename
//C function
static signed get_list(bool opt1,
bool opt2,
char * arg1,
objectType * arg2,
char * fileName)
Currently I have something like this:
static pList * get_list(char * arg1=NULL,
char * arg2=NULL,
char * arg3=NULL,
tObject * arg4=NULL)
This has many problems such as enforcing the object pointer is always the last argument. The SWIG documentation talks at length about C functions with variable arguments using "..." but I don't think this is what I need. I'd like the C function arguments to be fixed.
Upvotes: 2
Views: 912
Reputation: 137687
The easiest method is to wrap a Tcl procedure around the outside, like this:
rename get_list original.get_list
proc get_list args {
if {[llength $args] == 0 || [llength $args] % 2 == 0} {
error "wrong # args: ..."; # Do a proper error message here!
}
# Handle the required argument
set filename [lindex $args end]
# Initialize the defaults
array set opts {
-opt1 false
-opt2 false
-opt3 ""
-opt4 ""
}
# Merge in the supplied options
foreach {opt val} [lrange $args 0 end-1] {
if {![info exist opts($opt)]} {
error "unrecognized option \"$opt\""
}
set opts($opt) $value
}
# Hand off to C level...
original.get_list $opts(-opt1) $opts(-opt2) $opts(-opt3) $opts(-opt4) $filename
}
If you've got Tcl 8.6, that last handoff is best done with tailcall
so the rewriting code is cut out of the Tcl stack. It's not vital though, as SWIGged code rarely resolves names of Tcl commands and variables.
Upvotes: 2