Index: Makefile.in =================================================================== diff -u -N -rd81f1d01346c918a0bf2bff7f3a010644c076111 -r1c256d871fdda3b5f51923b072129b9c589f567e --- Makefile.in (.../Makefile.in) (revision d81f1d01346c918a0bf2bff7f3a010644c076111) +++ Makefile.in (.../Makefile.in) (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -719,8 +719,8 @@ # $(COMPILE) -c `@CYGPATH@ $(srcdir)/src/win/exampleA.c` -o $@ #======================================================================== -$(src_generic_dir)/predefined.h: $(src_generic_dir)/mk_predefined.tcl $(src_generic_dir)/nsf.tcl - (cd $(src_generic_dir); $(TCLSH) mk_predefined.tcl nsf.tcl > predefined.h) +$(src_generic_dir)/predefined.h: $(src_generic_dir)/mk_predefined.tcl $(src_generic_dir)/predefined_part1.tcl $(src_generic_dir)/predefined_part2.tcl + (cd $(src_generic_dir); $(TCLSH) mk_predefined.tcl predefined_part1.tcl predefined_part2.tcl > predefined.h) $(src_generic_dir)/nsfAPI.h: $(src_generic_dir)/gentclAPI.tcl $(src_generic_dir)/nsfAPI.decls $(TCLSH) $(src_generic_dir)/gentclAPI.tcl $(src_generic_dir)/nsfAPI.decls > $(src_generic_dir)/nsfAPI.h Index: configure =================================================================== diff -u -N -r70e66172cf08d62f1fda8f36aece3fa0896499c9 -r1c256d871fdda3b5f51923b072129b9c589f567e --- configure (.../configure) (revision 70e66172cf08d62f1fda8f36aece3fa0896499c9) +++ configure (.../configure) (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -1423,7 +1423,8 @@ --enable-memcount=yes|trace build nsf with memcount debug support (default: disabled) - --enable-development build nsf with development support (intensive + --enable-development=yes|test + build nsf with development support (intensive runtime checking, etc.; default: disabled) --enable-assertions build nsf with assertion support (default: enabled) --enable-assemble=yes|label|call @@ -5629,7 +5630,12 @@ $as_echo "#define NSF_DEVELOPMENT 1" >>confdefs.h fi +if test "$enable_development" = full; then +$as_echo "#define NSF_DEVELOPMENT_TEST 1" >>confdefs.h + +fi + if test "$enable_memcount" = yes; then $as_echo "#define NSF_MEM_COUNT 1" >>confdefs.h Index: generic/mk_predefined.tcl =================================================================== diff -u -N -rcaba76f5ac2943f5a3dfd33550cb578132f40c80 -r1c256d871fdda3b5f51923b072129b9c589f567e --- generic/mk_predefined.tcl (.../mk_predefined.tcl) (revision caba76f5ac2943f5a3dfd33550cb578132f40c80) +++ generic/mk_predefined.tcl (.../mk_predefined.tcl) (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -12,10 +12,10 @@ # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -25,25 +25,32 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -set f [open [lindex $argv 0]] -set content [read $f] -close $f +puts "/* Generated by mk_predefined.tcl */" +foreach file $argv { + set f [open $file] + set content [read $f] + close $f -regsub -all {\\} $content && content -regsub -all {"} $content {\"} content ;#" -regsub -all "\[ \]+\n" $content \n content ;# remove trailing space -regsub -all "\n\[ \t\]+" $content \n content ;# remove leading space -while {[regsub -all "\n#\[^\n\]*\n" $content \n content]>0} { + regsub -all {\\} $content && content + regsub -all "\"" $content {\"} content + regsub -all "\[ \]+\n" $content \n content ;# remove trailing space + regsub -all "\n\[ \t\]+" $content \n content ;# remove leading space + while {[regsub -all "\n#\[^\n\]*\n" $content \n content] > 0} { ;# remove comment lines -} -regsub -all "\n#\[^\n\]*\n" $content \n content ;# remove comment lines -regsub -all "\[\n\]+" $content \n content ;# remove empty lines -regsub -all "\n}" $content "}" content ;# newlines btwn braces -regsub -all "\n" $content "\\n\"\n\"" content + } + regsub -all "\n#\[^\n\]*\n" $content \n content ;# remove comment lines + regsub -all "\[\n\]+" $content \n content ;# remove empty lines + regsub -all "\n\}" $content "\}" content ;# newlines btwn braces + regsub -all "\n" $content "\\n\"\n\"" content -puts "/* Generated by mk_predefined.tcl */" -puts "static char cmd\[\] = " -puts "\"$content\";" + puts "static char [file root $file]\[\] =" + puts "\"$content\";" +} puts "" - +# +# Local variables: +# mode: tcl +# tcl-indent-level: 2 +# indent-tabs-mode: nil +# End: Index: generic/nsf.c =================================================================== diff -u -N -rb84afe7ed2a364dc01a0b7161cc9eea2467433f1 -r1c256d871fdda3b5f51923b072129b9c589f567e --- generic/nsf.c (.../nsf.c) (revision b84afe7ed2a364dc01a0b7161cc9eea2467433f1) +++ generic/nsf.c (.../nsf.c) (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -32980,7 +32980,10 @@ #include "predefined.h" /* fprintf(stderr, "predefined=<<%s>>\n", cmd);*/ - if (Tcl_Eval(interp, cmd) != TCL_OK) { + if ( + (Tcl_Eval(interp, predefined_part1) != TCL_OK) + || (Tcl_Eval(interp, predefined_part2) != TCL_OK) + ) { static char reportingCmd[] = "puts stderr \"Error in predefined code\n\ $::errorInfo\""; Index: generic/nsf.tcl =================================================================== diff -u -N --- generic/nsf.tcl (revision 0ca1bf1c5b3e4a029e935e5f8a42221b61c0d747) +++ generic/nsf.tcl (revision 0) @@ -1,248 +0,0 @@ -# -*- Tcl -*- -# -# Define a basic set of predefined Tcl commands and definitions for -# the Next Scripting Framework. This file will be transformed by -# mk_predefined.tcl into "predefined.h", which in included in nsf.c. -# -# Copyright (C) 2009-2016 Gustaf Neumann -# Copyright (C) 2010 Stefan Sobernig -# - -namespace eval ::nsf { - # - # get frequenly used primitiva into the ::nsf namespace - # - # Symbols reused in the next scripting language - - namespace export \ - next current self configure finalize interp is my relation dispatch - - namespace eval ::nsf::method::create {namespace export alias} - - # - # support for method provide and method require - # - - proc ::nsf::method::provide {require_name definition {script ""}} { - set ::nsf::methodIndex($require_name) [list definition $definition script $script] - } - - proc ::nsf::method::require {object name {per_object 0}} { - # - # On a method require, the optional script is evaluated and the - # "definition" gets inserted - # - on posiiton 1 the actual object - # - on posiiton 2 optionally "-per-object" - # - # The definition cmd must return the method handle. - # - set key ::nsf::methodIndex($name) - if {[info exists $key]} { - array set "" [set $key] - if {$(script) ne ""} { - eval $(script) - } - if {$per_object} { - set cmd [linsert $(definition) 1 -per-object] - return [eval [linsert $cmd 1 $object]] - } else { - return [eval [linsert $(definition) 1 $object]] - } - } else { - error "cannot require method $name for $object, method unknown" - } - } - - # - # The following helper proc is used e.g. in OpenACS to pair - # introspection with nsf::procs. - # - ::proc strip_proc_name {name} { - if {[string match ::nsf::procs::* $name]} { - return [string range $name 12 end] - } elseif {[string match nsf::procs::* $name]} { - return [string range $name 12 end] - } else { - return $name - } - } - - # - # ::nsf::mixin - # - # Provide a similar interface as for ::nsf::method::create, ::nsf::method::alias, - # etc.. Semantically, ::nsf::mixin behaves like a "mixin add", but - # can be used as well for deleting the mixin list (empty last - # argument). - # - - ::nsf::proc ::nsf::mixin {object -per-object:switch classes} { - set rel [expr {${per-object} ? "object-mixin" : "class-mixin"}] - if {[lindex $classes 0] ne ""} { - set oldSetting [::nsf::relation::get $object $rel] - # use uplevel to avoid namespace surprises - uplevel [list ::nsf::relation::set $object $rel [linsert $oldSetting 0 $classes]] - } else { - uplevel [list ::nsf::relation::set $object $rel ""] - } - } - - # - # provide some popular methods for "method require" - # - ::nsf::method::provide autoname {::nsf::method::alias autoname ::nsf::methods::object::autoname} - ::nsf::method::provide exists {::nsf::method::alias exists ::nsf::methods::object::exists} - ::nsf::method::provide volatile {::nsf::method::alias volatile ::nsf::methods::object::volatile} - - ###################################################################### - # unknown handler for objects and classes - # - proc ::nsf::object::unknown {name} { - foreach {key handler} [array get ::nsf::object::unknown] { - set result [uplevel [list {*}$handler $name]] - if {$result ne ""} { - return $result - } - } - return "" - } - namespace eval ::nsf::object::unknown { - proc add {key handler} {set ::nsf::object::unknown($key) $handler} - proc get {key} {return $::nsf::object::unknown($key)} - proc delete {key} {array unset ::nsf::object::unknown($key)} - proc keys {} {array names ::nsf::object::unknown} - } - - # Example unknown handler: - # ::nsf::object::unknown::add xotcl {::xotcl::Class __unknown} - - namespace eval ::nsf::argument {} - proc ::nsf::argument::unknown {args} { - #puts stderr "??? ::nsf::argument::unknown <$args> [info frame -1]" - return "" - } - - ###################################################################### - # exit handlers - # - proc ::nsf::exithandler {args} { - lassign $args op value - switch $op { - set {::proc ::nsf::__exithandler {} $value} - get {::info body ::nsf::__exithandler} - unset {proc ::nsf::__exithandler args {;}} - default {error "syntax: ::nsf::exithandler $::nsf::parameter::syntax(::nsf::exithandler)"} - } - } - # initialize exit handler - ::nsf::exithandler unset - - # - # logger - # - if {[info command ::ns_log] ne ""} { - proc ::nsf::log {level msg} { - # The function might be called in situations in - # aolserver/NaviServer, where ns_log is not available. - if {[info command ::ns_log] ne ""} { - ::ns_log $level "nsf: $msg" - } else { - puts stderr "$level: $msg" - } - } - } else { - proc ::nsf::log {level msg} { - puts stderr "$level: $msg" - } - } - - # - # debug::call and debug::exit command - # - namespace eval ::nsf::debug {} - proc ::nsf::debug::call {level objectInfo methodInfo arglist} { - nsf::log Debug "call($level) - $objectInfo $methodInfo $arglist" - } - proc ::nsf::debug::exit {level objectInfo methodInfo result usec} { - nsf::log Debug "exit($level) - $objectInfo $methodInfo $usec usec -> $result" - } - - # - # deprecated command - # - proc ::nsf::deprecated {what oldCmd newCmd} { - set msg "*** $what $oldCmd is deprecated." - if {$newCmd ne ""} {append msg " use $newCmd instead."} - #append msg "\n**\n" - nsf::log Warning $msg - } - - # - # determine platform aware temp directory - # - proc tmpdir {} { - foreach e [list TMPDIR TEMP TMP] { - if {[info exists ::env($e)] \ - && [file isdirectory $::env($e)] \ - && [file writable $::env($e)]} { - return $::env($e) - } - } - if {$::tcl_platform(platform) eq "windows"} { - foreach d [list "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP"] { - if {[file isdirectory $d] && [file writable $d]} { - return $d - } - } - } - return /tmp - } - namespace export tmpdir - - # if HOME is not set, and ~ is resolved, Tcl chokes on that - if {![info exists ::env(HOME)]} {set ::env(HOME) /root} - - # - # parameter support - # - namespace eval ::nsf::parameter {} - proc ::nsf::parameter::filter {defs pattern} { - set result {} - foreach def $defs { - if {[string match $pattern [::nsf::parameter::info name $def]]} { - lappend result $def - } - } - return $result - } - - set ::nsf::parameter::syntax(::nsf::xotclnext) "?--noArgs? ?/arg .../?" - set ::nsf::parameter::syntax(::nsf::__unset_unknown_args) "" - set ::nsf::parameter::syntax(::nsf::exithandler) "?get?|?set /cmds/?|?unset?" - - # - # Provide the build-time configuration settings via namespaced - # variables, for backward compatibility. - # - - if {[info commands ::nsf::pkgconfig] ne ""} { - - foreach c {version commit patchLevel} { - set ::nsf::$c [::nsf::pkgconfig get $c] - } - - foreach c {development memcount memtrace profile dtrace assertions} { - set ::nsf::config($c) [::nsf::pkgconfig get $c] - } - - unset -nocomplain c - - } -} - -# -# Local variables: -# mode: tcl -# tcl-indent-level: 2 -# indent-tabs-mode: nil -# End: Index: generic/predefined.h =================================================================== diff -u -N -r0ca1bf1c5b3e4a029e935e5f8a42221b61c0d747 -r1c256d871fdda3b5f51923b072129b9c589f567e --- generic/predefined.h (.../predefined.h) (revision 0ca1bf1c5b3e4a029e935e5f8a42221b61c0d747) +++ generic/predefined.h (.../predefined.h) (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -1,5 +1,5 @@ /* Generated by mk_predefined.tcl */ -static char cmd[] = +static char predefined_part1[] = "# -*- Tcl -*-\n" "namespace eval ::nsf {\n" "namespace export \\\n" @@ -82,7 +82,11 @@ "return $d}}}\n" "return /tmp}\n" "namespace export tmpdir\n" -"if {![info exists ::env(HOME)]} {set ::env(HOME) /root}\n" +"if {![info exists ::env(HOME)]} {set ::env(HOME) /root}}\n" +""; +static char predefined_part2[] = +"# -*- Tcl -*-\n" +"namespace eval ::nsf {\n" "namespace eval ::nsf::parameter {}\n" "proc ::nsf::parameter::filter {defs pattern} {\n" "set result {}\n" Index: generic/predefined_part1.tcl =================================================================== diff -u -N --- generic/predefined_part1.tcl (revision 0) +++ generic/predefined_part1.tcl (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -0,0 +1,218 @@ +# -*- Tcl -*- +# +# Define a basic set of predefined Tcl commands and definitions for +# the Next Scripting Framework. This file will be transformed by +# mk_predefined.tcl into "predefined.h", which in included in nsf.c. +# +# Copyright (C) 2009-2017 Gustaf Neumann +# Copyright (C) 2010 Stefan Sobernig +# +# The predefined code has to be split into 2 parts due to a string +# literal limitaton in ISO C99, that requires compilers to support +# only strings up to 4095 bytes. +# +# This is part 1. +# + +namespace eval ::nsf { + # + # get frequenly used primitiva into the ::nsf namespace + # + # Symbols reused in the next scripting language + + namespace export \ + next current self configure finalize interp is my relation dispatch + + namespace eval ::nsf::method::create {namespace export alias} + + # + # support for method provide and method require + # + + proc ::nsf::method::provide {require_name definition {script ""}} { + set ::nsf::methodIndex($require_name) [list definition $definition script $script] + } + + proc ::nsf::method::require {object name {per_object 0}} { + # + # On a method require, the optional script is evaluated and the + # "definition" gets inserted + # - on posiiton 1 the actual object + # - on posiiton 2 optionally "-per-object" + # + # The definition cmd must return the method handle. + # + set key ::nsf::methodIndex($name) + if {[info exists $key]} { + array set "" [set $key] + if {$(script) ne ""} { + eval $(script) + } + if {$per_object} { + set cmd [linsert $(definition) 1 -per-object] + return [eval [linsert $cmd 1 $object]] + } else { + return [eval [linsert $(definition) 1 $object]] + } + } else { + error "cannot require method $name for $object, method unknown" + } + } + + # + # The following helper proc is used e.g. in OpenACS to pair + # introspection with nsf::procs. + # + ::proc strip_proc_name {name} { + if {[string match ::nsf::procs::* $name]} { + return [string range $name 12 end] + } elseif {[string match nsf::procs::* $name]} { + return [string range $name 12 end] + } else { + return $name + } + } + + # + # ::nsf::mixin + # + # Provide a similar interface as for ::nsf::method::create, ::nsf::method::alias, + # etc.. Semantically, ::nsf::mixin behaves like a "mixin add", but + # can be used as well for deleting the mixin list (empty last + # argument). + # + + ::nsf::proc ::nsf::mixin {object -per-object:switch classes} { + set rel [expr {${per-object} ? "object-mixin" : "class-mixin"}] + if {[lindex $classes 0] ne ""} { + set oldSetting [::nsf::relation::get $object $rel] + # use uplevel to avoid namespace surprises + uplevel [list ::nsf::relation::set $object $rel [linsert $oldSetting 0 $classes]] + } else { + uplevel [list ::nsf::relation::set $object $rel ""] + } + } + + # + # provide some popular methods for "method require" + # + ::nsf::method::provide autoname {::nsf::method::alias autoname ::nsf::methods::object::autoname} + ::nsf::method::provide exists {::nsf::method::alias exists ::nsf::methods::object::exists} + ::nsf::method::provide volatile {::nsf::method::alias volatile ::nsf::methods::object::volatile} + + ###################################################################### + # unknown handler for objects and classes + # + proc ::nsf::object::unknown {name} { + foreach {key handler} [array get ::nsf::object::unknown] { + set result [uplevel [list {*}$handler $name]] + if {$result ne ""} { + return $result + } + } + return "" + } + namespace eval ::nsf::object::unknown { + proc add {key handler} {set ::nsf::object::unknown($key) $handler} + proc get {key} {return $::nsf::object::unknown($key)} + proc delete {key} {array unset ::nsf::object::unknown($key)} + proc keys {} {array names ::nsf::object::unknown} + } + + # Example unknown handler: + # ::nsf::object::unknown::add xotcl {::xotcl::Class __unknown} + + namespace eval ::nsf::argument {} + proc ::nsf::argument::unknown {args} { + #puts stderr "??? ::nsf::argument::unknown <$args> [info frame -1]" + return "" + } + + ###################################################################### + # exit handlers + # + proc ::nsf::exithandler {args} { + lassign $args op value + switch $op { + set {::proc ::nsf::__exithandler {} $value} + get {::info body ::nsf::__exithandler} + unset {proc ::nsf::__exithandler args {;}} + default {error "syntax: ::nsf::exithandler $::nsf::parameter::syntax(::nsf::exithandler)"} + } + } + # initialize exit handler + ::nsf::exithandler unset + + # + # logger + # + if {[info command ::ns_log] ne ""} { + proc ::nsf::log {level msg} { + # The function might be called in situations in + # aolserver/NaviServer, where ns_log is not available. + if {[info command ::ns_log] ne ""} { + ::ns_log $level "nsf: $msg" + } else { + puts stderr "$level: $msg" + } + } + } else { + proc ::nsf::log {level msg} { + puts stderr "$level: $msg" + } + } + + # + # debug::call and debug::exit command + # + namespace eval ::nsf::debug {} + proc ::nsf::debug::call {level objectInfo methodInfo arglist} { + nsf::log Debug "call($level) - $objectInfo $methodInfo $arglist" + } + proc ::nsf::debug::exit {level objectInfo methodInfo result usec} { + nsf::log Debug "exit($level) - $objectInfo $methodInfo $usec usec -> $result" + } + + # + # deprecated command + # + proc ::nsf::deprecated {what oldCmd newCmd} { + set msg "*** $what $oldCmd is deprecated." + if {$newCmd ne ""} {append msg " use $newCmd instead."} + #append msg "\n**\n" + nsf::log Warning $msg + } + + # + # determine platform aware temp directory + # + proc tmpdir {} { + foreach e [list TMPDIR TEMP TMP] { + if {[info exists ::env($e)] \ + && [file isdirectory $::env($e)] \ + && [file writable $::env($e)]} { + return $::env($e) + } + } + if {$::tcl_platform(platform) eq "windows"} { + foreach d [list "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP"] { + if {[file isdirectory $d] && [file writable $d]} { + return $d + } + } + } + return /tmp + } + namespace export tmpdir + + # if HOME is not set, and ~ is resolved, Tcl chokes on that + if {![info exists ::env(HOME)]} {set ::env(HOME) /root} + +} + +# +# Local variables: +# mode: tcl +# tcl-indent-level: 2 +# indent-tabs-mode: nil +# End: Index: generic/predefined_part2.tcl =================================================================== diff -u -N --- generic/predefined_part2.tcl (revision 0) +++ generic/predefined_part2.tcl (revision 1c256d871fdda3b5f51923b072129b9c589f567e) @@ -0,0 +1,61 @@ +# -*- Tcl -*- +# +# Define a basic set of predefined Tcl commands and definitions for +# the Next Scripting Framework. This file will be transformed by +# mk_predefined.tcl into "predefined.h", which in included in nsf.c. +# +# Copyright (C) 2009-2017 Gustaf Neumann +# Copyright (C) 2010 Stefan Sobernig +# +# The predefined code has to be split into 2 parts due to a string +# literal limitaton in ISO C99, that requires compilers to support +# only strings up to 4095 bytes. +# +# This is part 2. +# + +namespace eval ::nsf { + # + # parameter support + # + namespace eval ::nsf::parameter {} + proc ::nsf::parameter::filter {defs pattern} { + set result {} + foreach def $defs { + if {[string match $pattern [::nsf::parameter::info name $def]]} { + lappend result $def + } + } + return $result + } + + set ::nsf::parameter::syntax(::nsf::xotclnext) "?--noArgs? ?/arg .../?" + set ::nsf::parameter::syntax(::nsf::__unset_unknown_args) "" + set ::nsf::parameter::syntax(::nsf::exithandler) "?get?|?set /cmds/?|?unset?" + + # + # Provide the build-time configuration settings via namespaced + # variables, for backward compatibility. + # + + if {[info commands ::nsf::pkgconfig] ne ""} { + + foreach c {version commit patchLevel} { + set ::nsf::$c [::nsf::pkgconfig get $c] + } + + foreach c {development memcount memtrace profile dtrace assertions} { + set ::nsf::config($c) [::nsf::pkgconfig get $c] + } + + unset -nocomplain c + + } +} + +# +# Local variables: +# mode: tcl +# tcl-indent-level: 2 +# indent-tabs-mode: nil +# End: