Index: tcc4tcl.c ================================================================== --- tcc4tcl.c +++ tcc4tcl.c @@ -67,19 +67,23 @@ Tcl_Obj *sym_addr; static CONST char *options[] = { "add_include_path", "add_file", "add_library", "add_library_path", "add_symbol", "command", "compile", "define", "get_symbol", "output_file", "undefine", + "parse_args", (char *) NULL }; enum options { TCC4TCL_ADD_INCLUDE, TCC4TCL_ADD_FILE, TCC4TCL_ADD_LIBRARY, TCC4TCL_ADD_LIBRARY_PATH, TCC4TCL_ADD_SYMBOL, TCC4TCL_COMMAND, TCC4TCL_COMPILE, - TCC4TCL_DEFINE, TCC4TCL_GET_SYMBOL, TCC4TCL_OUTPUT_FILE, TCC4TCL_UNDEFINE + TCC4TCL_DEFINE, TCC4TCL_GET_SYMBOL, TCC4TCL_OUTPUT_FILE, TCC4TCL_UNDEFINE, + TCC4TCL_PARSE_ARGS }; char *str; int rv; + int tcc_argc; + char **tcc_argv; ts = (struct TclTCCState *) cdata; s = ts->s; if (objc < 2) { @@ -253,10 +257,26 @@ Tcl_WrongNumArgs(interp, 2, objv, "symbol"); return TCL_ERROR; } tcc_undefine_symbol(s,Tcl_GetString(objv[2])); return TCL_OK; + case TCC4TCL_PARSE_ARGS: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "args..."); + return TCL_ERROR; + } + + tcc_argc = objc - 2; + tcc_argv = (char **) ckalloc(sizeof(*tcc_argv) * (tcc_argc + 1)); + for (index = 0; index < tcc_argc; index++) { + tcc_argv[index] = Tcl_GetString(objv[index + 2]); + } + tcc_argv[tcc_argc] = NULL; + + tcc_parse_args(s, tcc_argc, tcc_argv); + + return(TCL_OK); default: Tcl_Panic("internal error during option lookup"); } return TCL_OK; } Index: tcc4tcl.tcl ================================================================== --- tcc4tcl.tcl +++ tcc4tcl.tcl @@ -44,11 +44,11 @@ } else { set type "package" } } - array set $handle [list code "" type $type filename $output package $pkgName add_inc_path "" add_lib_path "" add_lib "" add_macros ""] + array set $handle [list code "" type $type filename $output package $pkgName add_inc_path "" add_lib_path "" add_lib "" add_cmdline ""] proc $handle {cmd args} [string map [list @@HANDLE@@ $handle] { set handle {@@HANDLE@@} if {$cmd == "go"} { @@ -157,47 +157,14 @@ upvar #0 $handle state set state(tk) 1 } - proc _process_command_line {handle cmdStr} { - # XXX:TODO: This needs to handle shell-quoted arguments + proc _process_command_line {handle args} { upvar #0 $handle state - set cmdStr [regsub -all { *} $cmdStr { }] - set work [split $cmdStr " "] - - foreach cmd $work { - switch -glob -- $cmd { - "-I*" { - set dir [string range $cmd 2 end] - _add_include_path $handle $dir - } - "-D*" { - set symbolval [string range $cmd 2 end] - set symbolval [split $symbolval =] - set symbol [lindex $symbolval 0] - set val [join [lrange $symbolval 1 end] =] - - dict set state(add_macros) $symbol $val - } - "-U*" { - set symbol [string range $cmd 2 end] - dict unset state(add_macros) $symbol $val - } - "-l*" { - set library [string range $cmd 2 end] - _add_library $handle $library - } - "-L*" { - set libraryDir [string range $cmd 2 end] - _add_library_path $handle $libraryDir - } - "-g" { - # Ignored - } - } - } + + lappend state(add_cmdline) {*}$args } proc _delete {handle} { rename $handle "" unset $handle @@ -462,14 +429,10 @@ upvar #0 $handle state set code "" - foreach {macroName macroVal} $state(add_macros) { - append code "#define [string trim "$macroName $macroVal"]\n" - } - append code $state(code) "\n" if {$state(type) == "exe" || $state(type) == "dll"} { if {[info exists state(procs)] && [llength $state(procs)] > 0} { set code "int _initProcs(Tcl_Interp *interp);\n\n$code" @@ -567,10 +530,14 @@ if {[info command ::tcc4tcl] == ""} { return -code error "Unable to load tcc4tcl library" } ::tcc4tcl $dir $tcc_type tcc + + if {$state(add_cmdline) ne ""} { + tcc parse_args {*}$state(add_cmdline) + } foreach path $state(add_inc_path) { tcc add_include_path $path } Index: test.tcl ================================================================== --- test.tcl +++ test.tcl @@ -1,9 +1,9 @@ #! /usr/bin/env tclsh lappend auto_path [lindex $argv 0] -package require tcc4tcl +package require -exact tcc4tcl 0.0 tcc4tcl::cproc test {int i} int { return(i+42); } tcc4tcl::cproc test1 {int i} int { return(i+42); } tcc4tcl::cproc ::bob::test1 {int i} int { return(i+42); } @@ -235,7 +235,30 @@ critcl::cproc test14 {int x} int { return(x + test); } puts "Test14: [test14 3]" + +# Executable +close [file tempfile exe] +file delete -force -- $exe +set handle [tcc4tcl::new $exe] +$handle ccode { + #include + int main(int argc, char **argv) { + printf("hi\n"); + return(0); + } +} +$handle process_command_line -r +$handle go +set execCode [catch { + puts [exec ls -l $exe] + exec ld -o $exe.e $exe + puts [exec $exe.e] +} err] +file delete $exe +if {$execCode} { + error $err +} exit 0