Index: tcc4critcl.tcl ================================================================== --- tcc4critcl.tcl +++ tcc4critcl.tcl @@ -82,25 +82,63 @@ } proc $command args [list apply [list {handle command} $body] $handle $command] } -proc ::critcl::cheaders {header} { +proc ::critcl::cheaders {args} { set handle [::critcl::_allocateHandle] - $handle ccode "#include \"$header\"" + foreach arg $args { + unset -nocomplain includeDir + + if {[info exists nextArg]} { + set thisArg $nextArg + unset nextArg + set $thisArg $arg + } + + switch -glob -- $arg { + "-I" { + set nextArg "includeDir" + } + "-I*" { + set includeDir [string trim [string range $arg 2 end]] + } + } + + if {[info exists includeDir]} { + $handle add_include_path [file join $::critcl::dir $includeDir] + unset includeDir + continue + } + + foreach header [glob -tails -nocomplain -directory $::critcl::dir -- $arg] { + $handle add_include_path [file join $::critcl::dir [file dirname $header]] + $handle ccode "#include \"$header\"" + } + } } proc ::critcl::csources {file} { set handle [::critcl::_allocateHandle] + + if {![info exists ::critcl::csources]} { + set ::critcl::csources [list] + } # Locate file relative to current script - set file [file join $::critcl::dir $file] + foreach file [glob -nocomplain -directory $::critcl::dir -- $file] { + set fullFile [file normalize $file] + if {$fullFile in $::critcl::csources} { + continue + } + lappend ::critcl::csources $fullFile - set fd [open $file] - $handle ccode [read $fd] - close $fd + set fd [open $file] + $handle ccode [read $fd] + close $fd + } } proc ::critcl::cflags args { set handle [::critcl::_allocateHandle] $handle process_command_line [join $args " "] Index: tcc4tcl.tcl ================================================================== --- tcc4tcl.tcl +++ tcc4tcl.tcl @@ -86,10 +86,11 @@ upvar #0 $handle state set tclCommand [lookupNamespace $tclCommand] set cSymbol [cleanname [namespace tail $tclCommand]] + set cSymbol [cleanname $tclCommand] lappend state(procs) $tclCommand [list $cSymbol] foreach {clientData interp objc objv} $argList {} set cArgList "ClientData $clientData, Tcl_Interp *$interp, int $objc, Tcl_Obj *CONST $objv\[\]" @@ -467,10 +468,35 @@ variable dir upvar #0 $handle state set code "" + + if {$outputOnly} { + append code "#if 0\n" + set seenCLIPaths [list] + foreach path $state(add_inc_path) { + if {$path in $seenCLIPaths} { + continue + } + lappend seenCLIPaths $path + append code "CLI:-I${path}\n" + } + set seenCLIPaths [list] + foreach path $state(add_lib_path) { + if {$path in $seenCLIPaths} { + continue + } + lappend seenCLIPaths $path + append code "CLI:-L${path}\n" + } + unset seenCLIPaths + foreach path $state(add_lib) { + append code "CLI:-l${path}\n" + } + append code "#endif\n" + } foreach {macroName macroVal} $state(add_macros) { append code "#define [string trim "$macroName $macroVal"]\n" } @@ -531,11 +557,11 @@ set packageVersion "0" } append code "int [string totitle $packageName]_Init(Tcl_Interp *interp) \{\n" append code "#ifdef USE_TCL_STUBS\n" - append code " if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) \{\n" + append code " if (Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0) == 0L) \{\n" append code " return TCL_ERROR;\n" append code " \}\n" append code "#endif\n" if {[info exists state(procs)] && [llength $state(procs)] > 0} { @@ -642,11 +668,18 @@ unset $handle } } proc ::tcc4tcl::checkname {n} {expr {[regexp {^[a-zA-Z0-9_]+$} $n] > 0}} -proc ::tcc4tcl::cleanname {n} {regsub -all {[^a-zA-Z0-9_]+} $n _} +proc ::tcc4tcl::cleanname {n} { + set n [regsub -all {[^a-zA-Z0-9_]+} $n _] + if {[string index $n 0] eq "_"} { + set n "tcc4tcl${n}" + } + + return $n +} proc ::tcc4tcl::cproc {name adefs rtype {body "#"}} { set handle [::tcc4tcl::new] $handle cproc $name $adefs $rtype $body return [$handle go]