From 16059fe56aaecbc0e7fc0abc7ce2069264c36765 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Thu, 25 Aug 2022 20:22:58 +0200 Subject: [PATCH 01/10] Add module support for tcc4tcl -Fix hook_proc to only note internal procs (not sourced ones) -Add support for tcc4tcl::tclwraps module scope interp --- tsp-packagehelper.tcl | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index 1d207cf..7edfcff 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -41,14 +41,22 @@ namespace eval ::tsp { # give name of save tcl source here, otherwise we use __lastsaved__.tcl variable ACTSOURCE "" + + variable _HOOK_LEVEL 0 } -proc ::tsp::hook_proc {} { +proc ::tsp::hook_proc {level} { # we hook the proc construct to get information about package defined procs + variable _HOOK_LEVEL + set _HOOK_LEVEL $level if {[info command ::__proc] eq ""} { rename ::proc ::__proc ::__proc ::proc {procName procargs procbody} { - lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody] + #puts "script [info script] [info level] [info frame]" + if {([info script] eq "")&&([info level]==$::tsp::_HOOK_LEVEL)} { + lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody] + #puts "Appending $procName" + } if {[catch {uplevel 0 ::__proc [list $procName $procargs $procbody]} err]} { rename ::proc "" rename ::__proc ::proc @@ -86,7 +94,7 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} catch { unset ::tsp::TCC_HANDLE} set ::tsp::TCC_HANDLE [tcc4tcl::new] - + set tcc4tcl::moduleName $packagename set ::tsp::PACKAGE_PROCS "" set ::tsp::PACKAGE_INIT_PROC 0 set ::tsp::TCL_PROCS "" @@ -112,7 +120,7 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} set ::tsp::LOAD_DLLS "" set ::tsp::EXTERNAL_DLLS "" - ::tsp::hook_proc + ::tsp::hook_proc [info level] } proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { @@ -402,7 +410,7 @@ proc ::tsp::write_pkgIndex {packagename} { catch {set tclpr $::tsp::TCL_PROCS} foreach tcldef $tclpr { lassign $tcldef cproc cvars cbody - puts $fd "# $cproc $cvars" + puts $fd [string map {\n "."} "# $cproc $cvars"] } set handle $::tsp::TCC_HANDLE set loadextlibs "proc ${packagename}_loadextdlls {dir} {\ncatch {\n" @@ -573,6 +581,7 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { if {$ctype==99} { puts "Debug Source" puts [$::tsp::TCC_HANDLE code] + puts "#--End of code---------------------" return 1 } From 21e5d4c8d2e99eb377d6536a65af36b87cb300e3 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Sat, 27 Aug 2022 10:31:52 +0200 Subject: [PATCH 02/10] Code cleaning --- tsp-packagehelper.tcl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index 7edfcff..f7c0db6 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -52,10 +52,8 @@ proc ::tsp::hook_proc {level} { if {[info command ::__proc] eq ""} { rename ::proc ::__proc ::__proc ::proc {procName procargs procbody} { - #puts "script [info script] [info level] [info frame]" if {([info script] eq "")&&([info level]==$::tsp::_HOOK_LEVEL)} { lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody] - #puts "Appending $procName" } if {[catch {uplevel 0 ::__proc [list $procName $procargs $procbody]} err]} { rename ::proc "" @@ -94,7 +92,7 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} catch { unset ::tsp::TCC_HANDLE} set ::tsp::TCC_HANDLE [tcc4tcl::new] - set tcc4tcl::moduleName $packagename + set ::tsp::PACKAGE_PROCS "" set ::tsp::PACKAGE_INIT_PROC 0 set ::tsp::TCL_PROCS "" @@ -581,7 +579,6 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { if {$ctype==99} { puts "Debug Source" puts [$::tsp::TCC_HANDLE code] - puts "#--End of code---------------------" return 1 } From 19e4b4284c27fc5a576f8b9f1c0f9b6c5a5ba50e Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Sat, 22 Oct 2022 18:40:22 +0200 Subject: [PATCH 03/10] Add basic support for array indexing supports the forms a(b) and a($b) preliminary, needs testing --- tsp-clang.tcl | 8 ++-- tsp-generate-set.tcl | 104 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 12 deletions(-) diff --git a/tsp-clang.tcl b/tsp-clang.tcl index 752701b..1c6461a 100755 --- a/tsp-clang.tcl +++ b/tsp-clang.tcl @@ -567,13 +567,14 @@ proc ::tsp::lang_assign_empty_zero {var type} { # proc ::tsp::lang_assign_var_array_idxvar {targetObj arrVar idxVar errMsg} { append result "/* ::tsp::lang_assign_var_array_idxvar */\n" - + append result "[::tsp::lang_safe_release $targetObj]" append result "$targetObj = Tcl_ObjGetVar2(interp, $arrVar, $idxVar, TCL_LEAVE_ERR_MSG);\n" append result "if ($targetObj == NULL) \{\n" append result " /* Tcl_AppendResult(interp, [::tsp::lang_quote_string $errMsg], (char *) NULL);*/\n" append result " *rc = TCL_ERROR;\n" append result " ERROR_EXIT;\n" append result "\}\n" + append result "[::tsp::lang_preserve $targetObj]" return $result } @@ -584,15 +585,14 @@ proc ::tsp::lang_assign_var_array_idxvar {targetObj arrVar idxVar errMsg} { # proc ::tsp::lang_assign_var_array_idxtext {targetObj arrVar idxTxtVar errMsg} { append result "/* ::tsp::lang_array_get_array_idxtext */\n" - + append result "[::tsp::lang_safe_release $targetObj]" append result "$targetObj = Tcl_ObjGetVar2(interp, $arrVar, $idxTxtVar, TCL_LEAVE_ERR_MSG);\n" append result "if ($targetObj == NULL) \{\n" append result " /* Tcl_AppendResult(interp, [::tsp::lang_quote_string $errMsg], (char *) NULL);*/\n" append result " *rc = TCL_ERROR;\n" append result " ERROR_EXIT;\n" append result "\}\n" - return $result - + append result "[::tsp::lang_preserve $targetObj]" return $result } diff --git a/tsp-generate-set.tcl b/tsp-generate-set.tcl index 8dea751..48bb7b0 100755 --- a/tsp-generate-set.tcl +++ b/tsp-generate-set.tcl @@ -671,18 +671,106 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam set sourceCmdRange [lindex $component 2] lassign [::tsp::parse_nestedbody compUnit $sourceCmdRange] sourceType sourceRhsVar sourceCode - if {$sourceCode eq ""} { - ::tsp::addError compUnit "assignment from nested command: no code generated: target \"$targetVarName\" " - return [list void "" ""] + if {$sourceCode eq ""} { + ::tsp::addError compUnit "assignment from nested command: no code generated: target \"$targetVarName\" " + return [list void "" ""] + } + + if {$sourceType eq "void"} { + ::tsp::addError compUnit "void assignment from nested command: target \"$targetVarName\"" + return [list void "" ""] } - - if {$sourceType eq "void"} { - ::tsp::addError compUnit "void assignment from nested command: target \"$targetVarName\"" - return [list void "" ""] - } append code $sourceCode append code [::tsp::gen_assign_scalar_scalar compUnit $tmp string $sourceRhsVar $sourceType ] } + text_array_idxvar - array_idxvar { + append code "//Parsing Array $compType in $component of $sourceComponents\n" + #::tsp::addWarning compUnit "$compType not implemented $component $sourceComponents" + #append code "// Parsing $component in $sourceComponents\n" + set tmp_s [::tsp::get_tmpvar compUnit string] + set doreturn 0 + + # assignment from native variable or var, possible type coersion + set sourceVarName [lindex $component 2] + #append code "// assignment |$sourceVarName| to $tmp_s\n" + set sourceType [::tsp::getVarType compUnit $sourceVarName] + if {$sourceType eq "undefined"} { + ::tsp::addError compUnit "set command arg 2 interpolated string variable not defined: \"$sourceVarName\"" + return [list ""] + } + append code [::tsp::gen_assign_scalar_scalar compUnit $tmp_s string $sourceVarName $sourceType] + + if {($compType=="array_idxvar")} { + #::tsp::addWarning compUnit "set arg 2 interpolated string cannot contain $compType as $component in $sourceComponents, only commands, text, backslash, or scalar variables" + set tmp_a [::tsp::get_tmpvar compUnit var tmp_array] + set tmp_v [::tsp::get_tmpvar compUnit var tmp_idx] + append code [::tsp::lang_assign_var_string $tmp_v $tmp_s] + # append code "// Convert array |$tmp_a| to $tmp\n" + append code [::tsp::lang_assign_var_array_idxvar $tmp_a [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 1]]] $tmp_v "Error loading Array Text"] + append code [::tsp::lang_convert_string_var $tmp $tmp_a] + } else { + set sourceText [lindex $sourceComponents 3] + if {$sourceText eq ""} { + append code "//Missing source in $sourceComponents\n" + continue + } else { + #::tsp::addWarning compUnit "set arg 2 interpolated string should not contain $compType as $sourceText in $sourceComponents, only commands, text, backslash, or scalar variables\n" + set newsource "[lindex $sourceComponents 1](" + #append code "// Convert |$newsource| to $tmp via $tmp_s\n" + append code [::tsp::lang_assign_string_const $tmp $newsource] + append code [::tsp::lang_append_string $tmp $tmp_s] + append code "Tcl_DStringAppend($tmp,\")\",-1);\n" + set doreturn 1 + } + } + if {$targetType eq "string"} { + #append code "// Append string |$tmp|\n" + append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + } elseif {$targetType eq "var"} { + #append code "// Append var |$tmp|\n" + append code [::tsp::lang_assign_var_string $targetVarName $tmp] + } + #append code [::tsp::lang_assign_empty_zero $tmp string] + if {$doreturn>0} { + append code "// exiting\n" + return $code + } + } + text_array_idxtext - array_idxtext { + append code "//Parsing Array $compType in $component of $sourceComponents\n" + set tmp_s [::tsp::get_tmpvar compUnit string] + set doreturn 0 + if {($compType=="array_idxtext")} { + #::tsp::addWarning compUnit "set arg 2 interpolated string cannot contain $compType as $component in $sourceComponents, only commands, text, backslash, or scalar variables" + set tmp_a [::tsp::get_tmpvar compUnit var tmp_array] + #append code "// Convert array |$tmp_a| to $tmp\n" + append code [::tsp::lang_assign_var_array_idxvar $tmp_a [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 1]]] [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 2]]] "Error loading Array Text"] + append code [::tsp::lang_convert_string_var $tmp $tmp_a] + } else { + set sourceText [lindex $sourceComponents 3] + if {$sourceText eq ""} { + append code "//Missing source in $sourceComponents\n" + continue + } else { + #::tsp::addWarning compUnit "set arg 2 interpolated string should not contain $compType as $sourceText in $sourceComponents, only commands, text, backslash, or scalar variables\n" + #append code "// Convert |$sourceText| to $tmp\n" + append code [::tsp::lang_assign_string_const $tmp $sourceText] + set doreturn 1 + } + } + if {$targetType eq "string"} { + #append code "// Append string |$tmp|\n" + append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + } elseif {$targetType eq "var"} { + #append code "// Append var |$tmp|\n" + append code [::tsp::lang_assign_var_string $targetVarName $tmp] + } + #append code [::tsp::lang_assign_empty_zero $tmp string] + if {$doreturn>0} { + append code "// exiting\n" + return $code + } + } default { ::tsp::addError compUnit "set arg 2 interpolated string cannot contain $compType, only commands, text, backslash, or scalar variables" return "" From 850be4687a30ffd453b6b1b0c8ca95d750149e50 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Fri, 7 Apr 2023 11:47:21 +0200 Subject: [PATCH 04/10] Changes affect only helper routines, not the TSP Core --- tcc4tcl_helper.tcl | 24 ++++++--- tsp-packagehelper.tcl | 114 +++++++++++++++++++++++++++--------------- 2 files changed, 90 insertions(+), 48 deletions(-) diff --git a/tcc4tcl_helper.tcl b/tcc4tcl_helper.tcl index 0bdc72b..bd8e523 100644 --- a/tcc4tcl_helper.tcl +++ b/tcc4tcl_helper.tcl @@ -163,7 +163,7 @@ proc ::tcc4tcl::analyse_includes {handle {prefix ""}} { set prefix $::tccenv::pathprefix/ } set prefix1 ${prefix}lib/ - set prefix2 ${prefix}lib/tcc4tcl-0.30/ + set prefix2 ${prefix}lib/tcc4tcl/ foreach path $usedpath { set shortpath [string map [list $prefix ""] $path] @@ -264,7 +264,8 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { # $exeFile cc to execute # $compilertype can be gccwin32/gcclin64/tccwin32/tcclin64/user and defines prebuilt ccOptions to use; set to user to have no predefined options puts "Making Directives for $filepath ($::tccenv::tccmaindir)" - set pathway [::tcc4tcl::analyse_includes $handle] + set pathway "" + catch {set pathway [::tcc4tcl::analyse_includes $handle]} set includestccwin32 "-Iinclude -Iinclude/stdinc -Iinclude/generic -Iinclude/generic/win -Iinclude/xlib -Iwin32 -Iwin32/winapi " set includesgccwin32 "-Iinclude -Iinclude/generic -Iinclude/generic/win -Iinclude/xlib" set includestcclin64 "-Iinclude -Iinclude/stdinc -Iinclude/generic -Iinclude/generic/unix -Iinclude/xlib " @@ -272,15 +273,15 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { set includesuser "" set librariestccwin32 "-ltclstub86elf -ltkstub86elf" - set librariestcclin64 "-ltclstub86elf -ltkstub86elf" + set librariestcclin64 "-ltclstub86_64 -ltkstub86_64" set librariesgccwin32 "-Llib -ltclstub86 -ltkstub86" set librariesgcclin64 "-Llib -ltclstub86_64 -ltkstub86_64" set librariesuser "" set ccoptionstccwin32 "-m32 -D_WIN32 " set ccoptionsgccwin32 "-s -m32 -D_WIN32 -static-libgcc " - set ccoptionstcclin64 "" - set ccoptionsgcclin64 "-s -fPIC -D_GNU_SOURCE " + set ccoptionstcclin64 {-Wl,-rpath='.'} + set ccoptionsgcclin64 {-s -fPIC -D_GNU_SOURCE -Wl,-rpath=. } set ccoptionstccuser "" @@ -296,8 +297,14 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { set libraries_addon "" lappend libraries_addon "-Llib" + set libps "" + set libs "" + set opts "" + catch { set libps [$handle add_library_path] set libs [$handle add_library] + set opts [$handle add_options] + } foreach inclib $libs { lappend libraries_addon "-l$inclib" } @@ -342,9 +349,10 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { set ccpath [file join $exeDir $exeFile] append ccoptions " -shared -DUSE_TCL_STUBS -O2" append ccOptions " $ccoptions" + append ccOptions " [join $opts { }]" - puts "Directive for $compiler" - puts "$ccpath $ccOptions $includes $includes_generic $cfile -o$ofile $libraries" + #puts "Directive for $compiler" + #puts "$ccpath $ccOptions $includes $includes_generic $cfile -o$ofile $libraries" lappend ccdirectives $compiler "$ccpath $ccOptions $includes $includes_generic $cfile -o$ofile $libraries" } return $ccdirectives @@ -406,7 +414,7 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) #else -# define DLLIMPORT __attribute__(dllimport) +# define DLLIMPORT # if defined(__GNUC__) && __GNUC__ > 3 # define DLLEXPORT __attribute__ ((visibility(\"default\"))) # else diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index f7c0db6..e40e358 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -212,18 +212,25 @@ proc ::tsp::add_dllinclude {fname} { lappend ::tsp::EXTERNAL_DLLS $fname } -proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_866_3.upx.exe"}} { - # ok, now things really get difficult, if the directory structure doesn't work +proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_8.6.12.exe"}} { + # ok, now things really get difficult, if the directory structure doesn't work "./tclkit_866_3.upx.exe" # this actually only works under windows, you need a tclkit named $shell in the current working dir set result "failed testloading package $packagename" set callresult "" + set packagedir [file dir $packagename] + set packagename [file tail $packagename] puts "Testing package $packagename" if {[catch { puts "Creating new exec" set fd [open resrc.tcl w] - puts "appending auto_path with [file dir $tsp::PACKAGE_DIR]" + puts $fd "#!/usr/bin/tclsh" puts $fd "catch {console show}" + puts "appending auto_path with [file dir $tsp::PACKAGE_DIR]" puts $fd "lappend auto_path [file dir $tsp::PACKAGE_DIR]" + if {[file dir $tsp::PACKAGE_DIR] ne $packagedir} { + puts "appending auto_path with $packagedir" + puts $fd "lappend auto_path $packagedir" + } puts "Loading package... $packagename" puts $fd "package require $packagename" @@ -238,43 +245,56 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_866_3.upx.e puts "Go" # shell actually hardcoded... todo implement some clever routine to find nearest kit - - if {[catch { - if {![file exists $shell]} { - puts "Shell not found $shell... searching" - # mark your shells as tclkit-8.6.6.exe to get found 866 8-6-6 all will do - # this will search for 8.6.6 shell - # or at least any 8.6 shell - set flist [glob tclkit*.exe] - set cand "" - foreach kit $flist { - set vnum [join [regexp -all -inline "\[0-9\]" $kit]] - set vstring2 [join [lrange $vnum 0 1] "."] - set vstring3 [join [lrange $vnum 0 2] "."] - if {$vstring2 eq "8.6"} { - lappend cand $kit $vstring3 + # and to run under linux + if {$::tcl_platform(platform)=="unix"} { + puts "Seems to be a native linux, calling tclsh" + #exec >@stdout tclsh resrc.tcl + # solution: + set runcmd [list exec tclsh resrc.tcl 2>@stderr] + + if {[catch $runcmd res]} { + error "Failed to run command $runcmd: $res" + } + + puts $res + } else { + if {[catch { + if {![file exists $shell]} { + puts "Shell not found $shell... searching" + # mark your shells as tclkit-8.6.6.exe to get found 866 8-6-6 all will do + # this will search for 8.6.6 shell + # or at least any 8.6 shell + set flist [glob tclkit*.exe] + set cand "" + foreach kit $flist { + set vnum [join [regexp -all -inline "\[0-9\]" $kit]] + set vstring2 [join [lrange $vnum 0 1] "."] + set vstring3 [join [lrange $vnum 0 2] "."] + if {$vstring2 eq "8.6"} { + lappend cand $kit $vstring3 + } + if {$vstring3 eq "8.6.6"} { + # found an 866, use it + set shell $kit + puts "found $shell" + break; + } } - if {$vstring3 eq "8.6.6"} { - # found an 866, use it - set shell $kit - puts "found $shell" - break; + if {[llength $cand]==0} { + puts "Error: Shell not found" + return } + set cand [lsort -decreasing -stride 2 $cand] + puts "Candidates $cand" + set shell [lindex $cand 0] + puts "using $shell" + } - if {[llength $cand]==0} { - puts "Error: Shell not found" - return - } - set cand [lsort -decreasing -stride 2 $cand] - puts "Candidates $cand" - set shell [lindex $cand 0] - puts "using $shell" - - } - exec $shell resrc.tcl & - } err]} { - puts "Error while preparing package $packagename\n$err" + exec $shell resrc.tcl & + } err]} { + puts "Error while preparing package $packagename\n$err" } + } return } @@ -359,14 +379,20 @@ proc ::tsp::rewrite_procnamespace {} { foreach {procname cprocname} $state(procs) { if {[lsearch $::tsp::PACKAGE_PROCS [namespace tail $procname]]<0} { # pure c implemented... there will be no valid TCL representation - set procdef [list $procname "args" [list puts "Not implemented \"$procname\""]] - lappend ::tsp::PACKAGE_PROCS $procname $procdef + ##set procdef [list $procname "args" [list puts "Not implemented \"$procname\""]] + ##lappend ::tsp::PACKAGE_PROCS $procname $procdef set cdef [dict get $state(procdefs) $procname] lassign $cdef cprocname rtype cprocargs set procargs "" + set procargsfull "" foreach {ctype vname} $cprocargs { lappend procargs $ctype + if {$vname!= "interp"} { + lappend procargsfull $vname + } } + set procdef [list $procname "$procargsfull" [list puts "Not implemented \"$procname\""]] + lappend ::tsp::PACKAGE_PROCS $procname $procdef #lappend ::tsp::COMPILED_PROCS $procname [list $rtype $procargs $cprocname] } } @@ -412,7 +438,12 @@ proc ::tsp::write_pkgIndex {packagename} { } set handle $::tsp::TCC_HANDLE set loadextlibs "proc ${packagename}_loadextdlls {dir} {\ncatch {\n" - append loadextlibs {set appdir [file dir [info nameofexecutable]]} + append loadextlibs { + switch -- $::tcl_platform(platform) { + windows {set appdir [file dir [info nameofexecutable]]} + unix {set appdir [file dir [info script]]} + } + } append loadextlibs "\n" set libs [$handle add_library] @@ -421,6 +452,9 @@ proc ::tsp::write_pkgIndex {packagename} { lappend libs {*}$::tsp::EXTERNAL_DLLS } foreach incpath $libs { + if {![file exists [file join $tsp::PACKAGE_DIR $incpath[info sharedlibextension]]]} { + set incpath lib$incpath + } append loadextlibs "\nset incdll \[file join \$dir $incpath\[info sharedlibextension\]\]\n" append loadextlibs "set appdll \[file join \$appdir $incpath\[info sharedlibextension\]\]\n" append loadextlibs "if {!\[file exists \$appdll\]} {\n" @@ -611,7 +645,7 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { puts "Compiling external $cdirect" set ::errorCode "" catch { - eval exec $cdirect + exec {*}$cdirect } err cd $wd puts "Result:\n$err\n" From 4c5315d6a896336ddeafd5f260582437c0926b26 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Mon, 2 Dec 2024 22:09:04 +0100 Subject: [PATCH 05/10] Some small changes, bugfixes and additional features --- tcc4tcl_helper.tcl | 37 ++++++----- tsp-clang.tcl | 10 ++- tsp-compile.tcl | 2 + tsp-expr.tcl | 2 +- tsp-generate-math.tcl | 1 - tsp-generate-set.tcl | 31 ++++++--- tsp-packagehelper.tcl | 150 +++++++++++++++++++++++++++++------------- tsp-types.tcl | 3 +- 8 files changed, 159 insertions(+), 77 deletions(-) diff --git a/tcc4tcl_helper.tcl b/tcc4tcl_helper.tcl index bd8e523..f8759f5 100644 --- a/tcc4tcl_helper.tcl +++ b/tcc4tcl_helper.tcl @@ -1,6 +1,6 @@ package provide tcc4tcl_helper 0.1 -namespace eval tccenv { +namespace eval ::tccenv { # some common envelope vars for our ide # this tries to analyze the surrounding dirs # to find a suitable external compiler @@ -30,6 +30,23 @@ namespace eval tccenv { variable EXTERNAL_COMPILERS "" variable CC_DIRECTIVES "" + variable DLEXPORTMAKRO " +/***************** DLL EXPORT MAKRO FOR TCC AND GCC ************/ +#if (defined(_WIN32) && (defined(_MSC_VER)|| defined(__TINYC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec)))) +#undef DLLIMPORT +#undef DLLEXPORT +# define DLLIMPORT __declspec(dllimport) +# define DLLEXPORT __declspec(dllexport) +#else +# define DLLIMPORT +# if defined(__GNUC__) && __GNUC__ > 3 +# define DLLEXPORT __attribute__ ((visibility(\"default\"))) +# else +# define DLLEXPORT +# endif +#endif +/***************************************************************/ +" # the following routines try to find tcc.exe and gcc.exe under win32 and set the tccenv vars accordingly @@ -406,23 +423,7 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers } } - set DLEXPORTMAKRO " -/***************** DLL EXPORT MAKRO FOR TCC AND GCC ************/ -#if (defined(_WIN32) && (defined(_MSC_VER)|| defined(__TINYC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec)))) -#undef DLLIMPORT -#undef DLLEXPORT -# define DLLIMPORT __declspec(dllimport) -# define DLLEXPORT __declspec(dllexport) -#else -# define DLLIMPORT -# if defined(__GNUC__) && __GNUC__ > 3 -# define DLLEXPORT __attribute__ ((visibility(\"default\"))) -# else -# define DLLEXPORT -# endif -#endif -/***************************************************************/ -" + set DLEXPORTMAKRO $::tccenv::DLEXPORTMAKRO upvar #0 $handle state set oldtype "package" if {$state(type)!="package"} { diff --git a/tsp-clang.tcl b/tsp-clang.tcl index 1c6461a..f7a4f5d 100755 --- a/tsp-clang.tcl +++ b/tsp-clang.tcl @@ -134,6 +134,7 @@ proc ::tsp::lang_type_null {} { # declare a native boolean # proc ::tsp::lang_decl_native_boolean {varName} { + return "int $varName;\n" return "int $varName = 0;\n" } @@ -141,6 +142,7 @@ proc ::tsp::lang_decl_native_boolean {varName} { # declare a native int # proc ::tsp::lang_decl_native_int {varName} { + return "Tcl_WideInt $varName;\n" return "Tcl_WideInt $varName = 0;\n" } @@ -148,6 +150,7 @@ proc ::tsp::lang_decl_native_int {varName} { # declare a native double # proc ::tsp::lang_decl_native_double {varName} { + return "double $varName;\n" return "double $varName = 0;\n" } @@ -1161,7 +1164,7 @@ proc ::tsp::lang_create_compilable {compUnitDict code} { lassign $proc_info procType procArgTypes procRef if {$procType eq "void"} { - set procNativeType "" + set procNativeType "void" } else { set procNativeType "[::tsp::lang_xlate_native_type $procType] " } @@ -1232,10 +1235,11 @@ TSP_UserDirect_${name}(Tcl_Interp* interp, int* rc $nativeTypedArgs ) { int idx2; char* str1; char* str2; - char* exprErrMsg = NULL; + char* exprErrMsg ; + Tcl_Obj* _tmpVar_cmdResultObj = NULL; - Tcl_CallFrame* frame = NULL; + Tcl_CallFrame* frame; $returnVarDecl [::tsp::indent compUnit $argObjvArrays 1 \n] diff --git a/tsp-compile.tcl b/tsp-compile.tcl index 176272b..f5ca5da 100755 --- a/tsp-compile.tcl +++ b/tsp-compile.tcl @@ -88,6 +88,7 @@ proc ::tsp::compile_proc {file name procargs body} { set errInf "" set rc [ catch {set compileResult [::tsp::parse_body compUnit {0 end}] } errInf] if {$rc != 0} { + catch {puts [join [dict get $compUnit errors] \n]} error "tsp internal error: parse_body error: $errInf" } @@ -110,6 +111,7 @@ proc ::tsp::compile_proc {file name procargs body} { # reparse set rc [ catch {set compileResult [::tsp::parse_body compUnit {0 end}] } errInf] if {$rc != 0} { + catch {puts [join [dict get $compUnit errors] \n]} error "tsp internal error: parse_body error: $errInf" } diff --git a/tsp-expr.tcl b/tsp-expr.tcl index 1f7c908..d4db30e 100755 --- a/tsp-expr.tcl +++ b/tsp-expr.tcl @@ -587,7 +587,7 @@ proc ::tsp::produce_subexpr {compUnitDict expr tree} { set type [::tsp::getVarType compUnit $thingtext] set idx [lsearch -exact $::tsp::EXPR_TYPES $type] if {$idx == -1} { - error "variable \"$thingtext\" not type of boolean, int, double, or string: \"$type\" in expression: $nodeexpr" + error "subex variable \"$thingtext\" not type of boolean, int, double, or string: \"$type\" in expression: $nodeexpr" } # NOTE that we change the variable for native compilation by prefixing with "__" set pre [::tsp::var_prefix $thingtext] diff --git a/tsp-generate-math.tcl b/tsp-generate-math.tcl index 4f50a85..491acfd 100755 --- a/tsp-generate-math.tcl +++ b/tsp-generate-math.tcl @@ -16,7 +16,6 @@ proc ::tsp::gen_command_expr {compUnitDict tree} { # just get raw text from body set rawtext [::tsp::parse_getstring compUnit [lindex $tree 1]] - if { [string range $rawtext 0 0] ne "\{"} { ::tsp::addError compUnit "expr argument not a braced expression" return [list void "" ""] diff --git a/tsp-generate-set.tcl b/tsp-generate-set.tcl index 48bb7b0..e01392b 100755 --- a/tsp-generate-set.tcl +++ b/tsp-generate-set.tcl @@ -67,7 +67,7 @@ proc ::tsp::gen_command_set {compUnitDict tree} { } set targetStr [parse getstring $body [lindex [lindex $tree 1] 1]] set sourceStr [parse getstring $body [lindex [lindex $tree 2] 1]] - + #puts "set $targetStr $sourceStr " # check target, should be a single text, text_array_idxtext, or text_array_idxvar set targetComponents [::tsp::parse_word compUnit [lindex $tree 1]] set firstType [lindex [lindex $targetComponents 0] 0] @@ -390,7 +390,7 @@ proc ::tsp::produce_set {compUnitDict tree targetComponents sourceComponents} { # generate assignment # mostly same as a scalar from scalar assignment set sourceVarName $sourceRhsVar - append result "\n/***** ::tsp::generate_set assign from command */\n" + append result "\n/***** ::tsp::generate_set assign from command (set $targetVarName = $sourceVarName) */\n" append code $sourceCode set targetType [::tsp::gen_check_target_var compUnit $targetVarName $targetType $sourceType] if {$targetType eq "ERROR"} { @@ -640,7 +640,8 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam set targetPre [::tsp::var_prefix $targetVarName] append result "\n/***** ::tsp::gen_assign_var_string_interpolated_string */\n" - + + set tmp [::tsp::get_tmpvar compUnit string] set tmp2 "" set arrVar "" @@ -648,6 +649,13 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam set tmp2 [::tsp::get_tmpvar compUnit string] append result [::tsp::lang_assign_empty_zero $tmp2 string] } + # fix: why is this not reset? + if {$targetType eq "string"} { + if {$targetPre!=""} { + append result "Tcl_DStringSetLength($targetPre$targetVarName,0);\n" + } + } + foreach component $sourceComponents { set compType [lindex $component 0] switch $compType { @@ -684,6 +692,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam append code [::tsp::gen_assign_scalar_scalar compUnit $tmp string $sourceRhsVar $sourceType ] } text_array_idxvar - array_idxvar { + puts "//Parsing Array $compType in $component of $sourceComponents\n" append code "//Parsing Array $compType in $component of $sourceComponents\n" #::tsp::addWarning compUnit "$compType not implemented $component $sourceComponents" #append code "// Parsing $component in $sourceComponents\n" @@ -705,8 +714,8 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam set tmp_a [::tsp::get_tmpvar compUnit var tmp_array] set tmp_v [::tsp::get_tmpvar compUnit var tmp_idx] append code [::tsp::lang_assign_var_string $tmp_v $tmp_s] - # append code "// Convert array |$tmp_a| to $tmp\n" - append code [::tsp::lang_assign_var_array_idxvar $tmp_a [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 1]]] $tmp_v "Error loading Array Text"] + #append code "// Convert array |$tmp_a| to $tmp\n" + append code [::tsp::lang_assign_var_array_idxvar $tmp_a [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 1]]] $tmp_v "Error loading Array Text"] append code [::tsp::lang_convert_string_var $tmp $tmp_a] } else { set sourceText [lindex $sourceComponents 3] @@ -724,7 +733,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } } if {$targetType eq "string"} { - #append code "// Append string |$tmp|\n" + #append code "// Append string 727 |$tmp|\n" append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] } elseif {$targetType eq "var"} { #append code "// Append var |$tmp|\n" @@ -732,7 +741,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } #append code [::tsp::lang_assign_empty_zero $tmp string] if {$doreturn>0} { - append code "// exiting\n" + #append code "// exiting\n" return $code } } @@ -759,8 +768,11 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } } if {$targetType eq "string"} { - #append code "// Append string |$tmp|\n" - append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + #append code "// Append string 763 |$tmp|\n" + ##???append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + ### deleted this output 23-Oct 20, since it produced continuosly double output with + ### Line 781 string case + #append code "// ok;\n" } elseif {$targetType eq "var"} { #append code "// Append var |$tmp|\n" append code [::tsp::lang_assign_var_string $targetVarName $tmp] @@ -777,6 +789,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } } if {$targetType eq "string"} { + append code "// Append string 781 |$tmp|\n" append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] } elseif {$targetType eq "var"} { append code [::tsp::lang_append_string $tmp2 $tmp] diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index e40e358..c22cccb 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -7,7 +7,7 @@ # PACKAGENAME_tsp_YYYY-MM-DD-hh-mm-ss.tcl (with tsp directives to create package) # pkgIndex.tcl # PACKAGENAME.puretcl.tcl (Untouched, pure TCL procs) -# PACKAGENAME.tclorig.tcl (TCL Replacment procs) +# PACKAGENAME.tclprocs.tcl (TCL Replacment procs) # PACKAGENAME.c (sourcecode, final) # PACKAGENAME.dll (binary file) # @@ -29,6 +29,7 @@ namespace eval ::tsp { variable PACKAGE_NAME "" variable PACKAGE_VERSION "1.0" variable PACKAGE_DIR "" + variable TSPPACKAGE_SPACE [file normalize [file dirname [info script]]] variable TCL_VERSION "TCL_VERSION" variable TCL_PROCS "" # load tcls for additional sources @@ -49,9 +50,11 @@ proc ::tsp::hook_proc {level} { # we hook the proc construct to get information about package defined procs variable _HOOK_LEVEL set _HOOK_LEVEL $level + #puts "Hooking proc $level" if {[info command ::__proc] eq ""} { rename ::proc ::__proc ::__proc ::proc {procName procargs procbody} { + #puts "Hook hit $procName in -[info script]- lv [info level]==$::tsp::_HOOK_LEVEL ?" if {([info script] eq "")&&([info level]==$::tsp::_HOOK_LEVEL)} { lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody] } @@ -150,7 +153,7 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { } else { set ::tsp::COMPILE_DIRECTIVES [::tcc4tcl::write_packagecode $::tsp::TCC_HANDLE $::tsp::PACKAGE_NAME $tsp::PACKAGE_DIR $::tsp::PACKAGE_VERSION $::tsp::TCL_VERSION] } - } + } ::tsp::write_pkgAltTcl $::tsp::PACKAGE_NAME ::tsp::write_pkgIndex $::tsp::PACKAGE_NAME @@ -174,8 +177,17 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { } ::tsp::compile_package $::tsp::PACKAGE_NAME $compiler + # pkginit? + if {$::tsp::PACKAGE_INIT_PROC>0} { + if {$compiler in "intern memory"} { + if {[catch {${::tsp::PACKAGE_NAME}_pkgInit} e]} { + puts "error: $e" + } + } + } set ::tsp::COMPILE_PACKAGE 0 set ::tsp::PACKAGE_NAME "" + } proc ::tsp::addExternalCompiler {compiler ccOptions exeDir exeFile {compilertype gccwin32}} { @@ -212,25 +224,29 @@ proc ::tsp::add_dllinclude {fname} { lappend ::tsp::EXTERNAL_DLLS $fname } -proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_8.6.12.exe"}} { +proc ::tsp::test_packageX {packagename {callcmd ""} {shell "tclkit_8.6.12.exe"}} { # ok, now things really get difficult, if the directory structure doesn't work "./tclkit_866_3.upx.exe" # this actually only works under windows, you need a tclkit named $shell in the current working dir - set result "failed testloading package $packagename" + set result "failed testloading package $packagename in [pwd]" set callresult "" set packagedir [file dir $packagename] set packagename [file tail $packagename] - puts "Testing package $packagename" + puts "Testing package $packagename in [pwd]" if {[catch { puts "Creating new exec" - set fd [open resrc.tcl w] + set res_name [file normalize resrc.tcl] + set fd [open $res_name w] puts $fd "#!/usr/bin/tclsh" puts $fd "catch {console show}" - puts "appending auto_path with [file dir $tsp::PACKAGE_DIR]" - puts $fd "lappend auto_path [file dir $tsp::PACKAGE_DIR]" + puts "appending auto_path with [file normalize [file dir $tsp::PACKAGE_DIR]]" + puts $fd "lappend auto_path [file normalize [file dir $tsp::PACKAGE_DIR]]" + puts "Testing for [file dir $tsp::PACKAGE_DIR] ne $packagedir" if {[file dir $tsp::PACKAGE_DIR] ne $packagedir} { puts "appending auto_path with $packagedir" puts $fd "lappend auto_path $packagedir" } + puts "Appending $tsp::TSPPACKAGE_SPACE" + puts $fd "lappend auto_path $tsp::TSPPACKAGE_SPACE" puts "Loading package... $packagename" puts $fd "package require $packagename" @@ -247,11 +263,12 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_8.6.12.exe" # shell actually hardcoded... todo implement some clever routine to find nearest kit # and to run under linux if {$::tcl_platform(platform)=="unix"} { - puts "Seems to be a native linux, calling tclsh" + puts "Seems to be a native linux, calling tclsh $res_name" #exec >@stdout tclsh resrc.tcl # solution: - set runcmd [list exec tclsh resrc.tcl 2>@stderr] - + set runcmd "exec tclsh \"$res_name\" 2>@stderr" + #" + puts "running $runcmd" if {[catch $runcmd res]} { error "Failed to run command $runcmd: $res" } @@ -264,10 +281,15 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_8.6.12.exe" # mark your shells as tclkit-8.6.6.exe to get found 866 8-6-6 all will do # this will search for 8.6.6 shell # or at least any 8.6 shell - set flist [glob tclkit*.exe] + set flist [glob -nocomplain tclkit*.exe] + if {[llength $flist]==0} { + puts "Shell not found in ./ ... searching $::tccenv::tclexedir" + set flist [glob -nocomplain [file join $::tccenv::tclexedir tclkit*.exe]] + puts $flist + } set cand "" foreach kit $flist { - set vnum [join [regexp -all -inline "\[0-9\]" $kit]] + set vnum [join [regexp -all -inline "\[0-9\]" [file tail $kit]]] set vstring2 [join [lrange $vnum 0 1] "."] set vstring3 [join [lrange $vnum 0 2] "."] if {$vstring2 eq "8.6"} { @@ -290,7 +312,7 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "./tclkit_8.6.12.exe" puts "using $shell" } - exec $shell resrc.tcl & + exec $shell $res_name & } err]} { puts "Error while preparing package $packagename\n$err" } @@ -381,18 +403,20 @@ proc ::tsp::rewrite_procnamespace {} { # pure c implemented... there will be no valid TCL representation ##set procdef [list $procname "args" [list puts "Not implemented \"$procname\""]] ##lappend ::tsp::PACKAGE_PROCS $procname $procdef - set cdef [dict get $state(procdefs) $procname] - lassign $cdef cprocname rtype cprocargs - set procargs "" - set procargsfull "" - foreach {ctype vname} $cprocargs { - lappend procargs $ctype - if {$vname!= "interp"} { - lappend procargsfull $vname + catch { + set cdef [dict get $state(procdefs) $procname] + lassign $cdef cprocname rtype cprocargs + set procargs "" + set procargsfull "" + foreach {ctype vname} $cprocargs { + lappend procargs $ctype + if {$vname!= "interp"} { + lappend procargsfull $vname + } } + set procdef [list $procname "$procargsfull" [list puts "Not implemented \"$procname\""]] + lappend ::tsp::PACKAGE_PROCS $procname $procdef } - set procdef [list $procname "$procargsfull" [list puts "Not implemented \"$procname\""]] - lappend ::tsp::PACKAGE_PROCS $procname $procdef #lappend ::tsp::COMPILED_PROCS $procname [list $rtype $procargs $cprocname] } } @@ -411,31 +435,47 @@ proc ::tsp::rewrite_procnamespace {} { set state(procs) $nsprocs } -proc ::tsp::write_pkgIndex {packagename} { - # write a pkindex.tcl file to load package - if {$tsp::PACKAGE_DIR eq ""} { - set filename [file join $tsp::PACKAGE_DIR "$packagename.pkgIndex.tcl"] - } else { - set filename [file join $tsp::PACKAGE_DIR "pkgIndex.tcl"] - } - set fd [open $filename w] - puts $fd "# Package Index for $packagename generated by TSP//TCCIDE Version $::_version" - puts $fd "# Compiled Procs " - puts $fd "" +proc ::tsp::getProcIndex {packagename} { + # + set helpindex "" + lappend helpindex "# Help Index:" + lappend helpindex "# Generated at [set t [clock format [clock seconds] -format "%Y-%m-%d_%H-%M-%S"]]" + lappend helpindex "# Package Index/Loader for $packagename generated by TSP//TCCIDE Version $::_version" + lappend helpindex "" + lappend helpindex "# Compiled Procs " + lappend helpindex "" set cpr {} catch {set cpr $::tsp::PACKAGE_PROCS} foreach {procname procdef} $cpr { lassign $procdef cproc cvars cbody - puts $fd "# ${::tsp::PACKAGE_NAMESPACE}::$cproc $cvars" + lappend helpindex "# ${::tsp::PACKAGE_NAMESPACE}::$cproc $cvars" } - puts $fd "\n# TCL Procs " - puts $fd "" + lappend helpindex "" + lappend helpindex "# TCL Procs " + lappend helpindex "" set tclpr {} catch {set tclpr $::tsp::TCL_PROCS} foreach tcldef $tclpr { lassign $tcldef cproc cvars cbody - puts $fd [string map {\n "."} "# $cproc $cvars"] + lappend helpindex [string map {\n "."} "# $cproc $cvars"] + } + return [join $helpindex \n] +} + +proc ::tsp::write_pkgIndex {packagename} { + # write a pkgindex.tcl file to load package + if {$tsp::PACKAGE_DIR eq ""} { + set filename [file join $tsp::PACKAGE_DIR "$packagename.pkgIndex.tcl"] + set loadername [file join $tsp::PACKAGE_DIR "$packagename.${packagename}.loader.tcl"] + } else { + set filename [file join $tsp::PACKAGE_DIR "pkgIndex.tcl"] + set loadername [file join $tsp::PACKAGE_DIR "${packagename}.loader.tcl"] } + + set fd [open $loadername w] + + puts $fd [::tsp::getProcIndex $packagename] + set handle $::tsp::TCC_HANDLE set loadextlibs "proc ${packagename}_loadextdlls {dir} {\ncatch {\n" append loadextlibs { @@ -468,17 +508,19 @@ proc ::tsp::write_pkgIndex {packagename} { } set pkgloadlib "proc ${packagename}_loadlib {dir packagename} {\n" - if {$loadextlibs ne ""} { + if {($loadextlibs ne "")} { append pkgloadlib " ${packagename}_loadextdlls \$dir\n" + } + if {($loadextlibs ne "")||($::tsp::LOAD_DLLS ne "")} { append pkgloadlib " ${packagename}_loadext \$dir\n" } - if {$cpr ne ""} { + if {$::tsp::PACKAGE_PROCS ne ""} { append pkgloadlib " if {\[catch {load \[file join \$dir \$packagename\[info sharedlibextension\]\]} err\]} {\n" append pkgloadlib " source \[file join \$dir \${packagename}.tclprocs.tcl\]\n" append pkgloadlib " }\n" } - if {$tclpr ne ""} { + if {$::tsp::TCL_PROCS ne ""} { # load puretcl proc also append pkgloadlib " source \[file join \$dir \${packagename}.puretcl.tcl\]\n" if {$::tsp::PACKAGE_INIT_PROC>0} { @@ -501,19 +543,39 @@ proc ::tsp::write_pkgIndex {packagename} { } append pkgloadext "}\n" - - set pkgrun "package ifneeded $packagename $::tsp::PACKAGE_VERSION \[list ${packagename}_loadlib \$dir {$packagename}\]\n" + set pkgrun "#run loader here\n${packagename}_loadlib \[file dir \[info script\]\] {$packagename}\n" puts $fd $loadextlibs puts $fd $pkgloadlib puts $fd $pkgloadext puts $fd $pkgrun close $fd + + set fd [open $filename w] + + set pkgrun "package ifneeded $packagename $::tsp::PACKAGE_VERSION \[list source \[file join \$dir [file tail $loadername]\]\]" + puts $fd $pkgrun + close $fd } proc ::tsp::write_pkgAltTcl {packagename} { # write an tcl file to keep all procs as alternate to compiled procs (can't load) # and those procs, that we didn't compile + + # add a little help function + if {$::tsp::PACKAGE_NAMESPACE eq ""} { + set help_proc ${packagename}_help + } else { + set help_proc ${::tsp::PACKAGE_NAMESPACE}::help + } + + set help_body " puts {\n" + append help_body [::tsp::getProcIndex $packagename] + append help_body "\n}\n" + set help_procdef [list $help_proc "" $help_body] + + lappend ::tsp::TCL_PROCS $help_procdef + set filename [file join $tsp::PACKAGE_DIR "$packagename.tclprocs.tcl"] set fd [open $filename w] puts $fd "# TSP Pure TCL procs for loadlib failure management" diff --git a/tsp-types.tcl b/tsp-types.tcl index 0feb50a..65d383c 100755 --- a/tsp-types.tcl +++ b/tsp-types.tcl @@ -492,7 +492,8 @@ proc ::tsp::reset_tmpvarsUsed {compUnitDict} { proc ::tsp::get_tmpvar {compUnitDict type {varName ""}} { upvar $compUnitDict compUnit - + #set callerlevel [expr [info level]-1] + #puts "tempvar $type requested from $callerlevel: [info level $callerlevel]" if {[lsearch $::tsp::VAR_TYPES $type] < 0 || $type eq "array"} { error "::tsp::get_tmpvar - invalid var type $type\n[::tsp::currentLine compUnit]\n[::tsp::error_stacktrace]" } From d14300a284a1c4ce1ebbca72044c826638947434 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Sat, 21 Dec 2024 09:03:30 +0100 Subject: [PATCH 06/10] Some bugfixes regarding arrays and self referent strings --- tcc4tcl_helper.tcl | 48 ++++++++++++++-- tsp-generate-set.tcl | 75 ++++++++++++++++++------- tsp-packagehelper.tcl | 126 +++++++++++++++++++++++++++--------------- tsp-types.tcl | 19 ++++--- 4 files changed, 192 insertions(+), 76 deletions(-) diff --git a/tcc4tcl_helper.tcl b/tcc4tcl_helper.tcl index f8759f5..c6f81bb 100644 --- a/tcc4tcl_helper.tcl +++ b/tcc4tcl_helper.tcl @@ -297,7 +297,7 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { set ccoptionstccwin32 "-m32 -D_WIN32 " set ccoptionsgccwin32 "-s -m32 -D_WIN32 -static-libgcc " - set ccoptionstcclin64 {-Wl,-rpath='.'} + set ccoptionstcclin64 {-Wl,-rpath=.} set ccoptionsgcclin64 {-s -fPIC -D_GNU_SOURCE -Wl,-rpath=. } set ccoptionstccuser "" @@ -375,6 +375,42 @@ proc ::tcc4tcl::prepare_compilerdirectives {filepath handle} { return $ccdirectives } +proc lstride {L n} { + set t [list]; set res [list] + foreach i $L { + lappend t $i + if {[llength $t]==$n} { + lappend res $t + set t [list] + } + } + if [llength $t] {lappend res $t} ;# maybe keep the rest + set res +} + +proc ::tcc4tcl::dlexport_procdefs {procdefs proclist} { + # + ### experimental insert### + # + ########################## + # + set exportcode "" + foreach {procname cname_obj} $procdefs { + # [list $tclname $rtype $adefs] + lassign $cname_obj cname rtype adefs + if {[string range $procname 0 1]!="__"} {;#rmoeve special procs + # + set adefs [lstride $adefs 2] + set adefs [join $adefs ,] + set dlcode "DLLEXPORT $rtype $cname ($adefs);\n" + puts "$procname -> obj $cname_obj cname $cname rtype $rtype adefs $adefs" + puts $dlcode + append exportcode $dlcode + } + } + return $exportcode +} + proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packageversion 1.0} {tclversion TCL_VERSION}} { proc relTo {targetfile currentpath } { # Get relative path to target file from current path @@ -422,7 +458,7 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers default {\n} } } - + set DLEXPORTMAKRO $::tccenv::DLEXPORTMAKRO upvar #0 $handle state set oldtype "package" @@ -432,14 +468,18 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers set state(type) "package" } + set compiletime [clock format [clock seconds]] + #modify code with dlexportmakro set oldcode $state(code) set newcode $DLEXPORTMAKRO append newcode $oldcode + #append newcode [::tcc4tcl::dlexport_procdefs $state(procdefs) ""] set state(code) $newcode puts "Writing Package $packagename --> $filepath" set mycode [$handle code] + # beautify code set mycode [::tcc4tcl::reformat [string map [list [eol] \n] $mycode] 4] set $state(type) $oldtype @@ -447,13 +487,13 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers set filename [file join $filepath "$packagename.c"] set ccdirectives [::tcc4tcl::prepare_compilerdirectives $filename $::tsp::TCC_HANDLE] set fp [open $filename w] - puts $fp "/***************** Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" + puts $fp "/***************** $compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" puts $fp "/* Compiler directives are raw estimates, please adapt to given pathstructure */\n" foreach {compiler ccdirective} $ccdirectives { puts $fp "/* for $compiler use */" puts $fp "/* $ccdirective */\n" } - puts $fp "/***************** Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" + puts $fp "/***************** $compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" puts $fp $mycode close $fp return $ccdirectives diff --git a/tsp-generate-set.tcl b/tsp-generate-set.tcl index e01392b..9054de4 100755 --- a/tsp-generate-set.tcl +++ b/tsp-generate-set.tcl @@ -142,6 +142,7 @@ proc ::tsp::produce_set {compUnitDict tree targetComponents sourceComponents} { # variable parsed as an array, but some other type set errors 1 ::tsp::addError compUnit "set arg 1 \"$targetVarName\" previously defined as type: \"$targetType\", now referenced as array" + #puts "set arg 1 \"$targetVarName\" previously defined as type: \"$targetType\", now referenced as array" } # is index a string or variable? @@ -637,11 +638,29 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam # puts "gen_assign_var_string_interpolated_string- ::tsp::setDirty compUnit $targetVarName" ::tsp::setDirty compUnit $targetVarName - set targetPre [::tsp::var_prefix $targetVarName] + set recursiveSet "" + set oldTarget $targetVarName + + foreach component $sourceComponents { + # preanalyse, if recursive set occurs + set compType [lindex $component 0] + set sourceVarName [lindex $component 1] + if {$sourceVarName==$targetVarName} { + if {$compType=="scalar"} { + append code "// DEBUG: recursive set $sourceVarName \n" + set recursiveSet [::tsp::get_tmpvar compUnit string] + set targetVarName $recursiveSet + append code [::tsp::lang_assign_empty_zero $recursiveSet string] + } else { + ::tsp::addError compUnit "recursive assignment to \"$targetVarName\"" + return ERROR + } + } + } + set targetPre [::tsp::var_prefix $targetVarName] append result "\n/***** ::tsp::gen_assign_var_string_interpolated_string */\n" - set tmp [::tsp::get_tmpvar compUnit string] set tmp2 "" set arrVar "" @@ -668,6 +687,10 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam scalar { # assignment from native variable or var, possible type coersion set sourceVarName [lindex $component 1] + if {$sourceVarName==$targetVarName} { + # create another tempvar + append code "// DEBUG: sourceVarName=targetVarName=$targetVarName \n" + } set sourceType [::tsp::getVarType compUnit $sourceVarName] if {$sourceType eq "undefined"} { ::tsp::addError compUnit "set command arg 2 interpolated string variable not defined: \"$sourceVarName\"" @@ -692,17 +715,16 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam append code [::tsp::gen_assign_scalar_scalar compUnit $tmp string $sourceRhsVar $sourceType ] } text_array_idxvar - array_idxvar { - puts "//Parsing Array $compType in $component of $sourceComponents\n" append code "//Parsing Array $compType in $component of $sourceComponents\n" #::tsp::addWarning compUnit "$compType not implemented $component $sourceComponents" - #append code "// Parsing $component in $sourceComponents\n" + #append code "//Parsing $component in $sourceComponents\n" set tmp_s [::tsp::get_tmpvar compUnit string] set doreturn 0 # assignment from native variable or var, possible type coersion set sourceVarName [lindex $component 2] - #append code "// assignment |$sourceVarName| to $tmp_s\n" set sourceType [::tsp::getVarType compUnit $sourceVarName] + #append code "// assignment |$sourceVarName|$sourceType| to $tmp_s\n" if {$sourceType eq "undefined"} { ::tsp::addError compUnit "set command arg 2 interpolated string variable not defined: \"$sourceVarName\"" return [list ""] @@ -716,6 +738,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam append code [::tsp::lang_assign_var_string $tmp_v $tmp_s] #append code "// Convert array |$tmp_a| to $tmp\n" append code [::tsp::lang_assign_var_array_idxvar $tmp_a [::tsp::get_constvar [::tsp::getConstant compUnit [lindex $component 1]]] $tmp_v "Error loading Array Text"] + append code "//DEBUG1: lang_convert_string_var after array \n" append code [::tsp::lang_convert_string_var $tmp $tmp_a] } else { set sourceText [lindex $sourceComponents 3] @@ -733,11 +756,11 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } } if {$targetType eq "string"} { - #append code "// Append string 727 |$tmp|\n" - append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + append code "// Append string 727 dropped |$tmp|\n" + #append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] } elseif {$targetType eq "var"} { - #append code "// Append var |$tmp|\n" - append code [::tsp::lang_assign_var_string $targetVarName $tmp] + append code "// Append var 740 dropped |$tmp|\n" + #append code [::tsp::lang_assign_var_string $targetVarName $tmp] } #append code [::tsp::lang_assign_empty_zero $tmp string] if {$doreturn>0} { @@ -746,8 +769,15 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } } text_array_idxtext - array_idxtext { - append code "//Parsing Array $compType in $component of $sourceComponents\n" + append code "//Parsing Array $compType in $component of $sourceComponents\n" set tmp_s [::tsp::get_tmpvar compUnit string] + set sourceVarName [lindex $component 1] + set sourceType [::tsp::getVarType compUnit $sourceVarName] + #append code "// assignment |$sourceVarName|$sourceType| to $tmp_s\n" + if {($sourceVarName ne "") && ($sourceType ne "array")} { + ::tsp::addError compUnit "set command argument not defined as array but as $sourceType: \"$sourceVarName\"" + return [list ""] + } set doreturn 0 if {($compType=="array_idxtext")} { #::tsp::addWarning compUnit "set arg 2 interpolated string cannot contain $compType as $component in $sourceComponents, only commands, text, backslash, or scalar variables" @@ -767,16 +797,16 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam set doreturn 1 } } - if {$targetType eq "string"} { - #append code "// Append string 763 |$tmp|\n" - ##???append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] - ### deleted this output 23-Oct 20, since it produced continuosly double output with - ### Line 781 string case - #append code "// ok;\n" - } elseif {$targetType eq "var"} { - #append code "// Append var |$tmp|\n" - append code [::tsp::lang_assign_var_string $targetVarName $tmp] - } + if {$targetType eq "string"} { + #append code "// Append string 763 |$tmp|\n" + ##???append code [::tsp::lang_append_string $targetPre$targetVarName $tmp] + ### deleted this output 23-Oct 20, since it produced continuosly double output with + ### Line 781 string case + #append code "// ok;\n" + } elseif {$targetType eq "var"} { + append code "// Append var 778 |$tmp|\n" + append code [::tsp::lang_assign_var_string $targetVarName $tmp] + } #append code [::tsp::lang_assign_empty_zero $tmp string] if {$doreturn>0} { append code "// exiting\n" @@ -795,6 +825,11 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam append code [::tsp::lang_append_string $tmp2 $tmp] } } + if {$recursiveSet!=""} { + append code "// DEBUG: had recursive set\n" + append code [::tsp::lang_convert_string_string [::tsp::var_prefix $oldTarget]$oldTarget $targetPre$targetVarName] + set targetVarName $oldTarget + } if {$targetType eq "var"} { append code [::tsp::gen_assign_scalar_scalar compUnit $targetVarName var $tmp2 string] } diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index c22cccb..d56cfda 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -55,16 +55,27 @@ proc ::tsp::hook_proc {level} { rename ::proc ::__proc ::__proc ::proc {procName procargs procbody} { #puts "Hook hit $procName in -[info script]- lv [info level]==$::tsp::_HOOK_LEVEL ?" - if {([info script] eq "")&&([info level]==$::tsp::_HOOK_LEVEL)} { - lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody] + set nsprocname $procName + if {(([info script] eq "")||([info script] eq $::tsp::ACTSOURCE))&&([info level]==$::tsp::_HOOK_LEVEL)} { + #puts "lappend ::tsp::TCL_PROCS [list $procName $procargs $procbody]" + if {$::tsp::PACKAGE_NAMESPACE ne ""} { + set nsprocname ::${::tsp::PACKAGE_NAMESPACE}::$procName + puts "Namespace rewriting $procName to $nsprocname" + # check if namespace exists or create it + if {[namespace exists ::${::tsp::PACKAGE_NAMESPACE}]==0} { + namespace eval ::${::tsp::PACKAGE_NAMESPACE} {} + } + } + lappend ::tsp::TCL_PROCS [list $nsprocname $procargs $procbody] } - if {[catch {uplevel 0 ::__proc [list $procName $procargs $procbody]} err]} { + if {[catch {uplevel 0 ::__proc [list $nsprocname $procargs $procbody]} err]} { rename ::proc "" rename ::__proc ::proc return -code error "Error in proc $err" } } } + } proc ::tsp::unhook_proc {} { @@ -96,7 +107,7 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} catch { unset ::tsp::TCC_HANDLE} set ::tsp::TCC_HANDLE [tcc4tcl::new] - set ::tsp::PACKAGE_PROCS "" + set ::tsp::NAMESPACE_VARS "" set ::tsp::PACKAGE_INIT_PROC 0 set ::tsp::TCL_PROCS "" set ::tsp::PACKAGE_HEADER \ @@ -123,7 +134,9 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} ::tsp::hook_proc [info level] } - +proc ::tsp::package_export {exportprocnames} { + # +} proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { ::tsp::unhook_proc @@ -136,9 +149,9 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { return } - set tsp::PACKAGE_DIR $packagedir - if {![file isdir $tsp::PACKAGE_DIR]} { - file mkdir $tsp::PACKAGE_DIR + set ::tsp::PACKAGE_DIR $packagedir + if {![file isdir $::tsp::PACKAGE_DIR]} { + file mkdir $::tsp::PACKAGE_DIR } ::tsp::rewrite_procnamespace @@ -151,10 +164,25 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { set ::tsp::COMPILE_DIRECTIVES "" puts "failed crafting compiledirectives... use package require tcc4tcc-helper" } else { - set ::tsp::COMPILE_DIRECTIVES [::tcc4tcl::write_packagecode $::tsp::TCC_HANDLE $::tsp::PACKAGE_NAME $tsp::PACKAGE_DIR $::tsp::PACKAGE_VERSION $::tsp::TCL_VERSION] + set ::tsp::COMPILE_DIRECTIVES [::tcc4tcl::write_packagecode $::tsp::TCC_HANDLE $::tsp::PACKAGE_NAME $::tsp::PACKAGE_DIR $::tsp::PACKAGE_VERSION $::tsp::TCL_VERSION] } } + # add a little help function + if {$::tsp::PACKAGE_NAMESPACE eq ""} { + set help_proc ::${::tsp::PACKAGE_NAME}_help + } else { + set help_proc ::${::tsp::PACKAGE_NAMESPACE}::help + } + # add help-index + set help_body " puts {\n" + append help_body [::tsp::getProcIndex $::tsp::PACKAGE_NAME] + append help_body "\n}\n" + set help_procdef [list $help_proc "" $help_body] + set cmd "::$help_proc {} $help_body" + ::proc ::$help_proc {} $help_body + lappend ::tsp::TCL_PROCS $help_procdef + ::tsp::write_pkgAltTcl $::tsp::PACKAGE_NAME ::tsp::write_pkgIndex $::tsp::PACKAGE_NAME @@ -163,10 +191,10 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { if {($::tsp::ACTSOURCE ne "")&&[file exist $::tsp::ACTSOURCE]} { set t [clock format [clock seconds] -format "%Y-%m-%d_%H-%M-%S"] set srcname "${::tsp::PACKAGE_NAME}_tsp_${t}.tcl" - set srcname [file join $tsp::PACKAGE_DIR $srcname] + set srcname [file join $::tsp::PACKAGE_DIR $srcname] set vdiff 1 catch { - set lastsrcname [file join $tsp::PACKAGE_DIR "${::tsp::PACKAGE_NAME}_tsp_*.tcl"] + set lastsrcname [file join $::tsp::PACKAGE_DIR "${::tsp::PACKAGE_NAME}_tsp_*.tcl"] set lastsrcname [lindex [lsort -decreasing [glob $lastsrcname]] 0] set vdiff [version:filediff $::tsp::ACTSOURCE $lastsrcname] } @@ -177,6 +205,7 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { } ::tsp::compile_package $::tsp::PACKAGE_NAME $compiler + # pkginit? if {$::tsp::PACKAGE_INIT_PROC>0} { if {$compiler in "intern memory"} { @@ -238,15 +267,15 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "tclkit_8.6.12.exe"}} set fd [open $res_name w] puts $fd "#!/usr/bin/tclsh" puts $fd "catch {console show}" - puts "appending auto_path with [file normalize [file dir $tsp::PACKAGE_DIR]]" - puts $fd "lappend auto_path [file normalize [file dir $tsp::PACKAGE_DIR]]" - puts "Testing for [file dir $tsp::PACKAGE_DIR] ne $packagedir" - if {[file dir $tsp::PACKAGE_DIR] ne $packagedir} { + puts "appending auto_path with [file normalize [file dir $::tsp::PACKAGE_DIR]]" + puts $fd "lappend auto_path [file normalize [file dir $::tsp::PACKAGE_DIR]]" + puts "Testing for [file dir $::tsp::PACKAGE_DIR] ne $packagedir" + if {[file dir $::tsp::PACKAGE_DIR] ne $packagedir} { puts "appending auto_path with $packagedir" puts $fd "lappend auto_path $packagedir" } - puts "Appending $tsp::TSPPACKAGE_SPACE" - puts $fd "lappend auto_path $tsp::TSPPACKAGE_SPACE" + puts "Appending $::tsp::TSPPACKAGE_SPACE" + puts $fd "lappend auto_path $::tsp::TSPPACKAGE_SPACE" puts "Loading package... $packagename" puts $fd "package require $packagename" @@ -329,8 +358,8 @@ proc ::tsp::test_package {packagename {callcmd ""}} { if {[catch { puts "Creating new interp" set ip [interp create] - puts "appending auto_path with [file dir $tsp::PACKAGE_DIR]" - $ip eval lappend auto_path [file dir $tsp::PACKAGE_DIR] + puts "appending auto_path with [file dir $::tsp::PACKAGE_DIR]" + $ip eval lappend auto_path [file dir $::tsp::PACKAGE_DIR] puts "Loading package... $packagename" set result [$ip eval package require $packagename] if {$callcmd ne ""} { @@ -362,9 +391,9 @@ proc ::tsp::test_altpackage {packagename {callcmd ""}} { puts "Creating new interp" set ip [interp create] puts "Loading TCL package... $packagename.tclprocs.tcl" - set result [$ip eval source [file join $tsp::PACKAGE_DIR "${packagename}.tclprocs.tcl"]] + set result [$ip eval source [file join $::tsp::PACKAGE_DIR "${packagename}.tclprocs.tcl"]] puts "Loading TCL package... $packagename.puretcl.tcl" - set result [$ip eval source [file join $tsp::PACKAGE_DIR "${packagename}.puretcl.tcl"]] + set result [$ip eval source [file join $::tsp::PACKAGE_DIR "${packagename}.puretcl.tcl"]] if {$callcmd ne ""} { puts "Calling $callcmd" catch { @@ -447,8 +476,10 @@ proc ::tsp::getProcIndex {packagename} { set cpr {} catch {set cpr $::tsp::PACKAGE_PROCS} foreach {procname procdef} $cpr { - lassign $procdef cproc cvars cbody - lappend helpindex "# ${::tsp::PACKAGE_NAMESPACE}::$cproc $cvars" + if {[string range $procname 0 1]!="__"} { + lassign $procdef cproc cvars cbody + lappend helpindex "# ${::tsp::PACKAGE_NAMESPACE}::$cproc $cvars" + } } lappend helpindex "" lappend helpindex "# TCL Procs " @@ -464,12 +495,12 @@ proc ::tsp::getProcIndex {packagename} { proc ::tsp::write_pkgIndex {packagename} { # write a pkgindex.tcl file to load package - if {$tsp::PACKAGE_DIR eq ""} { - set filename [file join $tsp::PACKAGE_DIR "$packagename.pkgIndex.tcl"] - set loadername [file join $tsp::PACKAGE_DIR "$packagename.${packagename}.loader.tcl"] + if {$::tsp::PACKAGE_DIR eq ""} { + set filename [file join $::tsp::PACKAGE_DIR "$packagename.pkgIndex.tcl"] + set loadername [file join $::tsp::PACKAGE_DIR "$packagename.${packagename}.loader.tcl"] } else { - set filename [file join $tsp::PACKAGE_DIR "pkgIndex.tcl"] - set loadername [file join $tsp::PACKAGE_DIR "${packagename}.loader.tcl"] + set filename [file join $::tsp::PACKAGE_DIR "pkgIndex.tcl"] + set loadername [file join $::tsp::PACKAGE_DIR "${packagename}.loader.tcl"] } set fd [open $loadername w] @@ -481,7 +512,12 @@ proc ::tsp::write_pkgIndex {packagename} { append loadextlibs { switch -- $::tcl_platform(platform) { windows {set appdir [file dir [info nameofexecutable]]} - unix {set appdir [file dir [info script]]} + unix { + set appdir [file dir [info script]] + if {$appdir==$dir} { + set appdir [pwd] + } + } } } append loadextlibs "\n" @@ -492,7 +528,7 @@ proc ::tsp::write_pkgIndex {packagename} { lappend libs {*}$::tsp::EXTERNAL_DLLS } foreach incpath $libs { - if {![file exists [file join $tsp::PACKAGE_DIR $incpath[info sharedlibextension]]]} { + if {![file exists [file join $::tsp::PACKAGE_DIR $incpath[info sharedlibextension]]]} { set incpath lib$incpath } append loadextlibs "\nset incdll \[file join \$dir $incpath\[info sharedlibextension\]\]\n" @@ -564,19 +600,21 @@ proc ::tsp::write_pkgAltTcl {packagename} { # add a little help function if {$::tsp::PACKAGE_NAMESPACE eq ""} { - set help_proc ${packagename}_help + set help_proc ::${packagename}_help } else { - set help_proc ${::tsp::PACKAGE_NAMESPACE}::help + set help_proc ::${::tsp::PACKAGE_NAMESPACE}::help } - set help_body " puts {\n" + set help_body " puts {...\n" append help_body [::tsp::getProcIndex $packagename] append help_body "\n}\n" set help_procdef [list $help_proc "" $help_body] - lappend ::tsp::TCL_PROCS $help_procdef + if {[lsearch -index 0 $::tsp::TCL_PROCS $help_proc]==-1} { + lappend ::tsp::TCL_PROCS $help_procdef + } - set filename [file join $tsp::PACKAGE_DIR "$packagename.tclprocs.tcl"] + set filename [file join $::tsp::PACKAGE_DIR "$packagename.tclprocs.tcl"] set fd [open $filename w] puts $fd "# TSP Pure TCL procs for loadlib failure management" puts $fd "# package $packagename" @@ -603,7 +641,7 @@ proc ::tsp::write_pkgAltTcl {packagename} { } close $fd - set filename [file join $tsp::PACKAGE_DIR "${packagename}.puretcl.tcl"] + set filename [file join $::tsp::PACKAGE_DIR "${packagename}.puretcl.tcl"] set fd [open $filename w] puts $fd "# TSP Pure TCL procs for loadlib complemenary procs" puts $fd "# package $packagename" @@ -620,7 +658,7 @@ proc ::tsp::write_pkgAltTcl {packagename} { puts $fd "}" } - foreach procdef $tsp::TCL_PROCS { + foreach procdef $::tsp::TCL_PROCS { lassign $procdef procname procargs procbody if {$procname eq "${packagename}_pkgInit"} { set ::tsp::PACKAGE_INIT_PROC 1 @@ -678,20 +716,20 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { return 1 } - if {$tsp::COMPILE_DIRECTIVES eq ""} { + if {$::tsp::COMPILE_DIRECTIVES eq ""} { puts "ERROR: No compiler directives found" return -1 } - if {$tsp::PACKAGE_DIR eq ""} { + if {$::tsp::PACKAGE_DIR eq ""} { puts "No packagedir given, searching in $packagename/$packagename.c" - set filename [file join $tsp::PACKAGE_DIR "$packagename.c"] + set filename [file join $::tsp::PACKAGE_DIR "$packagename.c"] if {![file exists $filename]} { - set tsp::PACKAGE_DIR $packagename + set ::tsp::PACKAGE_DIR $packagename } } - set filename [file join $tsp::PACKAGE_DIR "$packagename.c"] - set dllname [file join $tsp::PACKAGE_DIR "$packagename.dll"] + set filename [file join $::tsp::PACKAGE_DIR "$packagename.c"] + set dllname [file join $::tsp::PACKAGE_DIR "$packagename.dll"] if {![file exists $filename]} { puts "ERROR: $filename source not found" return -1 @@ -702,7 +740,7 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { cd $::tccenv::tccexecutabledir } - set cdirect [dict get $tsp::COMPILE_DIRECTIVES $compiler] + set cdirect [dict get $::tsp::COMPILE_DIRECTIVES $compiler] puts "Compiling external $cdirect" set ::errorCode "" diff --git a/tsp-types.tcl b/tsp-types.tcl index 65d383c..bcb5b74 100755 --- a/tsp-types.tcl +++ b/tsp-types.tcl @@ -174,9 +174,9 @@ proc ::tsp::parse_procDefs {compUnitDict def} { set validReturnTypes $::tsp::RETURN_TYPES set validArgTypes $::tsp::VAR_TYPES - # patch for native proc withou pushcallframe/popcallframe + # patch for native proc without pushcallframe/popcallframe dict set compUnit isNative 1 - set unsupportedTypes "array" + set unsupportedTypes [list "array"] set len [llength $def] if {$len < 2} { @@ -189,12 +189,14 @@ proc ::tsp::parse_procDefs {compUnitDict def} { } set found [lsearch $validReturnTypes $type] if {$found < 0} { - ::tsp::addError compUnit "::tsp::procdef: invalid return type: $type" + ::tsp::addError compUnit "::tsp::procdef: invalid return type: $type $def" + dict set compUnit returns $type return } set unsupported [lsearch $unsupportedTypes $type] if {$unsupported>-1} { - ::tsp::addWarning compUnit "::tsp::procdef: not a native type $type" + ::tsp::addError compUnit "::tsp::procdef: invalid return type: $type $def" + dict set compUnit returns $type dict set compUnit isNative 0 return } @@ -246,9 +248,9 @@ proc ::tsp::parse_procDefs {compUnitDict def} { set type [lindex $defArgs $i] set unsupported [lsearch $unsupportedTypes $type] if {$unsupported>-1} { - ::tsp::addWarning compUnit "::tsp::procdef: not a native type $type" + ::tsp::addError compUnit "::tsp::procdef: invalid argument type $type $def" dict set compUnit isNative 0 - return + #return } set found [lsearch $validArgTypes $type] if {$found < 0} { @@ -293,10 +295,11 @@ proc ::tsp::parse_varDefs {compUnitDict def} { return } set unsupported [lsearch "array" $type] + #set unsupported -1 if {$unsupported>-1} { - ::tsp::addWarning compUnit "::tsp::procdef: not a native type $type" + #::tsp::addWarning compUnit "::tsp::procdef: not a native type $type $def" dict set compUnit isNative 0 - return + #return } set var_list [lrange $def 1 end] From e0e21d5cbfd2388af59eebe126cc4371122c8f35 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Mon, 30 Dec 2024 09:42:49 +0100 Subject: [PATCH 07/10] some small fixes --- tcc4tcl_helper.tcl | 2 +- tsp-clang.tcl | 3 ++- tsp-compile.tcl | 4 ++-- tsp-expr.tcl | 1 + tsp-packagehelper.tcl | 50 ++++++++++++++++++++++++++----------------- 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/tcc4tcl_helper.tcl b/tcc4tcl_helper.tcl index c6f81bb..a2e5d8a 100644 --- a/tcc4tcl_helper.tcl +++ b/tcc4tcl_helper.tcl @@ -485,7 +485,7 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers set $state(type) $oldtype set filename [file join $filepath "$packagename.c"] - set ccdirectives [::tcc4tcl::prepare_compilerdirectives $filename $::tsp::TCC_HANDLE] + set ccdirectives [::tcc4tcl::prepare_compilerdirectives $filename $handle] set fp [open $filename w] puts $fp "/***************** $compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" puts $fp "/* Compiler directives are raw estimates, please adapt to given pathstructure */\n" diff --git a/tsp-clang.tcl b/tsp-clang.tcl index f7a4f5d..66858f5 100755 --- a/tsp-clang.tcl +++ b/tsp-clang.tcl @@ -266,7 +266,8 @@ proc ::tsp::lang_convert_int_string {targetVarName sourceVarName errMsg} { append result "if ((*rc = TSP_Util_lang_convert_int_string(interp, $sourceVarName, &$targetVarName)) != TCL_OK) \{\n" } #FIXME: see Tcl_GetInt() but convert use Tcl_GetWideIntFromObj instead. - append result " Tcl_AppendResult(interp, [::tsp::lang_quote_string $errMsg], Tcl_GetString($sourceVarName), (char *) NULL);\n" +# append result " Tcl_AppendResult(interp, [::tsp::lang_quote_string $errMsg], Tcl_GetString($sourceVarName), (char *) NULL);\n" + append result " Tcl_AppendResult(interp, [::tsp::lang_quote_string $errMsg], $sourceVarName, (char *) NULL);\n" append result " ERROR_EXIT;\n" append result "\}\n" return $result diff --git a/tsp-compile.tcl b/tsp-compile.tcl index f5ca5da..c254621 100755 --- a/tsp-compile.tcl +++ b/tsp-compile.tcl @@ -89,7 +89,7 @@ proc ::tsp::compile_proc {file name procargs body} { set rc [ catch {set compileResult [::tsp::parse_body compUnit {0 end}] } errInf] if {$rc != 0} { catch {puts [join [dict get $compUnit errors] \n]} - error "tsp internal error: parse_body error: $errInf" + error "tsp internal error parsing $name: parse_body error: $errInf" } set returnType [dict get $compUnit returns] @@ -112,7 +112,7 @@ proc ::tsp::compile_proc {file name procargs body} { set rc [ catch {set compileResult [::tsp::parse_body compUnit {0 end}] } errInf] if {$rc != 0} { catch {puts [join [dict get $compUnit errors] \n]} - error "tsp internal error: parse_body error: $errInf" + error "tsp internal error w parsing $name: parse_body error: $errInf" } lassign $compileResult bodyType bodyRhs code diff --git a/tsp-expr.tcl b/tsp-expr.tcl index d4db30e..03e8626 100755 --- a/tsp-expr.tcl +++ b/tsp-expr.tcl @@ -443,6 +443,7 @@ proc ::tsp::produce_func {compUnitDict op expr tree} { } elseif {[llength $tree] == 1 && [lsearch -exact $::tsp::FUNC_1ARG $op] >= 0} { lassign [::tsp::produce_subexpr compUnit $expr [lindex $tree 0]] firstType firstOperand if {[string match string* $firstType]} { + #::tsp::lang_convert_int_string {targetVarName $firstType errMsg} error "arg type cannot be string for function: $op" } if {[::tsp::typeIsBoolean $firstType]} { diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index d56cfda..6d6bdfd 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -16,20 +16,22 @@ package require tcc4tcl source [file join [file dirname [info script]] tcc4tcl_helper.tcl] - namespace eval ::tsp { - # added for code package making MiR + # added for code package making MiR, also defined and used in tsp.tcl variable COMPILE_PACKAGE 0 variable PACKAGE_NAMESPACE "" - variable NAMESPACE_VARS "" variable PACKAGE_HEADER "" - variable TCC_HANDLE variable PACKAGE_PROCS "" + variable NAMESPACE_VARS "" + variable TCC_HANDLE + variable TSP_VERSION "-unknown-" + + # these variables are NOT to be used elsewhere in tsp variable PACKAGE_NAME "" variable PACKAGE_VERSION "1.0" variable PACKAGE_DIR "" - variable TSPPACKAGE_SPACE [file normalize [file dirname [info script]]] + #variable TSPPACKAGE_SPACE [file normalize [file dirname [info script]]] variable TCL_VERSION "TCL_VERSION" variable TCL_PROCS "" # load tcls for additional sources @@ -98,6 +100,12 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} set ::tsp::PACKAGE_NAMESPACE $packagenamespace set ::tsp::PACKAGE_VERSION $packageversion set ::tsp::TCL_VERSION $tclversion + + #which version of tsp did create the source? + if {$::tsp::TSP_VERSION eq "-unknown-"} { + # try taking it from application + catch {set ::tsp::TSP_VERSION $::_version} + } # reset system in case set ::tsp::COMPILER_LOG [dict create] set ::tsp::COMPILED_PROCS [dict create] @@ -110,17 +118,16 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} set ::tsp::NAMESPACE_VARS "" set ::tsp::PACKAGE_INIT_PROC 0 set ::tsp::TCL_PROCS "" - set ::tsp::PACKAGE_HEADER \ - { -/* START OF PACKAGE_HEADER */ + set ::tsp::PACKAGE_HEADER " +/* START OF PACKAGE_HEADER TSP (Version $::tsp::TSP_VERSION) */ /* don't forget to declare includedir tsp-package/native/clang/ in the right way */ #include #include -#include "TSP_cmd.c" -#include "TSP_func.c" -#include "TSP_util.c" +#include \"TSP_cmd.c\" +#include \"TSP_func.c\" +#include \"TSP_util.c\" /* END OF PACKAGE_HEADER */ - } + " $::tsp::TCC_HANDLE add_include_path "$::tsp::HOME_DIR/native/clang/" $::tsp::TCC_HANDLE add_include_path $packagename @@ -235,6 +242,7 @@ proc ::tsp::safeEval {cmd} { set r [namespace eval :: "$cmd"] puts "Result: $r" } err]} { + interp delete sl ::tsp::unhook_proc puts "Eval Error: $err" } @@ -265,29 +273,31 @@ proc ::tsp::test_packageX {packagename {callcmd ""} {shell "tclkit_8.6.12.exe"}} puts "Creating new exec" set res_name [file normalize resrc.tcl] set fd [open $res_name w] + fconfigure $fd -translation lf puts $fd "#!/usr/bin/tclsh" puts $fd "catch {console show}" - puts "appending auto_path with [file normalize [file dir $::tsp::PACKAGE_DIR]]" + puts ">>> appending auto_path with [file normalize [file dir $::tsp::PACKAGE_DIR]]" + puts $fd "lappend auto_path ." puts $fd "lappend auto_path [file normalize [file dir $::tsp::PACKAGE_DIR]]" - puts "Testing for [file dir $::tsp::PACKAGE_DIR] ne $packagedir" + #puts "Testing for [file dir $::tsp::PACKAGE_DIR] ne $packagedir" if {[file dir $::tsp::PACKAGE_DIR] ne $packagedir} { - puts "appending auto_path with $packagedir" + puts ">>> appending auto_path with $packagedir" puts $fd "lappend auto_path $packagedir" } - puts "Appending $::tsp::TSPPACKAGE_SPACE" - puts $fd "lappend auto_path $::tsp::TSPPACKAGE_SPACE" - puts "Loading package... $packagename" + #puts "Appending $::tsp::TSPPACKAGE_SPACE" + #puts $fd "lappend auto_path $::tsp::TSPPACKAGE_SPACE" + puts ">>> Load package... $packagename" puts $fd "package require $packagename" if {$callcmd ne ""} { - puts "Calling $callcmd" + puts ">>> Call $callcmd" puts $fd $callcmd } } err]} { puts "Error while preparing package $packagename\n$err" } close $fd - puts "Go" + puts ">>> Go" # shell actually hardcoded... todo implement some clever routine to find nearest kit # and to run under linux From 227f819561a444b95f2319e752bb29ac13697af8 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Wed, 29 Jan 2025 08:05:39 +0100 Subject: [PATCH 08/10] Some bugfixes --- tcc4tcl_helper.tcl | 31 +++++++++++++++++++------------ tsp-packagehelper.tcl | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/tcc4tcl_helper.tcl b/tcc4tcl_helper.tcl index a2e5d8a..0ad38ad 100644 --- a/tcc4tcl_helper.tcl +++ b/tcc4tcl_helper.tcl @@ -26,6 +26,8 @@ namespace eval ::tccenv { variable projectincludedir ${projectdir}/include variable projectlibdir ${projectdir}/lib + variable compiletime "" + variable includes_missing "" variable EXTERNAL_COMPILERS "" @@ -411,6 +413,19 @@ proc ::tcc4tcl::dlexport_procdefs {procdefs proclist} { return $exportcode } +proc ::tcc4tcl::prepare_packagecode {handle} { + # + set DLEXPORTMAKRO $::tccenv::DLEXPORTMAKRO + upvar #0 $handle state + #modify code with dlexportmakro + set oldcode $state(code) + set newcode $DLEXPORTMAKRO + append newcode $oldcode + #append newcode [::tcc4tcl::dlexport_procdefs $state(procdefs) ""] + set state(code) $newcode + +} + proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packageversion 1.0} {tclversion TCL_VERSION}} { proc relTo {targetfile currentpath } { # Get relative path to target file from current path @@ -459,7 +474,6 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers } } - set DLEXPORTMAKRO $::tccenv::DLEXPORTMAKRO upvar #0 $handle state set oldtype "package" if {$state(type)!="package"} { @@ -468,15 +482,8 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers set state(type) "package" } - set compiletime [clock format [clock seconds]] - - #modify code with dlexportmakro - set oldcode $state(code) - set newcode $DLEXPORTMAKRO - append newcode $oldcode - #append newcode [::tcc4tcl::dlexport_procdefs $state(procdefs) ""] - set state(code) $newcode - + set ::tccenv::compiletime [clock format [clock seconds]] +# puts "Writing Package $packagename --> $filepath" set mycode [$handle code] @@ -487,13 +494,13 @@ proc ::tcc4tcl::write_packagecode {handle packagename {filepath ""} {packagevers set filename [file join $filepath "$packagename.c"] set ccdirectives [::tcc4tcl::prepare_compilerdirectives $filename $handle] set fp [open $filename w] - puts $fp "/***************** $compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" + puts $fp "/***************** $::tccenv::compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" puts $fp "/* Compiler directives are raw estimates, please adapt to given pathstructure */\n" foreach {compiler ccdirective} $ccdirectives { puts $fp "/* for $compiler use */" puts $fp "/* $ccdirective */\n" } - puts $fp "/***************** $compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" + puts $fp "/***************** $::tccenv::compiletime Automatically Created with TCC4TCL Helper and maybe TSP **********************************/" puts $fp $mycode close $fp return $ccdirectives diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index 6d6bdfd..82734b8 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -31,6 +31,8 @@ namespace eval ::tsp { variable PACKAGE_NAME "" variable PACKAGE_VERSION "1.0" variable PACKAGE_DIR "" + variable writepkg 1 ;# controls if any code is written out + variable TEST_PROC "" #variable TSPPACKAGE_SPACE [file normalize [file dirname [info script]]] variable TCL_VERSION "TCL_VERSION" variable TCL_PROCS "" @@ -162,6 +164,7 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { } ::tsp::rewrite_procnamespace + ::tcc4tcl::prepare_packagecode $::tsp::TCC_HANDLE if {$compiler eq ""} { set compiler "intern" @@ -189,10 +192,11 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { set cmd "::$help_proc {} $help_body" ::proc ::$help_proc {} $help_body lappend ::tsp::TCL_PROCS $help_procdef - - ::tsp::write_pkgAltTcl $::tsp::PACKAGE_NAME - ::tsp::write_pkgIndex $::tsp::PACKAGE_NAME - + if {$::tsp::writepkg>0} { + puts "writing pkg $::tsp::PACKAGE_NAME from -$::tsp::ACTSOURCE-" + ::tsp::write_pkgAltTcl $::tsp::PACKAGE_NAME + ::tsp::write_pkgIndex $::tsp::PACKAGE_NAME + } # if a source file is given # copy source to packagedir... if already in place, rename if {($::tsp::ACTSOURCE ne "")&&[file exist $::tsp::ACTSOURCE]} { @@ -206,7 +210,7 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { set vdiff [version:filediff $::tsp::ACTSOURCE $lastsrcname] } if {$vdiff >0} { - puts "Copy src to $srcname" + puts "Copy src $::tsp::ACTSOURCE to $srcname" file copy "$::tsp::ACTSOURCE" "$srcname" } } @@ -217,7 +221,7 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { if {$::tsp::PACKAGE_INIT_PROC>0} { if {$compiler in "intern memory"} { if {[catch {${::tsp::PACKAGE_NAME}_pkgInit} e]} { - puts "error: $e" + puts "error ${::tsp::PACKAGE_NAME}_pkgInit: $e" } } } @@ -490,7 +494,12 @@ proc ::tsp::getProcIndex {packagename} { lassign $procdef cproc cvars cbody lappend helpindex "# ${::tsp::PACKAGE_NAMESPACE}::$cproc $cvars" } + if {$procname eq "${packagename}_pkgInit"} { + set ::tsp::PACKAGE_INIT_PROC 1 + puts "Init via $procname" + } } + lappend helpindex "" lappend helpindex "# TCL Procs " lappend helpindex "" @@ -499,6 +508,10 @@ proc ::tsp::getProcIndex {packagename} { foreach tcldef $tclpr { lassign $tcldef cproc cvars cbody lappend helpindex [string map {\n "."} "# $cproc $cvars"] + if {$cproc eq "${packagename}_pkgInit"} { + set ::tsp::PACKAGE_INIT_PROC 1 + puts "Init via $cproc" + } } return [join $helpindex \n] } @@ -561,7 +574,7 @@ proc ::tsp::write_pkgIndex {packagename} { append pkgloadlib " ${packagename}_loadext \$dir\n" } if {$::tsp::PACKAGE_PROCS ne ""} { - append pkgloadlib " if {\[catch {load \[file join \$dir \$packagename\[info sharedlibextension\]\]} err\]} {\n" + append pkgloadlib " if {\[catch {load \[file join \$dir \$packagename\[info sharedlibextension\]\] \$packagename} err\]} {\n" append pkgloadlib " source \[file join \$dir \${packagename}.tclprocs.tcl\]\n" append pkgloadlib " }\n" } @@ -641,6 +654,7 @@ proc ::tsp::write_pkgAltTcl {packagename} { lassign $procdef procname procargs procbody if {$procname eq "${packagename}_pkgInit"} { set ::tsp::PACKAGE_INIT_PROC 1 + puts "Init via $procname" } if {$::tsp::PACKAGE_NAMESPACE ne ""} { set procname "::${::tsp::PACKAGE_NAMESPACE}::$procname" @@ -672,6 +686,7 @@ proc ::tsp::write_pkgAltTcl {packagename} { lassign $procdef procname procargs procbody if {$procname eq "${packagename}_pkgInit"} { set ::tsp::PACKAGE_INIT_PROC 1 + puts "Init via $procname" } puts $fd "proc ${procname} {$procargs} {$procbody}\n" } @@ -762,7 +777,7 @@ proc ::tsp::compile_package {packagename {compiler tccwin32}} { if {[llength $::errorCode]>1} { puts "Compiling seems to have errors, execution halted" puts "errorCode $::errorCode" - return -code error + return -code error $err } return 1 } @@ -870,8 +885,10 @@ proc version:filediff {file1 file2 {cmdEqual {version:cmdEqual}} {cmdAdd {versio proc version:cmdEqual {txt line} { } proc version:cmdAdd {txt line} { + if {[string trim $txt]!=""} { append ::actdiff "$line: +$txt\n";update incr ::afilediffs + } } proc version:cmdDel {txt line} { if {[string trim $txt]!=""} { @@ -879,6 +896,10 @@ proc version:cmdDel {txt line} { incr ::afilediffs } } - +proc version:clear {} { + set ::lfilediffs "" + set ::tfilediffs "" + set ::cfilediffs 0 +} #----------------------------------- Code to remove ----------------------------------------- From 7ad2e60fec680985a91d18242456e4d9af479642 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Sun, 16 Feb 2025 18:22:52 +0100 Subject: [PATCH 09/10] some small bugfixes added tsp::tclwrap as wrapper for tcc4tcl::tclwrap --- tsp-packagehelper.tcl | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tsp-packagehelper.tcl b/tsp-packagehelper.tcl index 82734b8..f9298e3 100755 --- a/tsp-packagehelper.tcl +++ b/tsp-packagehelper.tcl @@ -99,7 +99,7 @@ proc ::tsp::init_package {packagename {packagenamespace ""} {packageversion 1.0} } set ::tsp::COMPILE_PACKAGE 1 set ::tsp::PACKAGE_NAME $packagename - set ::tsp::PACKAGE_NAMESPACE $packagenamespace + set ::tsp::PACKAGE_NAMESPACE [string trim $packagenamespace :]; # remove prepending/trailing :: set ::tsp::PACKAGE_VERSION $packageversion set ::tsp::TCL_VERSION $tclversion @@ -230,6 +230,31 @@ proc ::tsp::finalize_package {{packagedir ""} {compiler none}} { } +proc ::tsp::tclwrap {name {adefs {}} {rtype void} {cname ""}} { + # this is a trampoline for tcc4tcls tclwrap routine adding the namespace + if {[namespace exists ::${::tsp::PACKAGE_NAMESPACE}]>0} { + # prepend package_namespace to name + # first clean up the nampespace_identifeier + set vname "::${::tsp::PACKAGE_NAMESPACE}::${name}" + if {[info command $vname]==$vname} { + set name $vname + } + } + $::tsp::TCC_HANDLE tclwrap $name $adefs $rtype $cname +} +proc ::tsp::tclwrap_eval {name {adefs {}} {rtype void} {cname ""}} { + # this is a trampoline for tcc4tcls tclwrap routine adding the namespace + if {[namespace exists ::${::tsp::PACKAGE_NAMESPACE}]>0} { + # prepend package_namespace to name + set vname "::${::tsp::PACKAGE_NAMESPACE}::${name}" + if {[info command $vname]==$vname} { + set name $vname + } + } + $::tsp::TCC_HANDLE tclwrap_eval $name $adefs $rtype $cname +} + + proc ::tsp::addExternalCompiler {compiler ccOptions exeDir exeFile {compilertype gccwin32}} { # add external compiler to list EXTERNAL_COMPILERS # $compiler: compilername cc @@ -567,10 +592,10 @@ proc ::tsp::write_pkgIndex {packagename} { } set pkgloadlib "proc ${packagename}_loadlib {dir packagename} {\n" - if {($loadextlibs ne "")} { + if {($loadextlibs ne "")||($::tsp::LOAD_DLLS ne "")} { append pkgloadlib " ${packagename}_loadextdlls \$dir\n" } - if {($loadextlibs ne "")||($::tsp::LOAD_DLLS ne "")} { + if {($loadextlibs ne "")||($::tsp::LOAD_TCLS ne "")} { append pkgloadlib " ${packagename}_loadext \$dir\n" } if {$::tsp::PACKAGE_PROCS ne ""} { From 445e951af8b05a0d065472fd0683deaec4400a28 Mon Sep 17 00:00:00 2001 From: MichaelMiR01 Date: Thu, 29 May 2025 11:28:42 +0200 Subject: [PATCH 10/10] some bugfixes --- native/clang/TSP_util.c | 36 +++++++++++++++++++++++++++++++++++- native/clang/backup_n.tcl | 23 ----------------------- tsp-clang.tcl | 3 +-- tsp-generate-control.tcl | 6 +++--- tsp-generate-set.tcl | 11 ++++++++--- tsp-generate.tcl | 19 +++++++++++++++---- 6 files changed, 62 insertions(+), 36 deletions(-) delete mode 100755 native/clang/backup_n.tcl diff --git a/native/clang/TSP_util.c b/native/clang/TSP_util.c index a17879f..60769bc 100755 --- a/native/clang/TSP_util.c +++ b/native/clang/TSP_util.c @@ -1,7 +1,38 @@ #ifndef _TCL #include #endif - +int TSP_debug(Tcl_Interp* interp, char const *format, ...) { + /* Helper for Debugging*/ + char __buf [4096]; + va_list aptr; + int ret; + va_start(aptr, format); + ret = vsnprintf(__buf, 4096, format, aptr); + va_end(aptr); + // compensate for surplus linebreaks, sincs puts will already write one + if(ret<0) return EOF; + if(ret>4096) ret=4096; + if(__buf[ret-1]=='\n') __buf[ret-1]=0; + Tcl_Interp* ip = interp; + if (ip==NULL) Tcl_Panic("No interp found to call tcl routine!"); + mod_Tcl_errorCode=0; + Tcl_Obj* argObjvArray [2]; + Tcl_Obj* funcname = Tcl_NewStringObj("puts",-1); + Tcl_IncrRefCount(funcname); + argObjvArray[0] = funcname; + Tcl_Obj* target_1 = Tcl_NewStringObj(__buf,-1); + Tcl_IncrRefCount(target_1); + argObjvArray[1] = target_1; + int rs = Tcl_EvalObjv(ip, 2, argObjvArray, 0); + if(funcname!=NULL) Tcl_DecrRefCount(funcname); + if(target_1 != NULL) Tcl_DecrRefCount(target_1); + if(rs !=TCL_OK) { + Tcl_Eval (ip, "puts {Error evaluating TCL-Function puts}; puts $errorInfo; flush stdout;"); + return EOF; + } + Tcl_DoOneEvent(TCL_DONT_WAIT|TCL_ALL_EVENTS); + return 1; +} /*********************************************************************************************/ /* convert to an int from a string */ @@ -224,9 +255,12 @@ TSP_Util_lang_assign_var_var(Tcl_Obj* targetVarName, Tcl_Obj* sourceVarName) { /*********************************************************************************************/ /* assign an array & element from a var */ + TSP_REMOVABLE int TSP_Util_lang_assign_array_var(Tcl_Interp* interp, Tcl_Obj* targetArrayVar, Tcl_Obj* targetIdxVar, Tcl_Obj* var) { Tcl_Obj* obj; + if (var==NULL) {return TCL_ERROR;}; + //debug(interp,"TSP_Util_lang_assign_array_var %p %p %p\n",targetArrayVar,targetIdxVar,var); obj = Tcl_ObjSetVar2(interp, targetArrayVar, targetIdxVar, var, TCL_LEAVE_ERR_MSG); if (obj == NULL) { return TCL_ERROR; diff --git a/native/clang/backup_n.tcl b/native/clang/backup_n.tcl deleted file mode 100755 index 82fed8a..0000000 --- a/native/clang/backup_n.tcl +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/tclsh -## exec tclkit -## Backup - -set t [clock format [clock seconds] -format "%Y-%m-%d_%H-%M"] -catch {console show} -file mkdir "./cvs" -foreach f0 [glob -nocomplain [file join "./" *]] { - if {[file isfile $f0]} { - set f [file tail $f0] - set n [file rootname $f] - set x [file extension $f] - set t0 [file mtime $f0] - set ts0 [clock format $t0 -format "%Y-%m-%d_%H-%M"] - #if {$f!=[file tail $::argv0]} { - set f1 "./cvs/$n.$ts0$x" - if {![file exists $f1]} { - puts "copy $f0 $f1" - file copy $f0 $f1 - } - #} - } -} diff --git a/tsp-clang.tcl b/tsp-clang.tcl index 66858f5..9f1af37 100755 --- a/tsp-clang.tcl +++ b/tsp-clang.tcl @@ -675,8 +675,7 @@ proc ::tsp::lang_assign_var_var {targetVarName sourceVarName {preserve 1}} { # which is preserved and released # proc ::tsp::lang_assign_array_var {targetArrayVar targetIdxVar var} { - append result "/* ::tsp::lang_assign_array_var */\n" - + append result "/* ::tsp::lang_assign_array_var $targetArrayVar $targetIdxVar $var */\n" append result "TSP_Util_lang_assign_array_var(interp, $targetArrayVar, $targetIdxVar, $var);\n" return $result } diff --git a/tsp-generate-control.tcl b/tsp-generate-control.tcl index b12edcf..0f723ca 100755 --- a/tsp-generate-control.tcl +++ b/tsp-generate-control.tcl @@ -19,14 +19,14 @@ proc ::tsp::gen_command_for {compUnitDict tree} { set rawtext [::tsp::parse_getstring compUnit [lindex $tree 1]] if {[string range $rawtext 0 0] ne "\{"} { - ::tsp::addError compUnit "start code argument not a braced word" + ::tsp::addError compUnit "start code argument not a braced word $rawtext" return [list void "" ""] } set pretext [lindex $rawtext 0] set rawtext [::tsp::parse_getstring compUnit [lindex $tree 2]] if {[string range $rawtext 0 0] ne "\{"} { - ::tsp::addError compUnit "test expr argument not a braced expression" + ::tsp::addError compUnit "test expr argument not a braced expression $rawtext" return [list void "" ""] } set exprtext [lindex $rawtext 0] @@ -112,7 +112,7 @@ proc ::tsp::gen_command_while {compUnitDict tree} { # get expr component, make sure it is braced set rawtext [::tsp::parse_getstring compUnit [lindex $tree 1]] if {[string range $rawtext 0 0] ne "\{"} { - ::tsp::addError compUnit "expr argument not a braced expression" + ::tsp::addError compUnit "expr argument not a braced expression $rawtext" return [list void "" ""] } set exprtext [lindex $rawtext 0] diff --git a/tsp-generate-set.tcl b/tsp-generate-set.tcl index 9054de4..67adbf4 100755 --- a/tsp-generate-set.tcl +++ b/tsp-generate-set.tcl @@ -659,7 +659,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } set targetPre [::tsp::var_prefix $targetVarName] - append result "\n/***** ::tsp::gen_assign_var_string_interpolated_string */\n" + append result "\n/***** ::tsp::gen_assign_var_string_interpolated_string targetType $targetType */\n" set tmp [::tsp::get_tmpvar compUnit string] set tmp2 "" @@ -671,7 +671,8 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam # fix: why is this not reset? if {$targetType eq "string"} { if {$targetPre!=""} { - append result "Tcl_DStringSetLength($targetPre$targetVarName,0);\n" + append result [::tsp::lang_assign_empty_zero $targetPre$targetVarName string] + #append result "/* DEBUG Tcl_DStringSetLength($targetPre$targetVarName,0);*/\n" } } @@ -716,6 +717,7 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam } text_array_idxvar - array_idxvar { append code "//Parsing Array $compType in $component of $sourceComponents\n" + puts "//Parsing Array $compType in $component of $sourceComponents\n" #::tsp::addWarning compUnit "$compType not implemented $component $sourceComponents" #append code "//Parsing $component in $sourceComponents\n" set tmp_s [::tsp::get_tmpvar compUnit string] @@ -746,12 +748,14 @@ proc ::tsp::gen_assign_var_string_interpolated_string {compUnitDict targetVarNam append code "//Missing source in $sourceComponents\n" continue } else { + error "DEBUG here, this is an unknown testcase??? 2025-04-18" #::tsp::addWarning compUnit "set arg 2 interpolated string should not contain $compType as $sourceText in $sourceComponents, only commands, text, backslash, or scalar variables\n" set newsource "[lindex $sourceComponents 1](" #append code "// Convert |$newsource| to $tmp via $tmp_s\n" append code [::tsp::lang_assign_string_const $tmp $newsource] append code [::tsp::lang_append_string $tmp $tmp_s] - append code "Tcl_DStringAppend($tmp,\")\",-1);\n" + append code [::tsp::lang_append_string $tmp "\")\""] + append code "// DEBUG Tcl_DStringAppend($tmp,\")\",-1);\n//DEBUG Appended additional braces\n" set doreturn 1 } } @@ -899,6 +903,7 @@ proc ::tsp::gen_assign_array_scalar {compUnitDict targetVarName targetArrayIdxte append code [::tsp::lang_assign_var_$sourceType $value $pre$sourceVarName] } else { # it's a native var, use a shadow var + ::tsp::setDirty compUnit $sourceVarName lassign [::tsp::getCleanShadowVar compUnit $sourceVarName] value shadowCode append code $shadowCode } diff --git a/tsp-generate.tcl b/tsp-generate.tcl index 1f05b87..311fbea 100755 --- a/tsp-generate.tcl +++ b/tsp-generate.tcl @@ -800,22 +800,33 @@ proc ::tsp::mkComment {text {len 40} {rawOnly 0}} { # get a clean shadow var for a native variable # generates code to set the shadow var if native variable is currently dirty # returns list of {var code} +# BUG FIXME This does not really work, if the shadow var gets set clean in a different code-path! +# HACK At least inserted a test if shadowVar is NULL +# to avoid crashing fron NULL Pointer Deref proc ::tsp::getCleanShadowVar {compUnitDict nativeVar} { upvar $compUnitDict compUnit set shadowVar [::tsp::get_tmpvar compUnit var $nativeVar] + set argVarComponents [list [list text $shadowVar $shadowVar]] + set sourceComponents [list [list scalar $nativeVar]] + set setTree "" if {[lsearch [::tsp::getCleanList compUnit] $nativeVar] == -1} { # var is not clean or not present, generate an assignment - set argVarComponents [list [list text $shadowVar $shadowVar]] - set sourceComponents [list [list scalar $nativeVar]] - set setTree "" set result "\n/* set shadow variable $nativeVar */" append result [lindex [::tsp::produce_set compUnit $setTree $argVarComponents $sourceComponents] 2] # mark the native variable clean - ::tsp::setDirty compUnit $nativeVar 0 +# BUG FIXME This does not really work, if the shadow var gets set clean in a different code-path! +# REMOVED, since it broke in case of multiple loops +# heapsort failed dramatically + # ::tsp::setDirty compUnit $nativeVar 0 } else { # var is clean no need to re-assign set result "/* shadow variable $nativeVar marked as clean */\n" + # prevent, that it's null + append result "if($shadowVar==NULL) {\n" + append result [lindex [::tsp::produce_set compUnit $setTree $argVarComponents $sourceComponents] 2] + append result "}\n" + } return [list $shadowVar $result]