Version History
-1.0.76.0 - October 4, 2011
--
-
- Prevent the domain unload event handler in SQLiteLog from being registered multiple times. Fix for [0d5b1ef362]. -
- Stop allowing non-default application domains to initialize the SQLiteLog class. Fix for [ac47dd230a]. -
1.0.75.0 - October 3, 2011
--
-
- Updated to SQLite 3.7.8 [3e0da808d2]. -
- More enhancements to the build system. -
- Add official NuGet packages for x86 and x64. -
- Add Changes and LastInsertRowId properties to the connection class. -
- Support more formats when converting data from/to the DateTime type. -
- Make all the assembly versioning attributes consistent. -
- Add unit testing infrastructure using Eagle. -
- Integrate all legacy unit tests, including the "testlinq" project, into the new test suite. -
- Add projects to build the interop assembly statically linked to the Visual C++ runtime. Fix for [53f0c5cbf6]. -
- Add SQLITE_ENABLE_STAT2 compile-time option to the interop assembly. Fix for [74807fbf27]. -
- Fix mutex issues exposed when running the test suite with the debug version of SQLite. -
- Fix transaction enlistment when repeated attempts are made to enlist in the same transaction. Fix for [ccfa69fc32]. -
- Support the SQLITE_FCNTL_WIN32_AV_RETRY file control to mitigate the impact of file sharing violations caused by external processes. -
- Refactor the logging interface to be thread-safe and self-initializing. -
- Shutdown the SQLite native interface when the AppDomain is being unloaded. Fix for [b4a7ddc83f]. -
- Support Skip operation for LINQ using OFFSET. Fix for [8b7d179c3c]. -
- Support EndsWith operation for LINQ using SUBSTR. Fix for [59edc1018b]. -
- Support all SQLite journal modes. Fix for [448d663d11]. -
- Do not throw exceptions when disposing SQLiteDataReader. Fix for [e1b2e0f769]. -
- The REAL type should be mapped to System.Double. Fix for [2c630bffa7] and [b0a5990f48]. -
- Minor optimization to GetParamValueBytes(). Fix for [201128cc88]. -
- Support the ON UPDATE, ON DELETE, and MATCH clause information when generating schema metadata for foreign keys. Partial fix for [b226147b37]. VS designer changes are not yet tested. -
- Fix incorrect resource name for SR.resx in the mixed-mode assembly. -
- Reduce the number of String.Compare() calls in the hot path for SQLiteCommand.ExecuteReader(). -
1.0.74.0 - July 4, 2011
- Updated to SQLite 3.7.7.1 [af0d91adf4].
- Fix incorrect hard-coded .NET Framework version information SQLiteFactory_Linq.cs that was causing IServiceProvider.GetService to fail when running against the .NET Framework 3.5.
- Fix all XML documentation warnings. @@ -93,19 +61,19 @@
- Add the testlinq project to the new build system and make it work properly with Visual Studio 2008 and 2010.
1.0.73.0 - June 2, 2011
- Updated to SQLite 3.7.6.3 [ed1da510a2]. -
- Minor optimization to GetBytes(). Fix for [8c1650482e]. +
- Minor optimization to GetBytes(). Fix for [8c1650482e].
- Update various assembly information settings. -
- Correct System.Data.SQLite.Linq version and resource information. Fix for [6489c5a396] and [133daf50d6]. +
- Correct System.Data.SQLite.Linq version and resource information. Fix for [6489c5a396] and [133daf50d6].
- Moved log handler from SQLiteConnection object to SQLiteFactory object to prevent if from being prematurely GCed. -
- We should block x64 installs on x86 and we should install native only if the setup package itself is native. Fix for [e058ce156e]. +
- We should block x64 installs on x86 and we should install native only if the setup package itself is native. Fix for [e058ce156e].
1.0.72.0 - May 1, 2011
-
-
- Add the correct directory to the path. Fix for [50515a0c8e]. +
- Add the correct directory to the path. Fix for [50515a0c8e].
1.0.71.0 - April 27, 2011
- Updated to SQLite 3.7.6+ [1bd1484cd7] to get additional Windows error logging.
- Updated setup to optionally add install directory to PATH if GAC option selected. Index: Doc/Extra/welcome.html ================================================================== --- Doc/Extra/welcome.html +++ Doc/Extra/welcome.html @@ -140,11 +140,11 @@ comes in 3 flavors: Win32, Itanium and x64 (AMD64).
Distributing the Binaries (Compact Framework)
System.Data.SQLite.DLL and SQLite.Interop.XXX.DLL must be deployed on the Compact Framework. The XXX is the build number of the - System.Data.SQLite library (e.g. "076"). SQLite.Interop.XXX is a fully + System.Data.SQLite library (e.g. "074"). SQLite.Interop.XXX is a fully native assembly compiled for the ARM processor, and System.Data.SQLite is the fully-managed Compact Framework assembly.
Index: Doc/SQLite.NET.chm
==================================================================
--- Doc/SQLite.NET.chm
+++ Doc/SQLite.NET.chm
cannot compute difference between binary files
ADDED Externals/Eagle/Tests/constraints.eagle
Index: Externals/Eagle/Tests/constraints.eagle
==================================================================
--- /dev/null
+++ Externals/Eagle/Tests/constraints.eagle
@@ -0,0 +1,1574 @@
+###############################################################################
+#
+# constraints.eagle --
+#
+# Extensible Adaptable Generalized Logic Engine (Eagle)
+# Test Constraints File
+#
+# Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+#
+###############################################################################
+
+#
+# NOTE: Use our own namespace here because even though we do not directly
+# support namespaces ourselves, we do not want to pollute the global
+# namespace if this script actually ends up being evaluated in Tcl.
+#
+namespace eval ::Eagle {
+ proc checkForPlatform { channel } {
+ tputs $channel "---- checking for platform... "
+
+ addConstraint $::tcl_platform(platform)
+
+ if {![isEagle]} then {
+ #
+ # BUGFIX: We do not want to skip any Mono bugs in Tcl.
+ # Also, fake the culture.
+ #
+ set constraints [list monoToDo monoBug monoCrash culture.en_US]
+
+ #
+ # NOTE: Add the necessary constraints for each version
+ # of Mono we know about.
+ #
+ foreach version [list 20 22 24 26 28 210 30] {
+ addConstraint [appendArgs monoToDo $version]
+ addConstraint [appendArgs monoBug $version]
+ addConstraint [appendArgs monoCrash $version]
+ }
+
+ foreach constraint $constraints {
+ addConstraint $constraint; # running in Tcl.
+ }
+ }
+
+ tputs $channel [appendArgs $::tcl_platform(platform) \n]
+ }
+
+ proc checkForEagle { channel } {
+ tputs $channel "---- checking for Eagle... "
+
+ if {[isEagle]} then {
+ #
+ # NOTE: We are running inside Eagle.
+ #
+ addConstraint eagle
+
+ #
+ # NOTE: We do not want to skip bugs or crashing
+ # issues for Tcl since we are not running
+ # in Tcl.
+ #
+ addConstraint tclBug
+ addConstraint tclCrash
+
+ #
+ # NOTE: Add the necessary constraints for each
+ # version of Tcl we know about.
+ #
+ foreach version [list 84 85 86] {
+ addConstraint [appendArgs tclBug $version]
+ addConstraint [appendArgs tclCrash $version]
+ }
+
+ tputs $channel yes\n
+ } else {
+ #
+ # NOTE: We are running inside Tcl.
+ #
+ addConstraint tcl
+
+ #
+ # NOTE: Each Tcl bug and crash constraint is set
+ # based on the exact Tcl version (i.e. not
+ # greater than or equal to).
+ #
+ if {[info exists ::tcl_version]} then {
+ #
+ # NOTE: For each Tcl version we know about,
+ # check it against the currently running
+ # Tcl version. If the two are not equal,
+ # add the test constraints that prevent
+ # skipping those tests that are buggy
+ # only for the particular version of Tcl.
+ #
+ foreach dotVersion [list 8.4 8.5 8.6] {
+ if {$::tcl_version ne $dotVersion} then {
+ set version [string map [list . ""] $dotVersion]
+
+ addConstraint [appendArgs tclBug $version]
+ addConstraint [appendArgs tclCrash $version]
+ }
+ }
+ }
+
+ #
+ # NOTE: We do not want to skip bugs or crashing
+ # issues for Eagle since we are not running
+ # in Eagle.
+ #
+ addConstraint eagleBug
+ addConstraint eagleCrash
+
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForGaruda { channel } {
+ tputs $channel "---- checking for Garuda... "
+
+ if {[haveGaruda packageId]} then {
+ #
+ # NOTE: We are running with or via Garuda.
+ #
+ addConstraint garuda
+
+ tputs $channel [appendArgs "yes (" $packageId ")\n"]
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForShell { channel } {
+ tputs $channel "---- checking for shell... "
+
+ set name [file rootname [file tail [info nameofexecutable]]]
+
+ if {[isEagle]} then {
+ if {$name eq "EagleShell"} then {
+ #
+ # NOTE: We are running in Eagle via the EagleShell.
+ #
+ addConstraint shell
+
+ tputs $channel "yes (Eagle)\n"
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ } else {
+ if {[string match tclsh* $name]} then {
+ #
+ # NOTE: We are running in Tcl via tclsh.
+ #
+ addConstraint shell
+
+ tputs $channel "yes (Tcl)\n"
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForDebug { channel } {
+ tputs $channel "---- checking for debug... "
+
+ if {[info exists ::tcl_platform(debug)] && $::tcl_platform(debug)} then {
+ addConstraint debug
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForVersion { channel } {
+ tputs $channel "---- checking for language version... "
+
+ if {[info exists ::tcl_version]} then {
+ #
+ # TODO: Cleanup the semantics for adding test
+ # constraints here.
+ #
+ if {$::tcl_version eq "8.4"} then {
+ #
+ # NOTE: Baseline reported language and feature
+ # version.
+ #
+ addConstraint tcl84
+ addConstraint tcl84OrHigher
+ addConstraint tcl84Feature
+
+ if {[isEagle]} then {
+ #
+ # NOTE: *EAGLE* We do want to include any
+ # tests that target "Tcl 8.5 or higher"
+ # features and/or "Tcl 8.6 or higher"
+ # features because they would not be in
+ # the test suite if we did not support
+ # that particular feature, regardless
+ # of the language version.
+ #
+ addConstraint tcl85Feature
+ addConstraint tcl86Feature
+ }
+ } elseif {$::tcl_version eq "8.5"} then {
+ #
+ # NOTE: Baseline reported language and feature
+ # version. Tcl 8.5 includes all the
+ # features from itself and Tcl 8.4.
+ #
+ addConstraint tcl85
+ addConstraint tcl84OrHigher
+ addConstraint tcl85OrHigher
+ addConstraint tcl84Feature
+ addConstraint tcl85Feature
+
+ if {[isEagle]} then {
+ #
+ # NOTE: *EAGLE* We do want to include any
+ # tests that target "Tcl 8.5 or higher"
+ # features and/or "Tcl 8.6 or higher"
+ # features because they would not be in
+ # the test suite if we did not support
+ # that particular feature, regardless
+ # of the language version.
+ #
+ addConstraint tcl86Feature
+ }
+ } elseif {$::tcl_version eq "8.6"} then {
+ #
+ # NOTE: Baseline reported language and feature
+ # version. Tcl 8.6 includes all the
+ # features from itself Tcl 8.4, and Tcl
+ # 8.5.
+ #
+ addConstraint tcl86
+ addConstraint tcl84OrHigher
+ addConstraint tcl85OrHigher
+ addConstraint tcl86OrHigher
+ addConstraint tcl84Feature
+ addConstraint tcl85Feature
+ addConstraint tcl86Feature
+ }
+
+ tputs $channel [appendArgs $::tcl_version \n]
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForCommand { channel name } {
+ tputs $channel [appendArgs "---- checking for command \"" $name \
+ "\"... "]
+
+ #
+ # NOTE: Is the command available?
+ #
+ if {[llength [info commands $name]] > 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint command.$name
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForFile { channel name {constraint ""} } {
+ tputs $channel [appendArgs "---- checking for file \"" $name \
+ "\"... "]
+
+ if {[file exists $name]} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ if {[string length $constraint] > 0} then {
+ addConstraint file_$constraint
+ } else {
+ addConstraint file_[file tail $name]
+ }
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForPathFile { channel name {constraint ""} } {
+ tputs $channel [appendArgs "---- checking for file \"" $name \
+ "\" along PATH... "]
+
+ if {[file exists $name]} then {
+ #
+ # NOTE: Yes, it appears that it is available [in the exact location they
+ # specified].
+ #
+ if {[string length $constraint] > 0} then {
+ addConstraint file_$constraint
+ } else {
+ addConstraint file_[file tail $name]
+ }
+
+ tputs $channel yes\n
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ } else {
+ #
+ # NOTE: Use the appropriate environment variable for the platform.
+ #
+ if {$::tcl_platform(platform) eq "windows"} then {
+ set pathName PATH
+ } else {
+ #
+ # HACK: For shared libraries, use the LD_LIBRARY_PATH.
+ #
+ if {[file extension $name] eq [info sharedlibextension]} then {
+ set pathName LD_LIBRARY_PATH
+ } else {
+ set pathName PATH
+ }
+ }
+
+ #
+ # NOTE: Is the required environment variable available?
+ #
+ if {[info exists ::env($pathName)]} then {
+ #
+ # NOTE: Ok, grab it now.
+ #
+ set path $::env($pathName)
+
+ #
+ # NOTE: Use the appropriate path separator for the platform.
+ #
+ if {[info exists ::tcl_platform(pathSeparator)]} then {
+ set separator $::tcl_platform(pathSeparator)
+ } elseif {$::tcl_platform(platform) eq "windows"} then {
+ set separator \;
+ } else {
+ set separator :
+ }
+
+ #
+ # NOTE: Grab just the file name from the possibly fully qualified file
+ # name provided by the caller.
+ #
+ set tail [file tail $name]
+
+ #
+ # NOTE: Check each directory in the PATH for the file.
+ #
+ foreach directory [split $path $separator] {
+ #
+ # NOTE: Check for the file in this directory contained in the PATH.
+ # This strips the directory portion off the file name specified
+ # by the caller, if any, before joining that file name to the
+ # current directory of the PATH being searched.
+ #
+ if {[file exists [file join $directory $tail]]} then {
+ #
+ # NOTE: Yes, it appears that it is available in the PATH.
+ #
+ if {[string length $constraint] > 0} then {
+ addConstraint file_$constraint
+ } else {
+ addConstraint file_[file tail $name]
+ }
+
+ tputs $channel yes\n
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForNativeCode { channel } {
+ tputs $channel "---- checking for native code... "
+
+ if {[isEagle]} then {
+ if {[info exists ::eagle_platform(compileOptions)] && \
+ [info exists ::tcl_platform(platform)] && \
+ [lsearch -exact -nocase $::eagle_platform(compileOptions) \
+ $::tcl_platform(platform)] != -1} then {
+ #
+ # NOTE: Yes, the binary matches the current platform,
+ # native code can be used.
+ #
+ addConstraint native
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ } else {
+ #
+ # NOTE: Tcl is always native code and can always execute native code.
+ #
+ addConstraint native
+
+ #
+ # HACK: Needed by test "benchmark-1.22".
+ #
+ addConstraint compile.NATIVE
+
+ tputs $channel yes\n
+ }
+ }
+
+ proc checkForTip127 { channel } {
+ tputs $channel "---- checking for TIP #127... "
+
+ #
+ # NOTE: Is the interpreter TIP #127 ready?
+ #
+ if {[catch {lsearch -index 0 0 0}] == 0} then {
+ addConstraint tip127
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTip194 { channel } {
+ tputs $channel "---- checking for TIP #194... "
+
+ #
+ # NOTE: Is the interpreter TIP #194 ready?
+ #
+ catch {apply} error
+
+ if {$error ne {invalid command name "apply"}} then {
+ addConstraint tip194
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTip241 { channel } {
+ tputs $channel "---- checking for TIP #241... "
+
+ #
+ # NOTE: Is the interpreter TIP #241 ready?
+ #
+ if {[catch {lsearch -nocase 0 0}] == 0} then {
+ addConstraint tip241
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTip285 { channel } {
+ tputs $channel "---- checking for TIP #285... "
+
+ #
+ # NOTE: Is the interpreter TIP #285 ready?
+ #
+ catch {interp cancel} error
+
+ if {$error eq "eval canceled"} then {
+ addConstraint tip285
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTiming { channel threshold } {
+ tputs $channel "---- checking for precision timing... "
+
+ #
+ # NOTE: Are we allowed to do precision timing tests?
+ #
+ if {![info exists ::no(timing)]} then {
+ #
+ # NOTE: Attempt to block for exactly one second.
+ #
+ set start [expr {[clock clicks -milliseconds] & 0x7fffffff}]
+ after 1000; # wait for "exactly" one second.
+ set stop [expr {[clock clicks -milliseconds] & 0x7fffffff}]
+
+ #
+ # NOTE: Calculate the difference between the actual and expected
+ # number of milliseconds.
+ #
+ set difference [expr {abs($stop - $start - 1000)}]
+
+ #
+ # NOTE: Are we within the threshold specified by the caller?
+ #
+ if {$difference >= 0 && $difference <= $threshold} then {
+ addConstraint timing
+
+ tputs $channel [appendArgs "yes (0 <= " $difference " <= " \
+ $threshold " milliseconds)\n"]
+ } else {
+ tputs $channel [appendArgs "no (0 <= " $difference " > " \
+ $threshold " milliseconds)\n"]
+ }
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForPerformance { channel } {
+ tputs $channel "---- checking for performance testing... "
+
+ #
+ # NOTE: Are we allowed to do performance testing?
+ #
+ if {![info exists ::no(performance)]} then {
+ addConstraint performance
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForInteractive { channel } {
+ tputs $channel "---- checking for interactive user... "
+
+ #
+ # NOTE: Is there an interactive user?
+ #
+ if {[info exists ::tcl_interactive] && $::tcl_interactive} then {
+ addConstraint interactive
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForUserInteraction { channel } {
+ tputs $channel "---- checking for user interaction... "
+
+ #
+ # HACK: For now, do the exact same check as checkForInteractive; however,
+ # this is still useful as a separate constraint because it can be
+ # individually disabled in "prologue.eagle".
+ #
+ if {[info exists ::tcl_interactive] && $::tcl_interactive} then {
+ addConstraint userInteraction
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForNetwork { channel host timeout } {
+ tputs $channel [appendArgs \
+ "---- checking for network connectivity to host \"" $host "\"... "]
+
+ if {[isEagle]} then {
+ #
+ # BUGBUG: Tcl 8.4 does not like this expression (and Tcl tries to
+ # compile it even though it will only actually ever be
+ # evaluated in Eagle).
+ #
+ set expr {[llength [info commands uri]] > 0 && \
+ [catch {uri ping $host $timeout} response] == 0 && \
+ [lindex $response 0] in [list Success TimedOut] && \
+ [string is integer -strict [lindex $response 1]] && \
+ [lindex $response 1] <= $timeout}
+
+ #
+ # NOTE: Does it look like we are able to contact the network host?
+ #
+ if {[expr $expr]} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint network_$host
+
+ tputs $channel [appendArgs "yes (" $response ")\n"]
+ } else {
+ tputs $channel no\n
+ }
+ } else {
+ #
+ # HACK: Running in Tcl, just assume we have network access.
+ #
+ addConstraint network_$host
+
+ tputs $channel yes\n
+ }
+ }
+
+ if {[isEagle]} then {
+ ###########################################################################
+ ############################ BEGIN Eagle ONLY #############################
+ ###########################################################################
+
+ proc checkForSoftwareUpdateTrust { channel } {
+ tputs $channel "---- checking for software update trust... "
+
+ if {[llength [info commands uri]] > 0 && \
+ [catch {uri softwareupdates} result] == 0 && \
+ $result eq "software update certificate is trusted"} then {
+ #
+ # NOTE: Yes, it appears that we trust our software updates.
+ # Since this setting is off by default, the user (or
+ # a script evaluated by the user) must have manually
+ # turned it on.
+ #
+ addConstraint softwareUpdate
+
+ tputs $channel "trusted\n"
+ } else {
+ tputs $channel "untrusted\n"
+ }
+ }
+
+ proc checkForAdministrator { channel } {
+ tputs $channel "---- checking for administrator... "
+
+ if {[isAdministrator]} then {
+ addConstraint administrator; # running as full admin.
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForHost { channel } {
+ tputs $channel "---- checking for host... "
+
+ if {[set code [catch {host isopen} result]] == 0 && $result} then {
+ addConstraint hostIsOpen
+
+ tputs $channel open\n
+ } elseif {$code == 0} then {
+ tputs $channel closed\n
+ } else {
+ tlog $result; tputs $channel error\n]
+ }
+ }
+
+ proc checkForPrimaryThread { channel } {
+ tputs $channel "---- checking for primary thread... "
+
+ set threadId [object invoke Interpreter.GetActive ThreadId]
+
+ if {[info tid] == $threadId} then {
+ addConstraint primaryThread
+
+ tputs $channel [appendArgs "yes (" $threadId ")\n"]
+ } else {
+ tputs $channel [appendArgs "no (" $threadId ")\n"]
+ }
+ }
+
+ proc checkForRuntime { channel } {
+ tputs $channel "---- checking for runtime... "
+
+ #
+ # NOTE: Are we running inside Mono (regardless of operating system)?
+ #
+ if {[isMono]} then {
+ #
+ # NOTE: Yes, it appears that we are running inside Mono.
+ #
+ addConstraint mono; # running on Mono.
+
+ tputs $channel [appendArgs [expr {[info exists \
+ ::eagle_platform(runtime)] ? \
+ $::eagle_platform(runtime) : "Mono"}] \n]
+ } else {
+ #
+ # NOTE: No, it appears that we are not running inside Mono.
+ #
+ addConstraint dotNet; # running on .NET.
+
+ #
+ # NOTE: We do not want to skip Mono bugs on .NET.
+ #
+ addConstraint monoToDo; # running on .NET.
+ addConstraint monoBug; # running on .NET.
+ addConstraint monoCrash; # running on .NET.
+
+ tputs $channel [appendArgs [expr {[info exists \
+ ::eagle_platform(runtime)] ? \
+ $::eagle_platform(runtime) : "Microsoft.NET"}] \n]
+ }
+ }
+
+ proc checkForImageRuntimeVersion { channel } {
+ tputs $channel "---- checking for image runtime version... "
+
+ if {[info exists ::eagle_platform(imageRuntimeVersion)] && \
+ [string length $::eagle_platform(imageRuntimeVersion)] > 0} then {
+ #
+ # NOTE: Get the major and minor portions of the version only.
+ #
+ set dotVersion [join [lrange [split \
+ $::eagle_platform(imageRuntimeVersion) .] 0 1] .]
+
+ #
+ # NOTE: Now create a version string for use in the constraint name
+ # (remove the periods).
+ #
+ set version [string map [list v "" . ""] $dotVersion]
+
+ #
+ # NOTE: Keep track of the specific image runtime version for usage in
+ # test constraints.
+ #
+ addConstraint imageRuntime$version
+
+ tputs $channel [appendArgs $::eagle_platform(imageRuntimeVersion) \
+ " " ( $dotVersion ) \n]
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForRuntimeVersion { channel } {
+ tputs $channel "---- checking for runtime version... "
+
+ if {[info exists ::eagle_platform(runtimeVersion)] && \
+ [string length $::eagle_platform(runtimeVersion)] > 0} then {
+ #
+ # NOTE: Get the major and minor portions of the version only.
+ #
+ set dotVersion [join [lrange [split \
+ $::eagle_platform(runtimeVersion) .] 0 1] .]
+
+ #
+ # NOTE: Now create a version string for use in the constraint name
+ # (remove the periods).
+ #
+ set version [string map [list . ""] $dotVersion]
+
+ if {[isMono]} then {
+ if {[string length $version] > 0} then {
+ #
+ # NOTE: We are running on Mono. Keep track of the specific
+ # version for usage in test constraints.
+ #
+ addConstraint mono$version
+ }
+
+ if {[string length $dotVersion] > 0 && \
+ [regexp -- {^(\d+)\.(\d+)$} $dotVersion dummy \
+ majorVersion minorVersion]} then {
+ set monoVersions [list]
+
+ #
+ # NOTE: Check for any Mono version 2.x or higher.
+ #
+ if {$majorVersion >= 2} then {
+ #
+ # NOTE: Check for any Mono version higher than 2.0.
+ #
+ if {$majorVersion > 2 || $minorVersion > 0} then {
+ lappend monoVersions 20
+ }
+
+ #
+ # NOTE: Check for any Mono version higher than 2.2.
+ #
+ if {$majorVersion > 2 || $minorVersion > 2} then {
+ lappend monoVersions 22
+ }
+
+ #
+ # NOTE: Check for any Mono version higher than 2.4.
+ #
+ if {$majorVersion > 2 || $minorVersion > 4} then {
+ lappend monoVersions 24
+ }
+
+ #
+ # NOTE: Check for any Mono version higher than 2.6.
+ #
+ if {$majorVersion > 2 || $minorVersion > 6} then {
+ lappend monoVersions 26
+ }
+
+ #
+ # NOTE: Check for any Mono version higher than 2.8.
+ #
+ if {$majorVersion > 2 || $minorVersion > 8} then {
+ lappend monoVersions 28
+ }
+
+ #
+ # NOTE: Check for any Mono version higher than 2.10.
+ #
+ if {$majorVersion > 2 || $minorVersion > 10} then {
+ lappend monoVersions 210
+ }
+ }
+
+ #
+ # NOTE: Check for any Mono version 3.x or higher.
+ #
+ if {$majorVersion >= 3} then {
+ #
+ # NOTE: Check for any Mono version higher than 3.0.
+ #
+ if {$majorVersion > 3 || $minorVersion > 0} then {
+ lappend monoVersions 30
+ }
+ }
+
+ #
+ # NOTE: Add the necessary constraints for each version of Mono we
+ # should NOT skip bugs for.
+ #
+ foreach monoVersion $monoVersions {
+ addConstraint [appendArgs monoToDo $monoVersion]
+ addConstraint [appendArgs monoBug $monoVersion]
+ addConstraint [appendArgs monoCrash $monoVersion]
+ }
+ }
+ } else {
+ if {[string length $version] > 0} then {
+ #
+ # NOTE: We are running on the .NET Framework. Keep track of the
+ # specific version for usage in test constraints.
+ #
+ addConstraint dotNet$version
+ }
+
+ #
+ # NOTE: We do not want to skip any Mono bugs on .NET. Add the
+ # necessary constraints for each version of Mono we know
+ # about.
+ #
+ foreach monoVersion [list 20 22 24 26 28 210 30] {
+ addConstraint [appendArgs monoToDo $monoVersion]
+ addConstraint [appendArgs monoBug $monoVersion]
+ addConstraint [appendArgs monoCrash $monoVersion]
+ }
+ }
+
+ tputs $channel [appendArgs $::eagle_platform(runtimeVersion) \
+ " " ( $dotVersion ) \n]
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForMachine { channel bits machine } {
+ tputs $channel [appendArgs "---- checking for machine \"" $bits \
+ "-bit " $machine "\"... "]
+
+ #
+ # NOTE: What are the machine architecture and the
+ # number of bits for this operating system?
+ #
+ if {[info exists ::tcl_platform(machine)] && \
+ [info exists ::tcl_platform(osBits)]} then {
+ #
+ # NOTE: Does the machine and number of bits match
+ # what the caller specified?
+ #
+ if {$::tcl_platform(machine) eq $machine && \
+ $::tcl_platform(osBits) eq $bits} then {
+ #
+ # NOTE: Yes, it matches.
+ #
+ addConstraint $machine.${bits}bit
+
+ set result yes
+ } else {
+ set result no
+ }
+
+ tputs $channel [appendArgs $result ", " $::tcl_platform(osBits) -bit \
+ " " $::tcl_platform(machine)\n]
+ } else {
+ tputs $channel "no, unknown\n"
+ }
+ }
+
+ proc checkForGarudaDll { channel } {
+ #
+ # NOTE: Check for the Garuda DLL of the same platform (i.e. machine
+ # type) as the native Tcl shell.
+ #
+ return [checkForFile $channel [file join $::base_path bin \
+ [machineToPlatform [getMachineForTclShell]] \
+ [appendArgs $::eagle_platform(configuration) Dll] \
+ [appendArgs Garuda [info sharedlibextension]]]]
+ }
+
+ proc checkForCulture { channel } {
+ tputs $channel "---- checking for culture... "
+
+ #
+ # NOTE: Grab the current culture.
+ #
+ set culture [info culture]
+
+ if {[string length $culture] > 0} then {
+ #
+ # NOTE: The culture information is present, use it and show it.
+ #
+ addConstraint culture.[string map [list - _] $culture]
+
+ tputs $channel [appendArgs $culture \n]
+ } else {
+ tputs $channel [appendArgs unknown \n]
+ }
+ }
+
+ proc checkForReferenceCountTracking { channel } {
+ tputs $channel "---- checking for object reference count tracking... "
+
+ if {[info exists ::eagle_platform(compileOptions)] && \
+ ([lsearch -exact -nocase $::eagle_platform(compileOptions) \
+ NOTIFY] != -1 || \
+ [lsearch -exact -nocase $::eagle_platform(compileOptions) \
+ NOTIFY_OBJECT] != -1)} then {
+ #
+ # NOTE: Yes, support for object reference count tracking is present.
+ #
+ addConstraint refCount
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForCompileOption { channel option } {
+ tputs $channel [appendArgs "---- checking for compile option \"" \
+ $option "\"... "]
+
+ if {[info exists ::eagle_platform(compileOptions)] && \
+ [lsearch -exact -nocase $::eagle_platform(compileOptions) \
+ $option] != -1} then {
+ #
+ # NOTE: Yes, support for the compile option is present.
+ #
+ addConstraint compile.$option
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForRuntimeOption { channel option } {
+ tputs $channel [appendArgs "---- checking for runtime option \"" \
+ $option "\"... "]
+
+ if {[info exists ::eagle_platform(runtimeOptions)] && \
+ [lsearch -exact -nocase $::eagle_platform(runtimeOptions) \
+ $option] != -1} then {
+ #
+ # NOTE: Yes, support for the runtime option is present.
+ #
+ addConstraint runtime.$option
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForDynamicLoading { channel } {
+ tputs $channel "---- checking for dynamic loading... "
+
+ #
+ # NOTE: As far as we know, dynamic loading always works on Windows.
+ # On some Unix systems, dlopen does not work (e.g. because
+ # Mono is statically linked, etc).
+ #
+ if {$::tcl_platform(platform) eq "windows" || \
+ ([llength [info commands library]] > 0 && \
+ [catch {library test}] == 0)} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint dynamic
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForWindowsForms { channel } {
+ tputs $channel "---- checking for Windows Forms... "
+
+ #
+ # HACK: When running on Windows, we do not need to do any other
+ # special checks here; however, on Unix (and Mac OS X?),
+ # we should check for the DISPLAY environment variable as
+ # some basic indication that the X server is available.
+ # This appears to be very necessary on Mono because it
+ # crashes after repeated failed attempts to create a
+ # Windows Form when the X server is unavailable (e.g. on
+ # OpenBSD).
+ #
+ if {$::tcl_platform(platform) eq "windows" || \
+ [info exists ::env(DISPLAY)]} then {
+ #
+ # NOTE: Is the Windows Forms assembly available?
+ #
+ if {[catch {object resolve System.Windows.Forms} assembly] == 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint winForms
+
+ tputs $channel yes\n
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForStaThread { channel } {
+ tputs $channel "---- checking for STA thread... "
+
+ if {[catch {object invoke System.Threading.Thread.CurrentThread \
+ GetApartmentState} apartmentState] == 0 && \
+ $apartmentState eq "STA"} then {
+ #
+ # NOTE: Yes, we are running in an STA thread.
+ #
+ addConstraint staThread
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForWindowsPresentationFoundation { channel } {
+ tputs $channel "---- checking for Windows Presentation Foundation... "
+
+ #
+ # NOTE: Is the Windows Presentation Foundation available?
+ #
+ if {[catch {object resolve PresentationFramework} assembly] == 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint wpf
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForDatabase { channel string } {
+ tputs $channel "---- checking for database... "
+
+ #
+ # HACK: Disable database connectivity testing on Mono because
+ # it fails to timeout (unless special test suite hacks
+ # for Mono have been disabled by the user).
+ #
+ if {[info exists ::no(mono)] || ![isMono]} then {
+ #
+ # NOTE: Can we access the local database?
+ #
+ if {[catch {sql open $string} connection] == 0} then {
+ #
+ # NOTE: Yes, it appears that we can connect to the local database.
+ #
+ addConstraint sql
+
+ #
+ # NOTE: Cleanup the database connection we just opened.
+ #
+ sql close $connection
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ } else {
+ tputs $channel "disabled\n"
+ }
+ }
+
+ proc checkForAssembly { channel name } {
+ tputs $channel [appendArgs "---- checking for assembly \"" $name \
+ "\"... "]
+
+ #
+ # NOTE: Can the assembly be loaded?
+ #
+ if {[catch {object resolve $name} assembly] == 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint $name
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForObjectMember { channel object member } {
+ tputs $channel [appendArgs "---- checking for object member \"" \
+ $object . $member "\"... "]
+
+ if {[catch {object members -flags +NonPublic -pattern $member $object} \
+ members] == 0 && [llength $members] > 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint $object.[string trim $member *?]
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTclInstalls { channel } {
+ tputs $channel "---- checking for Tcl installs... "
+
+ #
+ # NOTE: Check for dynamically loadable Tcl libraries (for this
+ # architecture only).
+ #
+ if {[catch {tcl select -architecture} tcl] == 0} then {
+ #
+ # NOTE: Did we find one? Attempt to grab the index
+ # of the version field from the list.
+ #
+ set index [lsearch -exact $tcl version]
+
+ if {$index != -1} then {
+ #
+ # NOTE: The very next list index contains the value
+ # (i.e. like a Tcl 8.5+ dict).
+ #
+ set dotVersion [lindex $tcl [incr index]]
+
+ #
+ # NOTE: Do we know the version?
+ #
+ if {[string length $dotVersion] > 0 && \
+ [regexp -- {^\d+\.\d+$} $dotVersion]} then {
+ #
+ # NOTE: Yes, some version of Tcl is available.
+ #
+ addConstraint tclLibrary
+
+ #
+ # NOTE: Is the version 8.x or higher?
+ #
+ if {$dotVersion >= 8.6} then {
+ addConstraint tclLibrary86
+ } elseif {$dotVersion >= 8.5} then {
+ addConstraint tclLibrary85
+ } elseif {$dotVersion >= 8.4} then {
+ addConstraint tclLibrary84
+ }
+
+ tputs $channel [appendArgs $dotVersion \n]
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForTclReady { channel } {
+ tputs $channel "---- checking for Tcl readiness... "
+
+ if {[catch {tcl ready} result] == 0 && $result} then {
+ #
+ # NOTE: Yes, native Tcl is loaded and ready.
+ #
+ addConstraint tclReady
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForTclShell { channel } {
+ #
+ # HACK: We do not care about the machine type returned from this
+ # procedure, we only care if it returns "error" because that
+ # would indicate an error was caught during [exec] (i.e. the
+ # native Tcl shell could not be executed).
+ #
+ if {[catch {getMachineForTclShell} result] == 0 && \
+ $result ne "error"} then {
+ #
+ # NOTE: Yes, a native Tcl shell appears to be available.
+ #
+ addConstraint tclShell
+
+ tputs $channel "---- checking for Tcl shell... yes\n"
+ } else {
+ tputs $channel "---- checking for Tcl shell... no\n"
+ }
+ }
+
+ proc checkForPowerShell { channel } {
+ tputs $channel "---- checking for PowerShell... "
+
+ #
+ # NOTE: Can the PowerShell assembly be loaded?
+ #
+ if {[catch {object resolve System.Management.Automation} \
+ assembly] == 0} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint powerShell
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForWix { channel } {
+ tputs $channel "---- checking for WiX... "
+
+ #
+ # NOTE: Platform must be Windows for this constraint to
+ # even be checked (i.e. we require the registry).
+ #
+ if {$::tcl_platform(platform) eq "windows"} then {
+ #
+ # NOTE: Indicate that we have not found it yet.
+ #
+ set directory ""
+
+ #
+ # NOTE: Have we not found the directory yet?
+ #
+ # Yes, this is somewhat redundant because we just set
+ # the directory to an empty string (above); however,
+ # maintaining a uniform pattern is more important.
+ #
+ if {[string length $directory] == 0} then {
+ #
+ # NOTE: Check for the WIX environment variable.
+ #
+ if {[info exists ::env(WIX)]} then {
+ set directory [file normalize [string trimright $::env(WIX)]]
+
+ if {[string length $directory] > 0} then {
+ #
+ # NOTE: We need the directory containing the binaries.
+ #
+ set directory [file join $directory bin]
+
+ #
+ # NOTE: Does the directory actually exist?
+ #
+ if {[file isdirectory $directory]} then {
+ #
+ # NOTE: The file name of the primary WiX assembly.
+ #
+ set fileName [file join $directory wix.dll]
+
+ #
+ # NOTE: We do not know the file version yet.
+ #
+ set version ""
+
+ #
+ # NOTE: Attempt to query the version of the file.
+ #
+ if {[catch {file version $fileName} version] == 0 && \
+ [string length $version] > 0} then {
+ #
+ # NOTE: Indicate where we found the file.
+ #
+ set where environment
+ } else {
+ #
+ # NOTE: The file does not exist or is not properly
+ # versioned.
+ #
+ set directory ""
+ }
+ } else {
+ #
+ # NOTE: The directory does not exist.
+ #
+ set directory ""
+ }
+ }
+ }
+ }
+
+ #
+ # NOTE: Have we not found the directory yet?
+ #
+ if {[string length $directory] == 0} then {
+ #
+ # NOTE: Registry hive where WiX install information
+ # is stored.
+ #
+ set key {HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML}
+
+ #
+ # NOTE: The versions of WiX that we support.
+ #
+ set versions [list 3.5 3.0]
+
+ #
+ # NOTE: Check each version, stopping when one is found.
+ #
+ foreach version $versions {
+ #
+ # NOTE: Attempt to fetch the WiX install directory
+ # value from the registry, removing the
+ # trailing backslash, if any.
+ #
+ set directory [file normalize [string trimright [object invoke \
+ Microsoft.Win32.Registry GetValue \
+ [appendArgs $key \\ $version] InstallRoot \
+ null] \\]]
+
+ #
+ # NOTE: Does the directory name look valid and
+ # does it actually exist?
+ #
+ if {[string length $directory] > 0} then {
+ #
+ # NOTE: Does the directory actually exist?
+ #
+ if {[file isdirectory $directory]} then {
+ #
+ # NOTE: The file name of the primary WiX assembly.
+ #
+ set fileName [file join $directory wix.dll]
+
+ #
+ # NOTE: We do not know the file version yet.
+ #
+ set version ""
+
+ #
+ # NOTE: Attempt to query the version of the file.
+ #
+ if {[catch {file version $fileName} version] == 0 && \
+ [string length $version] > 0} then {
+ #
+ # NOTE: Indicate where we found the file.
+ #
+ set where registry
+
+ #
+ # NOTE: We found it, bail out now.
+ #
+ break
+ } else {
+ #
+ # NOTE: The file does not exist or is not properly
+ # versioned.
+ #
+ set directory ""
+ }
+ } else {
+ #
+ # NOTE: The directory does not exist.
+ #
+ set directory ""
+ }
+ }
+ }
+ }
+
+ #
+ # NOTE: Did we find the directory?
+ #
+ if {[string length $directory] > 0 && \
+ [file isdirectory $directory]} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint wix
+
+ #
+ # NOTE: Save the directory for later usage by
+ # the test itself.
+ #
+ set ::test_wix $directory
+
+ #
+ # NOTE: Show where we found it.
+ #
+ tputs $channel [appendArgs "yes (" $version ", via " $where ", \"" \
+ $directory "\")\n"]
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForManagedDebugger { channel } {
+ tputs $channel "---- checking for managed debugger... "
+
+ #
+ # NOTE: Is the managed debugger attached?
+ #
+ if {[object invoke System.Diagnostics.Debugger IsAttached]} then {
+ #
+ # NOTE: Yes, it appears that it is attached.
+ #
+ addConstraint managedDebugger
+
+ tputs $channel yes\n
+ } else {
+ tputs $channel no\n
+ }
+ }
+
+ proc checkForScriptDebugger { channel } {
+ tputs $channel "---- checking for script debugger... "
+
+ #
+ # NOTE: Is the script debugger available?
+ #
+ if {[catch {object invoke -flags +NonPublic Interpreter.GetActive \
+ Debugger} debugger] == 0} then {
+ #
+ # NOTE: We do not own this, do not dispose it.
+ #
+ if {[string length $debugger] > 0} then {
+ object flags $debugger +NoDispose
+ }
+
+ if {[regexp -- {^Debugger#\d+$} $debugger]} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint scriptDebugger
+
+ tputs $channel yes\n
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ proc checkForScriptDebuggerInterpreter { channel } {
+ tputs $channel "---- checking for script debugger interpreter... "
+
+ #
+ # NOTE: Is the script debugger interpreter available?
+ #
+ if {[catch {object invoke -flags +NonPublic Interpreter.GetActive \
+ Debugger} debugger] == 0} then {
+ #
+ # NOTE: We do not own this, do not dispose it.
+ #
+ if {[string length $debugger] > 0} then {
+ object flags $debugger +NoDispose
+ }
+
+ if {[regexp -- {^Debugger#\d+$} $debugger] && \
+ [catch {object invoke $debugger Interpreter} interp] == 0} then {
+ #
+ # NOTE: We do not own this, do not dispose it.
+ #
+ if {[string length $interp] > 0} then {
+ object flags $interp +NoDispose
+ }
+
+ if {[regexp -- {^Interpreter#\d+$} $interp]} then {
+ #
+ # NOTE: Yes, it appears that it is available.
+ #
+ addConstraint scriptDebuggerInterpreter
+
+ tputs $channel yes\n
+
+ #
+ # NOTE: We are done here, return now.
+ #
+ return
+ }
+ }
+ }
+
+ tputs $channel no\n
+ }
+
+ ###########################################################################
+ ############################# END Eagle ONLY ##############################
+ ###########################################################################
+ } else {
+ ###########################################################################
+ ############################# BEGIN Tcl ONLY ##############################
+ ###########################################################################
+
+ #
+ # NOTE: We need several of our test constraint related commands in the
+ # global namespace.
+ #
+ exportAndImportPackageCommands [namespace current] [list checkForPlatform \
+ checkForEagle checkForGaruda checkForShell checkForDebug \
+ checkForVersion checkForCommand checkForFile checkForNativeCode \
+ checkForTip127 checkForTip194 checkForTip241 checkForTip285 \
+ checkForPerformance checkForTiming checkForInteractive \
+ checkForUserInteraction checkForNetwork] false false
+
+ ###########################################################################
+ ############################## END Tcl ONLY ###############################
+ ###########################################################################
+ }
+
+ #
+ # NOTE: Provide the Eagle test constraints package to the interpreter.
+ #
+ package provide EagleTestConstraints \
+ [expr {[isEagle] ? [info engine PatchLevel] : 1.0}]
+}
+
ADDED Externals/Eagle/Tests/epilogue.eagle
Index: Externals/Eagle/Tests/epilogue.eagle
==================================================================
--- /dev/null
+++ Externals/Eagle/Tests/epilogue.eagle
@@ -0,0 +1,281 @@
+###############################################################################
+#
+# epilogue.eagle --
+#
+# Extensible Adaptable Generalized Logic Engine (Eagle)
+# Test Epilogue File
+#
+# Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+#
+###############################################################################
+
+if {![info exists no([file tail [info script]])]} then {
+ if {[info level] > 0} then {
+ error "cannot run, current level is not global"
+ }
+
+ if {[isEagle]} then {
+ #
+ # NOTE: Show the current state of the memory.
+ #
+ tputs $test_channel [appendArgs "---- ending memory: " \
+ [formatListAsDict [debug memory]] \n]
+
+ #
+ # NOTE: Show the current state of the native stack.
+ #
+ catch {debug stack true} stack
+
+ tputs $test_channel [appendArgs "---- ending stack: " \
+ [formatListAsDict $stack] \n]
+
+ unset stack
+ }
+
+ #
+ # NOTE: Show when the tests actually ended (now).
+ #
+ tputs $test_channel [appendArgs "---- tests ended at " \
+ [clock format [clock seconds]] \n]
+
+ if {[isEagle]} then {
+ tputs $test_channel \n; # NOTE: Blank line.
+
+ if {$eagle_tests(passed) > 0} then {
+ host result Ok [appendArgs "PASSED: " $eagle_tests(passed) \n]
+ tlog [appendArgs "PASSED: " $eagle_tests(passed) \n]
+ }
+
+ if {$eagle_tests(failed) > 0} then {
+ host result Error [appendArgs "FAILED: " $eagle_tests(failed) \n]
+ tlog [appendArgs "FAILED: " $eagle_tests(failed) \n]
+
+ if {[llength $eagle_tests(failedNames)] > 0} then {
+ host result Error [appendArgs "FAILED: " $eagle_tests(failedNames) \n]
+ tlog [appendArgs "FAILED: " $eagle_tests(failedNames) \n]
+ }
+ }
+
+ if {$eagle_tests(skipped) > 0} then {
+ host result Break [appendArgs "SKIPPED: " $eagle_tests(skipped) \n]
+ tlog [appendArgs "SKIPPED: " $eagle_tests(skipped) \n]
+ }
+
+ if {$eagle_tests(total) > 0} then {
+ host result Return [appendArgs "TOTAL: " $eagle_tests(total) \n]
+ tlog [appendArgs "TOTAL: " $eagle_tests(total) \n]
+
+ #
+ # HACK: Temporarily modify the floating point precision so that the
+ # pass percentage does not end up with excessive detail. In
+ # theory, we could use [string format] here; however, that
+ # would fail under Mono.
+ #
+ if {$tcl_precision != 4} then {
+ set tcl_precision_save $tcl_precision
+ set tcl_precision 4
+ }
+
+ if {$eagle_tests(skipped) > 0} then {
+ set percent [getSkipPercentage]
+ host result Break [appendArgs "SKIP PERCENTAGE: " $percent %\n]
+ tlog [appendArgs "SKIP PERCENTAGE: " $percent %\n]
+ }
+
+ set percent [getPassPercentage]
+ host result Return [appendArgs "PASS PERCENTAGE: " $percent %\n]
+ tlog [appendArgs "PASS PERCENTAGE: " $percent% \n]
+
+ #
+ # NOTE: Restore the saved floating point precision.
+ #
+ if {[info exists tcl_precision_save]} then {
+ set tcl_precision $tcl_precision_save
+ unset tcl_precision_save
+ }
+ } else {
+ #
+ # NOTE: No tests.
+ #
+ set percent 0
+ }
+
+ #
+ # NOTE: Has the test pass threshold been set? If so, is it set to
+ # the default value?
+ #
+ if {![info exists test_threshold] || $test_threshold == 100} then {
+ #
+ # NOTE: The test pass threshold is set to the default value (100%).
+ # Check to make sure that all tests pass and then set the
+ # exit code to success; otherwise, we set it to failure.
+ #
+ set passedOrSkipped [expr {$eagle_tests(passed) + \
+ $eagle_tests(skipped)}]
+
+ if {$passedOrSkipped == $eagle_tests(total)} then {
+ set exitCode Success
+
+ host result Ok "OVERALL RESULT: SUCCESS\n"
+ tlog "OVERALL RESULT: SUCCESS\n"
+ } else {
+ set exitCode Failure
+
+ host result Error "OVERALL RESULT: FAILURE\n"
+ tlog "OVERALL RESULT: FAILURE\n"
+ }
+
+ unset passedOrSkipped
+ } else {
+ #
+ # NOTE: They specified a non-default test pass threshold. Check to
+ # make sure that we meet or exceed the requirement and then
+ # set the exit code to success; otherwise, set it to failure.
+ #
+ if {$percent >= $test_threshold} then {
+ set exitCode Success
+
+ host result Ok [appendArgs "OVERALL RESULT: SUCCESS (" \
+ $percent "% >= " $test_threshold %)\n]
+
+ tlog [appendArgs "OVERALL RESULT: SUCCESS (" \
+ $percent "% >= " $test_threshold %)\n]
+ } else {
+ set exitCode Failure
+
+ host result Error [appendArgs \
+ "OVERALL RESULT: FAILURE (" $percent "% < " $test_threshold %)\n]
+
+ tlog [appendArgs \
+ "OVERALL RESULT: FAILURE (" $percent "% < " $test_threshold %)\n]
+ }
+ }
+
+ unset percent
+
+ tputs $test_channel \n; # NOTE: Blank line.
+ } else {
+ tputs $test_channel \n; # NOTE: Blank line.
+
+ if {$::tcltest::numTests(Passed) > 0} then {
+ tputs $test_channel \
+ [appendArgs "PASSED: " $::tcltest::numTests(Passed) \n]
+ }
+
+ if {$::tcltest::numTests(Failed) > 0} then {
+ tputs $test_channel \
+ [appendArgs "FAILED: " $::tcltest::numTests(Failed) \n]
+
+ if {[llength $::tcltest::failFiles] > 0} then {
+ tputs $test_channel \
+ [appendArgs "FAILED: " $::tcltest::failFiles \n]
+ }
+ }
+
+ if {$::tcltest::numTests(Skipped) > 0} then {
+ tputs $test_channel \
+ [appendArgs "SKIPPED: " $::tcltest::numTests(Skipped) \n]
+ }
+
+ if {$::tcltest::numTests(Total) > 0} then {
+ tputs $test_channel \
+ [appendArgs "TOTAL: " $::tcltest::numTests(Total) \n]
+
+ if {$::tcltest::numTests(Skipped) > 0} then {
+ set percent [getSkipPercentage]
+ tputs $test_channel [appendArgs "SKIP PERCENTAGE: " \
+ [format "%.4f" $percent] %\n]
+ }
+
+ set percent [getPassPercentage]
+ tputs $test_channel [appendArgs "PASS PERCENTAGE: " \
+ [format "%.4f" $percent] %\n]
+ } else {
+ #
+ # NOTE: No tests.
+ #
+ set percent 0
+ }
+
+ #
+ # NOTE: Has the test pass threshold been set? If so, is it set to
+ # the default value?
+ #
+ if {![info exists test_threshold] || $test_threshold == 100} then {
+ #
+ # NOTE: The test pass threshold is set to the default value (100%).
+ # Check to make sure that all tests pass and then set the
+ # exit code to success; otherwise, we set it to failure.
+ #
+ set passedOrSkipped [expr {$::tcltest::numTests(Passed) + \
+ $::tcltest::numTests(Skipped)}]
+
+ if {$passedOrSkipped == $::tcltest::numTests(Total)} then {
+ set exitCode 0; # Success.
+
+ tputs $test_channel "OVERALL RESULT: SUCCESS\n"
+ } else {
+ set exitCode 1; # Failure.
+
+ tputs $test_channel "OVERALL RESULT: FAILURE\n"
+ }
+
+ unset passedOrSkipped
+ } else {
+ #
+ # NOTE: They specified a non-default test pass threshold. Check to
+ # make sure that we meet or exceed the requirement and then
+ # set the exit code to success; otherwise, set it to failure.
+ #
+ if {$percent >= $test_threshold} then {
+ set exitCode 0; # Success.
+
+ tputs $test_channel [appendArgs "OVERALL RESULT: SUCCESS (" \
+ $percent "% >= " $test_threshold %)\n]
+ } else {
+ set exitCode 1; # Failure.
+
+ tputs $test_channel [appendArgs "OVERALL RESULT: FAILURE (" \
+ $percent "% < " $test_threshold %)\n]
+ }
+ }
+
+ unset percent
+
+ tputs $test_channel \n; # NOTE: Blank line.
+ }
+
+ #
+ # NOTE: Check for and process any custom test epilogue script that may
+ # be set in the environment.
+ #
+ sourceIfValid epilogue [getEnvironmentVariable testEpilogue]
+
+ #
+ # NOTE: Do we need to exit now?
+ #
+ if {[isExitOnComplete]} then {
+ #
+ # NOTE: Exit now. In Eagle, this will not exit the entire process.
+ # Zero (0) will be the exit code if all the selected tests have
+ # succeeded or the test success threshold has been met or
+ # exceeded; otherwise, one (1) will be the exit code.
+ #
+ exit $exitCode
+ } else {
+ #
+ # NOTE: For Eagle, even when not exiting, we still set the ExitCode
+ # property of the interpreter.
+ #
+ if {[isEagle]} then {
+ object invoke -alias Interpreter.GetActive ExitCode $exitCode
+ }
+
+ unset exitCode
+ }
+}
ADDED Externals/Eagle/Tests/pkgIndex.eagle
Index: Externals/Eagle/Tests/pkgIndex.eagle
==================================================================
--- /dev/null
+++ Externals/Eagle/Tests/pkgIndex.eagle
@@ -0,0 +1,21 @@
+###############################################################################
+#
+# pkgIndex.eagle --
+#
+# Extensible Adaptable Generalized Logic Engine (Eagle)
+# Package Index File
+#
+# Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+#
+###############################################################################
+
+if {![package vsatisfies [package provide Tcl] 8.4]} {return}
+if {![package vsatisfies [package provide Eagle] 1.0]} {return}
+
+package ifneeded EagleTestConstraints 1.0 [list source [file join $dir \
+ constraints.eagle]]
ADDED Externals/Eagle/Tests/pkgIndex.tcl
Index: Externals/Eagle/Tests/pkgIndex.tcl
==================================================================
--- /dev/null
+++ Externals/Eagle/Tests/pkgIndex.tcl
@@ -0,0 +1,21 @@
+###############################################################################
+#
+# pkgIndex.tcl --
+#
+# Extensible Adaptable Generalized Logic Engine (Eagle)
+# Package Index File
+#
+# Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+#
+###############################################################################
+
+if {![package vsatisfies [package provide Tcl] 8.4]} {return}
+if {[string length [package provide Eagle]] > 0} then {return}
+
+package ifneeded EagleTestConstraints 1.0 [list source [file join $dir \
+ constraints.eagle]]
ADDED Externals/Eagle/Tests/prologue.eagle
Index: Externals/Eagle/Tests/prologue.eagle
==================================================================
--- /dev/null
+++ Externals/Eagle/Tests/prologue.eagle
@@ -0,0 +1,1481 @@
+###############################################################################
+#
+# prologue.eagle --
+#
+# Extensible Adaptable Generalized Logic Engine (Eagle)
+# Test Prologue File
+#
+# Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+#
+###############################################################################
+
+if {![info exists no([file tail [info script]])]} then {
+ if {[info level] > 0} then {
+ error "cannot run, current level is not global"
+ }
+
+ #
+ # NOTE: Set the location of the test suite, if necessary.
+ #
+ if {![info exists test_path]} then {
+ set test_path [file normalize [file dirname [info script]]]
+ }
+
+ #
+ # NOTE: Set the location of the base Eagle directory, if
+ # necessary.
+ #
+ if {![info exists base_path]} then {
+ #
+ # NOTE: Start out going up one level and check for a "lib"
+ # sub-directory. If not found, go up another level
+ # because we will always be two levels down from the
+ # base directory when running inside the source tree.
+ #
+ set base_path [file normalize [file dirname $test_path]]
+
+ #
+ # HACK: We must verify that the "init.eagle" file can eventually
+ # be found under the "lib" directory since Visual Studio
+ # insists on creating a superfluous (and empty) "lib\Eagle1.0"
+ # sub-directory inside of the "Library" project directory
+ # simply due to the links contained in the project file that
+ # actually point to the "lib\Eagle1.0" sub-directory under the
+ # solution directory.
+ #
+ # WARNING: The Eagle package name and version are hard-coded here.
+ #
+ if {![file exists [file join $base_path lib]] || \
+ ![file isdirectory [file join $base_path lib]] || \
+ ![file exists [file join $base_path lib Eagle1.0]] || \
+ ![file isdirectory [file join $base_path lib Eagle1.0]] || \
+ ![file exists [file join $base_path lib Eagle1.0 init.eagle]] || \
+ ![file isfile [file join $base_path lib Eagle1.0 init.eagle]]} then {
+ #
+ # NOTE: We do not bother to check if the "lib" sub-directory
+ # actually exists as a child of this one. This is the
+ # previous (legacy) behavior (i.e. where we always went
+ # up two levels to the base directory).
+ #
+ set base_path [file dirname $base_path]
+ }
+ }
+
+ #
+ # NOTE: Set the executable file name for the process, if
+ # necessary.
+ #
+ if {![info exists bin_file]} then {
+ set bin_file [info nameofexecutable]
+ }
+
+ #
+ # NOTE: Set the location of the directory containing the
+ # executable file for the process, if necessary.
+ #
+ if {![info exists bin_path]} then {
+ set bin_path [file normalize [file dirname $bin_file]]
+ }
+
+ #
+ # NOTE: Set the location of the [non-script] library directory
+ # (i.e. the directory where the plugins are located), if
+ # necessary.
+ #
+ if {![info exists lib_path]} then {
+ #
+ # NOTE: This should go one directory up from the directory
+ # containing the executable file for the process (e.g.
+ # the shell) and then into the "lib" directory just
+ # beneath that.
+ #
+ set lib_path [file normalize [file join [file dirname $bin_path] lib]]
+ }
+
+ #
+ # NOTE: Set the web host to test against, if necessary.
+ #
+ if {![info exists test_host]} then {
+ set test_host eagle.to
+ }
+
+ #
+ # NOTE: Set the port to use for server sockets, if necessary.
+ #
+ if {![info exists test_port]} then {
+ set test_port 12346; # IANA, 12346-12752 Unassigned
+ }
+
+ #
+ # NOTE: Set the network timeout, if necessary.
+ #
+ if {![info exists test_timeout]} then {
+ set test_timeout 2000; # in milliseconds.
+ }
+
+ #
+ # NOTE: Set the channel to use for test output, if necessary.
+ #
+ if {![info exists test_channel]} then {
+ set test_channel stdout
+ }
+
+ #
+ # NOTE: Set the primary package path, if necessary.
+ #
+ if {![info exists test_package_path]} then {
+ set test_package_path [file join $base_path lib]
+ }
+
+ #
+ # NOTE: Make sure our primary package path is part of the auto path.
+ #
+ if {[lsearch -exact $auto_path $test_package_path] == -1} then {
+ lappend auto_path $test_package_path
+ }
+
+ #
+ # NOTE: Make sure our test package path is part of the auto path.
+ #
+ if {[lsearch -exact $auto_path $test_path] == -1} then {
+ lappend auto_path $test_path
+ }
+
+ #############################################################################
+
+ #
+ # NOTE: Check for and load the Eagle library package, if necessary.
+ #
+ if {[catch {package present EagleLibrary}]} then {
+ package require EagleLibrary
+ }
+
+ #
+ # NOTE: Check for and load the Eagle test package, if necessary.
+ #
+ if {[catch {package present EagleTest}]} then {
+ package require EagleTest
+ }
+
+ #
+ # NOTE: Check for and load the Eagle test constraints package, if
+ # necessary.
+ #
+ if {[catch {package present EagleTestConstraints}]} then {
+ package require EagleTestConstraints
+ }
+
+ #############################################################################
+
+ #
+ # NOTE: If command line arguments were supplied, process them now.
+ #
+ set test_flags(-configuration) ""; # build configuration, default to empty.
+ set test_flags(-suffix) ""; # build suffix, default to empty.
+ set test_flags(-file) [list *.eagle]; # default to running all test files.
+ set test_flags(-notFile) [list l.*.eagle]; # COMPAT: Tcl.
+ set test_flags(-match) [list *]; # default to running all tests.
+ set test_flags(-skip) [list]; # default to skipping no tests.
+ set test_flags(-constraints) [list]; # default to no manual constraints.
+ set test_flags(-logFile) ""; # default to using standard log file naming.
+ set test_flags(-threshold) ""; # default to requiring all tests to pass.
+ set test_flags(-stopOnFailure) ""; # default to continue on failure.
+ set test_flags(-exitOnComplete) ""; # default to not exit after complete.
+
+ #
+ # NOTE: Check for and process any command line arguments.
+ #
+ if {[info exists argv]} then {
+ eval processTestArguments test_flags $argv
+
+ if {[info exists test_flags(-logFile)] && \
+ [string length $test_flags(-logFile)] > 0} then {
+ #
+ # NOTE: Set the log file name to the one provided by the command line.
+ #
+ set test_log $test_flags(-logFile)
+ }
+
+ if {[info exists test_flags(-threshold)] && \
+ [string is integer -strict $test_flags(-threshold)]} then {
+ #
+ # NOTE: Set the test pass threshold to the one provided by the command
+ # line.
+ #
+ set test_threshold $test_flags(-threshold)
+ }
+
+ if {[info exists test_flags(-stopOnFailure)] && \
+ [string is boolean -strict $test_flags(-stopOnFailure)]} then {
+ #
+ # NOTE: Set the test stop-on-failure flag to the one provided by the
+ # command line.
+ #
+ set test_stop_on_failure $test_flags(-stopOnFailure)
+ }
+
+ if {[info exists test_flags(-exitOnComplete)] && \
+ [string is boolean -strict $test_flags(-exitOnComplete)]} then {
+ #
+ # NOTE: Set the test exit-on-complete flag to the one provided by the
+ # command line.
+ #
+ set test_exit_on_complete $test_flags(-exitOnComplete)
+ }
+ }
+
+ #
+ # NOTE: Set the default test configuration (i.e. Debug or Release), if
+ # necessary.
+ #
+ if {![info exists test_configuration]} then {
+ set test_configuration [getPlatformInfo configuration Release]
+ }
+
+ #
+ # NOTE: Set the Tcl shell executable to use for those specialized
+ # tests that may require it, if necessary.
+ #
+ if {![info exists test_tclsh]} then {
+ if {[isEagle] || ![string match tclsh* $bin_file]} then {
+ set test_tclsh tclsh
+ } else {
+ set test_tclsh $bin_file
+ }
+ }
+
+ #
+ # NOTE: Has logging been disabled?
+ #
+ if {![info exists no(log)]} then {
+ #
+ # NOTE: Set the log to use for test output, if necessary.
+ #
+ if {![info exists test_log]} then {
+ set test_log [file join [getTemporaryPath] [file tail [info \
+ nameofexecutable]][getTestLogId].test.[pid].log]
+ }
+ }
+
+ #
+ # NOTE: Check for and process any custom test prologue script that may be set
+ # in the environment. This must be done after the Eagle test package
+ # has been made available and after the log file has been setup.
+ #
+ sourceIfValid prologue [getEnvironmentVariable testPrologue]
+
+ #
+ # NOTE: Show the name of the executable and the command line arguments, if
+ # any. This must be done after the log file has been setup; otherwise,
+ # this information will not be visible in the log file.
+ #
+ tputs $test_channel [appendArgs "---- testRunId: " \
+ [getTestRunId] \n]
+
+ tputs $test_channel [appendArgs "---- processId: " \
+ [pid] \n]
+
+ tputs $test_channel [appendArgs "---- test channel: " \
+ $test_channel \n]
+
+ tputs $test_channel [appendArgs "---- test configuration: " \
+ $test_configuration \n]
+
+ if {[isEagle]} then {
+ tputs $test_channel [appendArgs "---- original command line: " \
+ [info cmdline] \n]
+
+ tputs $test_channel [appendArgs "---- threadId: " \
+ [info tid] \n]
+
+ tputs $test_channel [appendArgs "---- processors: " \
+ [info processors] \n]
+
+ catch {object invoke Console.InputEncoding WebName} encoding
+
+ tputs $test_channel [appendArgs "---- input encoding: " \
+ $encoding \n]
+
+ catch {object invoke Console.OutputEncoding WebName} encoding
+
+ tputs $test_channel [appendArgs "---- output encoding: " \
+ $encoding \n]
+
+ tputs $test_channel [appendArgs "---- starting memory: " \
+ [formatListAsDict [debug memory]] \n]
+
+ catch {debug stack true} stack
+
+ tputs $test_channel [appendArgs "---- starting stack: " \
+ [formatListAsDict $stack] \n]
+
+ unset stack
+ catch {file drive} drive
+
+ tputs $test_channel [appendArgs "---- system drive: " \
+ [formatListAsDict $drive] \n]
+
+ unset drive
+ }
+
+ tputs $test_channel [appendArgs "---- executable: \"" \
+ $bin_file \"\n]
+
+ tputs $test_channel [appendArgs "---- command line: " \
+ [expr {[info exists argv] && [string length $argv] > 0 ? \
+ $argv : "