System.Data.SQLite
Check-in [90c8dbfba8]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update Eagle script library in externals to pre-Beta 42.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | netStandard20
Files: files | file ages | folders
SHA1: 90c8dbfba857c67ea33a2ef1b09e344d8a50bd6e
User & Date: mistachkin 2018-04-05 15:27:28
Context
2018-04-06
04:36
Minor correction to the build batch file. check-in: 3087e8c659 user: mistachkin tags: netStandard20
2018-04-05
15:27
Update Eagle script library in externals to pre-Beta 42. check-in: 90c8dbfba8 user: mistachkin tags: netStandard20
15:25
Work around inability of .NET Core SDK to properly generate resources from a 'resx' file that refers to other files. check-in: 681cdd1dde user: mistachkin tags: netStandard20
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Externals/Eagle/lib/Eagle1.0/exec.eagle.

50
51
52
53
54
55
56











57
58
59
60
61
62
63
      #
      # HACK: Assume that Mono is somewhere along the PATH.
      #
      lappend command mono \
          [appendArgs \" [file nativename [info nameofexecutable]] \"]
    } else {
      lappend command [info nameofexecutable]











    }

    #
    # NOTE: If possible, check if the current interpreter has security
    #       enabled; if so, add the appropriate command line option for
    #       the sub-process.
    #







>
>
>
>
>
>
>
>
>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
      #
      # HACK: Assume that Mono is somewhere along the PATH.
      #
      lappend command mono \
          [appendArgs \" [file nativename [info nameofexecutable]] \"]
    } else {
      lappend command [info nameofexecutable]

      #
      # HACK: When running on .NET Core, we need to insert the "exec"
      #       command line argument followed by our assembly name.
      #
      if {[isEagle] && [isDotNetCore]} then {
        lappend command exec

        lappend command [appendArgs \" \
            [file nativename [lindex [info assembly true] 1]] \"]
      }
    }

    #
    # NOTE: If possible, check if the current interpreter has security
    #       enabled; if so, add the appropriate command line option for
    #       the sub-process.
    #

Changes to Externals/Eagle/lib/Eagle1.0/info.eagle.

79
80
81
82
83
84
85









































































86
87
88
89
90
91
92
      if {[regexp -- $pattern [lindex $loaded end]]} then {
        return [lindex $loaded 0]
      }
    }

    return ""
  }









































































 
  #
  # NOTE: This procedure returns the Eagle core library base path, e.g. a
  #       value like "C:\Eagle" when loaded from "C:\Eagle\bin\Eagle.dll".
  #
  proc getBasePath {} {
    set assembly [object invoke -flags +NonPublic \







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
      if {[regexp -- $pattern [lindex $loaded end]]} then {
        return [lindex $loaded 0]
      }
    }

    return ""
  }
 
  #
  # NOTE: This procedure returns the fully qualified directory name where new
  #       packages targeting the interpreter should be installed.  The return
  #       values of this procedure are subject to change in future releases.
  #
  proc getPackageInstallPath { {packageName ""} {temporaryPrefix ""} } {
    #
    # NOTE: Skip using the Tcl library location if that has been explicitly
    #       forbidden.
    #
    if {![info exists ::no(getPackageInstallPath)]} then {
      #
      # NOTE: First, check if the Tcl library variable exists and its location
      #       exists.  The location may refer to a file.
      #
      global tcl_library

      if {[info exists tcl_library]} then {
        #
        # NOTE: What is the parent directory for the Tcl library location?  If
        #       the Tcl library location was a file, it should be a directory;
        #       if it was already a directory, it should still be one.  Either
        #       way, the new (directory) location must be writable.
        #
        set directory [file dirname $tcl_library]

        if {[file exists $directory] && [file isdirectory $directory] && \
            [file writable $directory]} then {
          #
          # NOTE: Ok, all checks passed, return the location.  Callers of this
          #       procedure should generally not put files directly within it;
          #       instead, they should create a sub-directory within it, named
          #       appropriately.  If a package name was supplied by the caller
          #       it will be used.  In that case, the resulting directory will
          #       be created if necessary.
          #
          if {[string length $packageName] > 0} then {
            set directory [file join $directory $packageName]
            file mkdir $directory
          }

          return $directory
        }
      }
    }

    #
    # NOTE: Next, since the fallback location requires the test package, load
    #       it now.
    #
    package require Eagle.Test

    #
    # NOTE: Return the temporary directory as the fallback location.  Callers
    #       of this procedure should generally not put files directly within
    #       it; instead, they should create a sub-directory within it, named
    #       appropriately.  If a temporary prefix was supplied by the caller
    #       it will be used.  In that case, the resulting directory will be
    #       created if necessary.
    #
    set directory [getTemporaryPath]

    if {[string length $temporaryPrefix] > 0} then {
      set directory [file join \
          $directory [appendArgs $temporaryPrefix - \
          [pid] - [string trim [clock seconds] -]]]

      file mkdir $directory
    }

    return $directory
  }
 
  #
  # NOTE: This procedure returns the Eagle core library base path, e.g. a
  #       value like "C:\Eagle" when loaded from "C:\Eagle\bin\Eagle.dll".
  #
  proc getBasePath {} {
    set assembly [object invoke -flags +NonPublic \

Changes to Externals/Eagle/lib/Eagle1.0/init.eagle.

109
110
111
112
113
114
115























116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    }

    #
    # NOTE: Success, return an empty string.
    #
    return ""
  }























 
  if {![interp issafe]} then {
    #
    # NOTE: Load the extra script library files that contain commonly used
    #       procedures that are shared between native Tcl and Eagle.
    #
    loadScripts [file dirname [info script]] [list \
        auxiliary.eagle database.eagle exec.eagle file1.eagle \
        file2.eagle file3.eagle info.eagle list.eagle \
        pkgt.eagle platform.eagle testlog.eagle unzip.eagle]

    #
    # NOTE: Load the extra script library files that contain procedures that
    #       require a specific language (i.e. either native Tcl or Eagle).
    #
    if {[isEagle]} then {
      loadScripts [file dirname [info script]] [list \
          compat.eagle csharp.eagle object.eagle process.eagle \
          runopt.eagle unkobj.eagle update.eagle]
    } else {
      loadScripts [file dirname [info script]] [list shim.eagle]
    }
  }
 
  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################
................................................................................
      }
    }
 
    #
    # NOTE: Add script library files borrowed from native Tcl.
    #
    if {![interp issafe]} then {
      loadScripts [file dirname [info script]] [list word.tcl]
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
................................................................................

    #
    # NOTE: Exports the necessary commands from this package and import them
    #       into the global namespace.
    #
    if {[llength [info commands exportAndImportPackageCommands]] > 0} then {
      exportAndImportPackageCommands [namespace current] [list \
          isEagle loadScripts isWindows isInteractive haveGaruda \
          isTclThread isMono isSameFileName getEnvironmentVariable \
          combineFlags getCompileInfo getPlatformInfo getPluginName \
          getPluginPath appendArgs lappendArgs getDictionaryValue \
          getColumnValue getRowColumnValue tqputs tqlog \
          makeBinaryChannel makeAsciiChannel makeUnicodeChannel \
          makeLogChannel readFile readSharedFile writeFile appendFile \
          appendLogFile appendSharedFile appendSharedLogFile \
          readAsciiFile writeAsciiFile readUnicodeFile \
          writeUnicodeFile getDirResultPath addToPath removeFromPath \
          execShell lshuffle ldifference filter map reduce \
          getLengthModifier debug findDirectories \
          findDirectoriesRecursive findFiles findFilesRecursive \







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|









|



|







 







|







 







|
|
|
|
|
|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
    }

    #
    # NOTE: Success, return an empty string.
    #
    return ""
  }
 
  #
  # NOTE: This procedure is designed to "load" (i.e. [source]) other script
  #       files that logically belong to the package defined in this script
  #       file.  Upon success, an empty string will be returned.  A script
  #       error may be raised.  This should work properly in both Tcl and
  #       Eagle.  This procedure must be defined in this script file because
  #       it is needed while this script file is being evaluated.  If there
  #       exists a global array element no($fileNameOnly) corresponding to a
  #       particular script file to be loaded, it will be skipped.
  #
  # <bootstrap>
  proc maybeLoadScripts { directory fileNamesOnly } {
    set matchFileNames [list]

    foreach fileNameOnly $fileNamesOnly {
      if {![info exists ::no($fileNameOnly)]} then {
        lappend matchFileNames $fileNameOnly
      }
    }

    return [uplevel 1 [list loadScripts $directory $matchFileNames]]
  }
 
  if {![interp issafe]} then {
    #
    # NOTE: Load the extra script library files that contain commonly used
    #       procedures that are shared between native Tcl and Eagle.
    #
    maybeLoadScripts [file dirname [info script]] [list \
        auxiliary.eagle database.eagle exec.eagle file1.eagle \
        file2.eagle file3.eagle info.eagle list.eagle \
        pkgt.eagle platform.eagle testlog.eagle unzip.eagle]

    #
    # NOTE: Load the extra script library files that contain procedures that
    #       require a specific language (i.e. either native Tcl or Eagle).
    #
    if {[isEagle]} then {
      maybeLoadScripts [file dirname [info script]] [list \
          compat.eagle csharp.eagle object.eagle process.eagle \
          runopt.eagle unkobj.eagle update.eagle]
    } else {
      maybeLoadScripts [file dirname [info script]] [list shim.eagle]
    }
  }
 
  if {[isEagle]} then {
    ###########################################################################
    ############################ BEGIN Eagle ONLY #############################
    ###########################################################################
................................................................................
      }
    }
 
    #
    # NOTE: Add script library files borrowed from native Tcl.
    #
    if {![interp issafe]} then {
      maybeLoadScripts [file dirname [info script]] [list word.tcl]
    }

    ###########################################################################
    ############################# END Eagle ONLY ##############################
    ###########################################################################
  } else {
    ###########################################################################
................................................................................

    #
    # NOTE: Exports the necessary commands from this package and import them
    #       into the global namespace.
    #
    if {[llength [info commands exportAndImportPackageCommands]] > 0} then {
      exportAndImportPackageCommands [namespace current] [list \
          isEagle loadScripts maybeLoadScripts isWindows isInteractive \
          haveGaruda isTclThread isMono isDotNetCore isSameFileName \
          getEnvironmentVariable combineFlags getCompileInfo getPlatformInfo \
          getPluginName getPluginPath getPackageInstallPath appendArgs \
          lappendArgs getDictionaryValue getColumnValue getRowColumnValue \
          tqputs tqlog makeBinaryChannel makeAsciiChannel makeUnicodeChannel \
          makeLogChannel readFile readSharedFile writeFile appendFile \
          appendLogFile appendSharedFile appendSharedLogFile \
          readAsciiFile writeAsciiFile readUnicodeFile \
          writeUnicodeFile getDirResultPath addToPath removeFromPath \
          execShell lshuffle ldifference filter map reduce \
          getLengthModifier debug findDirectories \
          findDirectoriesRecursive findFiles findFilesRecursive \

Changes to Externals/Eagle/lib/Eagle1.0/object.eagle.

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
275
276
277
278
279
280
281




282
283
284











285
286
287
288
289
290
291
292
293
      return ""
    }

    if {[string length $typeName] == 0} then {
      return ""
    }

    set type [object invoke -create -alias Type GetType $typeName]

    if {[string length $type] == 0} then {
      return ""
    }

    return [expr {[$type IsValueType] ? 0 : "null"}]
  }
................................................................................
    #
    # NOTE: Is there a script to be evaluated when the asynchronous script
    #       evaluation is complete?  If so, build an anonymous procedure
    #       that wraps it; otherwise, set the callback argument to null, so
    #       the core marshaller will handle the lack of a callback correctly.
    #       The context argument will be added to this script prior to it
    #       being evaluated; however, it is not actually used by this script.




    #
    if {[string length $doneScript] > 0} then {
      set callback [list -callbackflags {+ResetCancel FireAndForget} \











          -- apply [list [list script context] {uplevel 1 $script}] \
          $doneScript]
    } else {
      set callback null
    }

    #
    # NOTE: Initialize the local variable that will be used to receive the
    #       script error, if any.







|







 







>
>
>
>


<
>
>
>
>
>
>
>
>
>
>
>
|
|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
      return ""
    }

    if {[string length $typeName] == 0} then {
      return ""
    }

    set type [object invoke -create -alias Utility GetType $typeName]

    if {[string length $type] == 0} then {
      return ""
    }

    return [expr {[$type IsValueType] ? 0 : "null"}]
  }
................................................................................
    #
    # NOTE: Is there a script to be evaluated when the asynchronous script
    #       evaluation is complete?  If so, build an anonymous procedure
    #       that wraps it; otherwise, set the callback argument to null, so
    #       the core marshaller will handle the lack of a callback correctly.
    #       The context argument will be added to this script prior to it
    #       being evaluated; however, it is not actually used by this script.
    #       The -identifier option is NOT actually processed by the library;
    #       however, it is necessary here to avoid having multiple calls to
    #       this procedure collide with each other when attempting to remove
    #       their callbacks during cleanup.
    #
    if {[string length $doneScript] > 0} then {

      #
      # NOTE: If the core library was compiled without dynamic delegates,
      #       this procedure cannot be used when there is a callback, due
      #       to the AsynchronousCallback delegate type being unsupported.
      #
      if {[lsearch -exact -- \
          $::eagle_platform(compileOptions) EMIT] == -1} then {
        error "cannot eval async: library missing EMIT compile-option"
      }

      set callback [list -identifier [expr {random()}] -callbackflags \
          {+ResetCancel FireAndForget} -- apply [list [list script context] \
          {uplevel 1 $script}] $doneScript]
    } else {
      set callback null
    }

    #
    # NOTE: Initialize the local variable that will be used to receive the
    #       script error, if any.

Changes to Externals/Eagle/lib/Eagle1.0/pkgt.eagle.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
118
119
120
121
122
123
124




















125
126
127
128
129
130
131
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
...
161
162
163
164
165
166
167
168


169
170






































































































































































171
172
173
174
175
176
177
...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
...
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
...
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249



250
251
252
253
254
255
256
...
262
263
264
265
266
267
268
269


270
271
272
273
274
275
276
...
443
444
445
446
447
448
449


















































450
451
452
453
454
455
456
457
    # NOTE: The base URI used to build the URIs for the Package Client
    #       Toolset downloads.
    #
    variable baseUri; # DEFAULT: [getAuxiliaryBaseUri] -OR- https://urn.to/r

    if {$force || ![info exists baseUri]} then {
      if {[isEagle]} then {
        package require Eagle.Update
        set baseUri [getAuxiliaryBaseUri]
      } else {
        set baseUri https://urn.to/r
      }
    }

    #
................................................................................
    # NOTE: The URI where license certificate requests should be sent.
    #
    variable licenseUri; # DEFAULT: ${baseUri}/${urn}

    if {$force || ![info exists licenseUri]} then {
      set licenseUri {${baseUri}/${urn}}
    }




















  }
 
  #
  # NOTE: This procedure attempts to download and extract the Package Client
  #       Toolset.  The optional channel argument is the output channel where
  #       diagnostic information is sent.  The optional quiet argument should
  #       be non-zero to prevent diagnostic information from being emitted.
................................................................................
    variable baseUri
    variable packageToolsetUri
    variable packageToolsetUrn

    package require Eagle.Test
    package require Eagle.Unzip

    set extractRootDirectory [getTemporaryPath]

    set directory [file join $extractRootDirectory [appendArgs \
        ea-pt-di- [pid] - [string trim [clock seconds] -]]]

    set uri [subst $packageToolsetUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
    } else {
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive $fileName $extractRootDirectory]


    return [file join $extractDirectory pkgr_an_d client 1.0 neutral]
  }






































































































































































 
  #
  # NOTE: This procedure attempts to download and extract a native TclKit DLL
  #       for the current platform.  The optional channel argument is the
  #       output channel where diagnostic information is sent.  The optional
  #       quiet argument should be non-zero to prevent diagnostic information
  #       from being emitted.  This procedure may raise script errors.  The
................................................................................
    variable baseUri
    variable tclKitDllUri
    variable tclKitDllUrn

    package require Eagle.Test
    package require Eagle.Unzip

    set extractRootDirectory [getTemporaryPath]

    set directory [file join $extractRootDirectory [appendArgs \
        ea-td-di- [pid] - [string trim [clock seconds] -]]]

    set platform [machineToPlatform $::tcl_platform(machine) true]
    set urn [subst $tclKitDllUrn]; set uri [subst $tclKitDllUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
    } else {
      package require Eagle.Tools.Common
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive $fileName $extractRootDirectory]


    return [lindex [glob -nocomplain \
        [file join $extractDirectory lib *[info sharedlibextension]]] 0]
  }
 
  #
  # NOTE: This procedure attempts to download and extract the Security Toolset,
................................................................................
    variable baseUri
    variable securityToolsetUri
    variable securityToolsetUrn

    package require Eagle.Test
    package require Eagle.Unzip

    set extractRootDirectory [getTemporaryPath]

    set directory [file join $extractRootDirectory [appendArgs \
        ea-st-di- [pid] - [string trim [clock seconds] -]]]

    if {[info exists ::eagle_platform(text)]} then {

      set platform [string tolower $::eagle_platform(text)]
    } else {
      set platform [string tolower netFx20]; # TODO: Good default?
    }




    set dir [string map [list fx ""] $platform]; # netfx20 -> net20
    set urn [subst $securityToolsetUrn]; set uri [subst $securityToolsetUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive $fileName $extractRootDirectory]


    return [file join $extractDirectory build $dir lib]
  }
 
  #
  # NOTE: This procedure attempts to request a license certificate for Eagle,
  #       which includes the Harpy and Badge plugins.  The optional channel
  #       argument is the output channel where diagnostic information is sent.
................................................................................
    set newFileName [file join $directory [file tail $fileName]]

    file mkdir $directory; file copy $fileName $newFileName
    file delete $fileName

    return $newFileName
  }


















































 
  #
  # NOTE: Provide the Eagle "package toolset" package to the interpreter.
  #
  package provide Eagle.Package.Toolset \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}
 







<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
<
<







 







|
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|

|
|

<







 







|
>







 







<
<
<
<
<
|
>




>
>
>







 







|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








34
35
36
37
38
39
40

41
42
43
44
45
46
47
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
158
159
160
161
162
163
164
165



166
167
168
169
170
171
172
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
...
417
418
419
420
421
422
423





424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    # NOTE: The base URI used to build the URIs for the Package Client
    #       Toolset downloads.
    #
    variable baseUri; # DEFAULT: [getAuxiliaryBaseUri] -OR- https://urn.to/r

    if {$force || ![info exists baseUri]} then {
      if {[isEagle]} then {

        set baseUri [getAuxiliaryBaseUri]
      } else {
        set baseUri https://urn.to/r
      }
    }

    #
................................................................................
    # NOTE: The URI where license certificate requests should be sent.
    #
    variable licenseUri; # DEFAULT: ${baseUri}/${urn}

    if {$force || ![info exists licenseUri]} then {
      set licenseUri {${baseUri}/${urn}}
    }

    #
    # NOTE: The URN, relative to the base URI, where script evaluation
    #       requests should be submitted to the "safe" sandbox.
    #
    variable sandboxEvalUrn; # DEFAULT: eval_01

    if {$force || ![info exists sandboxEvalUrn]} then {
      set sandboxEvalUrn eval_01
    }

    #
    # NOTE: The URI where script evaluation requests should be submitted
    #       to the "safe" sandbox.
    #
    variable sandboxEvalUri; # DEFAULT: ${baseUri}/${urn}

    if {$force || ![info exists sandboxEvalUri]} then {
      set sandboxEvalUri {${baseUri}/${urn}}
    }
  }
 
  #
  # NOTE: This procedure attempts to download and extract the Package Client
  #       Toolset.  The optional channel argument is the output channel where
  #       diagnostic information is sent.  The optional quiet argument should
  #       be non-zero to prevent diagnostic information from being emitted.
................................................................................
    variable baseUri
    variable packageToolsetUri
    variable packageToolsetUrn

    package require Eagle.Test
    package require Eagle.Unzip

    set extractRootDirectory [getPackageInstallPath pkgd ea-pt-di]




    set uri [subst $packageToolsetUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
    } else {
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive \
        $fileName $extractRootDirectory true]

    return [file join $extractDirectory pkgr_an_d client 1.0 neutral]
  }
 
  #
  # NOTE: This procedure attempts to load (via [package require]) the package
  #       client toolset.  It is designed to be used in conjunction with the
  #       [downloadAndExtractPackageClientToolset] procedure, above.  Support
  #       is included for specifying an extra auto-path directory and API key
  #       to use.  By default, the [package unknown] handler is hooked to add
  #       the remote package repository lookup functionality.  Eagle supports
  #       extra script security via signed script certificates, which will be
  #       enabled by default, unless it is unavailable.
  #
  proc loadPackageClientToolset {
          {directory auto} {apiKeys ""} {hookUnknown true} {enableSecurity true}
          {strictSecurity false} {debug false} } {
    #
    # NOTE: When running in Eagle, namespace support must be available and
    #       enabled.
    #
    if {[isEagle] && ![namespace enable]} then {
      error "namespace support must be enabled"
    }

    #
    # NOTE: Does the caller want automatic discovery of the directory that
    #       contains the (downloaded?) package client toolset?  Currently,
    #       this only works on Windows and searches the temporary download
    #       location, which normally obtains its value from the environment
    #       variable TEMP.
    #
    if {$directory eq "auto"} then {
      #
      # NOTE: First, before doing anything else, see if the package client
      #       toolset is already installed somewhere it can be loaded from.
      #
      set needDirectory true

      if {[isEagle]} then {
        #
        # NOTE: Force Eagle to find *ALL* available package index files.
        #       This must be done in the global scope so that the special
        #       global variable 'dir' set by the package index loading
        #       subsystem can be accessed.  Use [catch] here just in case
        #       a package index file raises a script error.
        #
        catch {
          uplevel #0 [list package scan -host -normal -refresh]
        }
      } else {
        #
        # HACK: Force Tcl to find *ALL* available package index files.
        #       Without this, checking for the available versions of a
        #       package using [package versions] likely will not succeed
        #       unless the package is already loaded.  Use [catch] here
        #       just in case a package index file raises a script error.
        #
        catch {
          package require [appendArgs \
              bogus_package_ [string trim [clock seconds] -]]
        }
      }

      #
      # NOTE: Check and see if the package repository client is a known
      #       package now.  If so, there is no need to search directories
      #       for it.
      #
      if {[llength [package versions Eagle.Package.Repository]] > 0} then {
        set needDirectory false
      }

      #
      # NOTE: Is searching for temporary download directories required at
      #       this point?
      #
      if {$needDirectory} then {
        if {![isWindows]} then {
          error "directory discovery not supported on this platform"
        }

        set extractRootDirectory [getPackageInstallPath]

        foreach directory [findDirectoriesRecursive \
            [file join $extractRootDirectory pkgr_an_d]] {
          #
          # NOTE: Reset directory we just found to include the necessary
          #       sub-directory components for the actual client files
          #       and then stop, thereby selecting the first match.
          #
          set directory [file join $directory client 1.0 neutral]; break
        }
      }

      #
      # NOTE: If no directory was found, just clear the directory name,
      #       which will cause auto-path modification(s) to be skipped.
      #
      if {$directory eq "auto"} then {
        set directory ""
      }
    }

    #
    # NOTE: If there is a directory specified by the caller -OR- found
    #       via automatic directory discovery, add it to the auto-path
    #       now.
    #
    if {[string length $directory] > 0} then {
      #
      # NOTE: Only modify the auto-path if the directory is not already
      #       present.  This prevents needless variable trace execution
      #       that rescans the various auto-path directories.
      #
      if {![info exists ::auto_path] || \
          [lsearch -exact $::auto_path $directory] == -1} then {
        lappend ::auto_path $directory
      }
    }

    #
    # NOTE: If the caller wants to enable extra diagnostic information,
    #       set the appropriate environment variables now.
    #
    if {$debug} then {
      set ::env(DEBUG_PKGR) 1; set ::env(DEBUG_PKGD) 1
    }

    #
    # NOTE: If the caller specified API keys, add them to the configured
    #       list of API keys for the package repository client now.  This
    #       uses a special global variable.
    #
    if {[llength $apiKeys] > 0} then {
      eval lappend ::pkgr_api_keys $apiKeys
    }

    #
    # NOTE: If the caller wants to enable the extra Eagle script security,
    #       attempt to do that now.  Only treat a failure here as fatal if
    #       the caller said so.
    #
    if {[isEagle] && $enableSecurity} then {
      if {[catch {
        uplevel 1 [list source enableSecurity]
      } error] && $strictSecurity} then {
        error $error
      }
    }

    #
    # NOTE: In Eagle, to actually enable make use of the [package unknown]
    #       handler, an interpreter flag must be disabled.  If necessary,
    #       do that now.
    #
    if {[isEagle] && $hookUnknown} then {
      object invoke -flags +NonPublic -objectflags +AutoFlagsEnum \
          Interpreter.GetActive interpreterFlags -NoPackageUnknown
    }

    #
    # NOTE: Finally, attempt to actually load the package repository client.
    #       This may fail for a number of reasons.  The most likely failure
    #       case is when the directory containing the package is not found;
    #       however, there are other possible failure modes.
    #
    package require Eagle.Package.Repository
  }
 
  #
  # NOTE: This procedure attempts to download and extract a native TclKit DLL
  #       for the current platform.  The optional channel argument is the
  #       output channel where diagnostic information is sent.  The optional
  #       quiet argument should be non-zero to prevent diagnostic information
  #       from being emitted.  This procedure may raise script errors.  The
................................................................................
    variable baseUri
    variable tclKitDllUri
    variable tclKitDllUrn

    package require Eagle.Test
    package require Eagle.Unzip

    set platform [machineToPlatform $::tcl_platform(machine) true]

    set extractRootDirectory [getPackageInstallPath \
        [appendArgs KitDll_ $platform] ea-td-di]


    set urn [subst $tclKitDllUrn]; set uri [subst $tclKitDllUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
    } else {
      package require Eagle.Tools.Common
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive \
        $fileName $extractRootDirectory true]

    return [lindex [glob -nocomplain \
        [file join $extractDirectory lib *[info sharedlibextension]]] 0]
  }
 
  #
  # NOTE: This procedure attempts to download and extract the Security Toolset,
................................................................................
    variable baseUri
    variable securityToolsetUri
    variable securityToolsetUrn

    package require Eagle.Test
    package require Eagle.Unzip






    if {[info exists ::eagle_platform(text)] && \
        [string length $::eagle_platform(text)] > 0} then {
      set platform [string tolower $::eagle_platform(text)]
    } else {
      set platform [string tolower netFx20]; # TODO: Good default?
    }

    set extractRootDirectory [getPackageInstallPath \
        [appendArgs eee_ $platform] ea-st-di]

    set dir [string map [list fx ""] $platform]; # netfx20 -> net20
    set urn [subst $securityToolsetUrn]; set uri [subst $securityToolsetUri]
    set fileName [getTemporaryFileName]

    if {[isEagle]} then {
      uri download $uri $fileName
................................................................................
          ::Eagle::Tools::Common::writeFile

      set data [getFileViaHttp $uri 20 $channel $quiet -binary true]

      writeFile $fileName $data
    }

    set extractDirectory [extractZipArchive \
        $fileName $extractRootDirectory true]

    return [file join $extractDirectory build $dir lib]
  }
 
  #
  # NOTE: This procedure attempts to request a license certificate for Eagle,
  #       which includes the Harpy and Badge plugins.  The optional channel
  #       argument is the output channel where diagnostic information is sent.
................................................................................
    set newFileName [file join $directory [file tail $fileName]]

    file mkdir $directory; file copy $fileName $newFileName
    file delete $fileName

    return $newFileName
  }
 
  #
  # NOTE: This procedure attempts to submit the specified script to a remote
  #       sandbox for evaluation.  The apiKey parameter is the optional API
  #       key to use, which MAY enable additional permissions in the remote
  #       sandbox.  The params parameter contains any optional extra names
  #       and values to include in the submitted query.  Upon success, this
  #       procedure returns a Tcl dictionary that includes at least the keys
  #       "returnCode", "result", and "errorLine".  The "returnCode" value
  #       will be "Ok", "Error", "Return", "Break", "Continue", or possibly
  #       a signed integer.  The "result" value will be the textual result
  #       of the script or an error message.  The "errorLine" value will be
  #       zero or the line where a script error was raised.  This procedure
  #       may raise script errors.
  #
  proc evaluateInRemoteSandbox {
          script {apiKey ""} {params ""} {channel stdout} {quiet false} } {
    setupPackageToolsetVars false

    variable baseUri
    variable sandboxEvalUri
    variable sandboxEvalUrn

    set urn [subst $sandboxEvalUrn]
    set uri [subst $sandboxEvalUri]

    set query [list go 1 raw 1 script $script]

    if {[string length $apiKey] > 0} then {
      lappend query apiKey $apiKey
    }

    if {[llength $params] > 0} then {
      eval lappend query $params
    }

    if {[isEagle]} then {
      return [uri upload -inline -data $query $uri]
    } else {
      package require http 2.0
      package require Eagle.Tools.Common

      namespace import \
          ::Eagle::Tools::Common::getFileViaHttp

      return [getFileViaHttp \
          $uri 20 $channel $quiet -binary true \
          -query [eval ::http::formatQuery $query]]
    }
  }
 
  #
  # NOTE: Provide the Eagle "package toolset" package to the interpreter.
  #
  package provide Eagle.Package.Toolset \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}
 

Changes to Externals/Eagle/lib/Eagle1.0/platform.eagle.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

















56
57
58
59
60
61
62
    #
    return [expr {[info exists ::tcl_platform(engine)] && \
        [string compare -nocase eagle $::tcl_platform(engine)] == 0}]
  }
 
  #
  # NOTE: This is the procedure that detects whether or not we are running
  #       in Eagle on Mono (otherwise, we are running in Tcl or in Eagle on
  #       the .NET Framework).  This procedure must function correctly in
  #       both Tcl and Eagle and must return non-zero only when running in
  #       Eagle on Mono.
  #
  proc isMono {} {
    #
    # NOTE: Nothing too fancy or expensive should be done here.  In theory,
    #       use of this procedure should be rare; however, in practice, this
    #       procedure is actually used quite a bit (e.g. by the test suite).
    #
    return [expr {[info exists ::eagle_platform(runtime)] && \
        [string compare -nocase mono $::eagle_platform(runtime)] == 0}]
  }

















 
  #
  # NOTE: This procedure returns non-zero if the logged on user has full
  #       administrator rights on this machine.  Currently, this only works
  #       in Eagle; however, it may work from native Tcl in the future.
  #
  proc isAdministrator {} {







|
|
|
|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    #
    return [expr {[info exists ::tcl_platform(engine)] && \
        [string compare -nocase eagle $::tcl_platform(engine)] == 0}]
  }
 
  #
  # NOTE: This is the procedure that detects whether or not we are running
  #       in Eagle on Mono (i.e. otherwise, we are running in Tcl or in Eagle
  #       on the .NET Framework or .NET Core).  This procedure must function
  #       correctly in both Tcl and Eagle and must return non-zero only when
  #       running in Eagle on Mono.
  #
  proc isMono {} {
    #
    # NOTE: Nothing too fancy or expensive should be done here.  In theory,
    #       use of this procedure should be rare; however, in practice, this
    #       procedure is actually used quite a bit (e.g. by the test suite).
    #
    return [expr {[info exists ::eagle_platform(runtime)] && \
        [string compare -nocase mono $::eagle_platform(runtime)] == 0}]
  }
 
  #
  # NOTE: This is the procedure that detects whether or not we are running
  #       in Eagle on .NET Core (i.e. otherwise, we are running in Tcl or in
  #       Eagle on the .NET Framework or Mono).  This procedure must function
  #       correctly in both Tcl and Eagle and must return non-zero only when
  #       running in Eagle on .NET Core.
  #
  proc isDotNetCore {} {
    #
    # NOTE: Nothing too fancy or expensive should be done here.  In theory,
    #       use of this procedure should be rare; however, in practice, this
    #       procedure is actually used quite a bit (e.g. by the test suite).
    #
    return [expr {[info exists ::eagle_platform(runtime)] && \
        [string compare -nocase ".net core" $::eagle_platform(runtime)] == 0}]
  }
 
  #
  # NOTE: This procedure returns non-zero if the logged on user has full
  #       administrator rights on this machine.  Currently, this only works
  #       in Eagle; however, it may work from native Tcl in the future.
  #
  proc isAdministrator {} {

Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.

286
287
288
289
290
291
292






































293
294
295
296
297
298
299
...
714
715
716
717
718
719
720
721
722
723
724
725
726
727



























728
729
730
731





732
733
734
735
736
737
738
....
1311
1312
1313
1314
1315
1316
1317
1318

1319
1320
1321

1322
1323








1324
1325
1326
1327
1328
1329
1330
....
1333
1334
1335
1336
1337
1338
1339





















































1340
1341
1342
1343
1344
1345
1346
....
1398
1399
1400
1401
1402
1403
1404








1405

1406
1407
1408
1409
1410
1411
1412
....
1597
1598
1599
1600
1601
1602
1603
























1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
....
2030
2031
2032
2033
2034
2035
2036














2037
2038
2039
2040
2041
2042
2043
....
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144

2145
2146
2147
2148
2149
2150
2151
2152
....
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
....
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
....
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
....
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
....
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
....
2593
2594
2595
2596
2597
2598
2599






2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
....
2624
2625
2626
2627
2628
2629
2630





2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
....
3313
3314
3315
3316
3317
3318
3319








































3320
3321
3322
3323
3324
3325
3326
....
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955

3956
3957
3958
3959
3960
3961
3962
3963

    foreach name [eval $command] {
      lappend result $name $array($name)
    }

    return $result
  }






































 
  proc testResultGet { script } {
    set code [catch {uplevel 1 $script} result]
    return [expr {$code == 0 ? $result : "<error>"}]
  }
 
  proc testValueGet { varName {integer false} } {
................................................................................
    #
    # NOTE: Return the nested list of unknown arguments, formatted as
    #       name/value pairs, to the caller.
    #
    return $result
  }
 
  proc getTclShellFileName { automatic kits } {
    #
    # NOTE: Start out with an empty list of candiate Tcl shells.
    #
    set shells [list]

    #



























    # NOTE: Check all environment variables we know about that
    #       may contain the path where the Tcl shell is located.
    #
    foreach name [list Eagle_Tcl_Shell Tcl_Shell EAGLE_TCLSH TCLSH] {





      set value [getEnvironmentVariable $name]

      #
      # TODO: Possibly add a check if the file actually exists
      #       here.
      #
      if {[string length $value] > 0} then {
................................................................................
      return $::test_flags(-suffix)
    } elseif {[info exists ::test_suffix]} then {
      #
      # NOTE: Use the test suffix.  There is no default value for
      #       this variable (i.e. by default, it does not exist).
      #
      return $::test_suffix
    } elseif {[info exists ::eagle_platform(text)]} then {

      #
      # NOTE: Use the build text of Eagle itself.  This value will
      #       typically be "NetFx20" or "NetFx40".

      #
      return $::eagle_platform(text)








    } else {
      #
      # NOTE: We are missing the suffix, return nothing.
      #
      return ""
    }
  }
................................................................................
    if {[info exists ::test_uncounted_leaks] && \
        [string length $::test_uncounted_leaks] > 0} then {
      return $::test_uncounted_leaks
    }

    return [list]
  }





















































 
  proc getTestAssemblyName {} {
    if {[isEagle]} then {
      return [lindex [split [lindex [info assembly] 0] ,] 0]
    } else {
      return Eagle
    }
................................................................................
    #
    # HACK: Assume that Mono is somewhere along the PATH.
    #
    if {[isMono]} then {
      lappend command mono \
          [appendArgs \" [file nativename $commandName] \"]
    } else {








      lappend command $commandName

    }

    if {[llength $args] > 0} then {eval lappend command $args}
    set procName [lindex [info level [info level]] 0]

    if {![canTestExec $procName]} then {
      tputs $::test_channel [appendArgs "---- skipping command: " $command \n]
................................................................................
      hookPuts
    }

    set code [catch {uplevel 1 $script} result]
    set error [expr {$code == 0 ? false : true}]

    if {[isEagle]} then {
























      if {$code == 0 && [regexp -- {\s==== (.*?) FAILED\s} $result]} then {
        set code 1
      }

      #
      # NOTE: Display and/or log the results for the test that we just
      #       completed.
      #
      if {[shouldWriteTestData $code]} then {
        tresult $code $result
      } else {
        tlog $result
      }

      #
      # NOTE: If the test failed with an actual error (i.e. not just a
      #       test failure), make sure we do not obscure the error
................................................................................
    #
    set map [list \
        \\ \\\\ \$ \\\$ ( \\( ) \\) * \\* + \\+ - \\- . \\. \
        ? \\? \[ \\\[ \] \\\] ^ \\^ \{ \\\{ \} \\\}]

    return [string map $map [expr {$list ? [list $path] : $path}]]
  }














 
  proc inverseLsearchGlob { noCase patterns element } {
    #
    # NOTE: Perform the inverse of [lsearch -glob], attempt
    #       to match an element against a list of patterns.
    #
    set command [list string match]
................................................................................
  proc clearTestPercent { channel } {
    if {[isEagle]} then {
      host title ""
    }
  }
 
  proc reportTestPercent {
          channel percent totalFiles failedFiles leakedFiles } {
    if {[isEagle]} then {
      set totalTests $::eagle_tests(Total)
      set failedTests $::eagle_tests(Failed)
      set skippedTests $::eagle_tests(Skipped)
    } else {
      set totalTests $::tcltest::numTests(Total)
      set failedTests $::tcltest::numTests(Failed)
      set skippedTests $::tcltest::numTests(Skipped)
    }

    set status [appendArgs \
        "---- test suite running, about " $percent "% complete (" \
        $totalTests " tests total, " $failedTests " tests failed, " \
        $skippedTests " tests skipped, " $totalFiles " files total, " \

        $failedFiles " files failed, " $leakedFiles " files leaked)..."]

    tputs $channel [appendArgs $status \n]

    if {[isEagle]} then {
      host title $status
    }
  }
................................................................................
    #
    set failed [list]
    set leaked [list]

    #
    # NOTE: Process each file name we have been given by the caller...
    #
    set total 0; set lastPercent -1

    foreach fileName $fileNames {
      #
      # NOTE: If configured to break into the debugger before running the
      #       test file, do it now.
      #
      if {[isBreakOnDemand]} then {
................................................................................
        testDebugBreak
      }

      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

      if {$percent != $lastPercent} then {
        if {![info exists ::no(runPercent)]} then {
          reportTestPercent $channel $percent \
              $total [llength $failed] [llength $leaked]
        }

        set lastPercent $percent
      }

      #
      # NOTE: If the starting file names have been specified by the caller,
................................................................................
            #
            # NOTE: Log that this test file has ended.
            #
            if {![info exists ::no(runEndFile)]} then {
              tputs $channel [appendArgs "==== \"" $fileName "\" END\n"]
            }

            #
            # NOTE: At this point, we know that another test file was
            #       processed successfully.
            #
            incr total

            if {![info exists ::no(runPercent)]} then {
              reportTestPercent $channel $percent \
                  $total [llength $failed] [llength $leaked]
            }

            #
            # NOTE: Are we being prevented from waiting after the file?
            #
            if {![info exists ::no(postWait)]} then {
              if {[info exists ::test_wait(post)] && \
                  [string is integer -strict $::test_wait(post)]} then {
                if {![info exists ::no(runMetadata)]} then {
................................................................................
              #       the failure.  Set a special variable for the epilogue
              #       to pick up on (later).
              #
              lappend ::test_suite_errors [list $fileName $error]
            }
          }

          #
          # NOTE: We evaluated another test file.
          #
          incr count

          #
          # NOTE: Record failed test count after this file.
          #
          if {[isEagle]} then {
            set after $::eagle_tests(Failed)
          } else {
            set after $::tcltest::numTests(Failed)
................................................................................
            lappend failed [file tail $fileName]
          }

          #
          # NOTE: In terms of files, not tests, what percent done are we now?
          #
          set percent [formatDecimal \
              [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

          if {$percent != $lastPercent} then {
            if {![info exists ::no(runPercent)]} then {
              reportTestPercent $channel $percent \
                  $total [llength $failed] [llength $leaked]
            }

            set lastPercent $percent
          }

          #
          # NOTE: Unset the current test file name, it is no longer
................................................................................
          #
          if {![info exists ::no(runNonTestFile)]} then {
            tputs $channel [appendArgs \
                "==== \"" $fileName "\" NON_TEST_FILE\n"]
          }
        }







        #
        # NOTE: In terms of files, not tests, what percent done are we now?
        #
        set percent [formatDecimal \
            [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

        if {$percent != $lastPercent} then {
          if {![info exists ::no(runPercent)]} then {
            reportTestPercent $channel $percent \
                $total [llength $failed] [llength $leaked]
          }

          set lastPercent $percent
        }

        #
        # NOTE: If the test file raised an error (i.e. to indicate a
................................................................................
        #
        # NOTE: This entire file has been skipped.  Record that fact in the
        #       test suite log file.
        #
        if {![info exists ::no(runSkippedFile)]} then {
          tputs $channel [appendArgs "==== \"" $fileName "\" SKIPPED\n"]
        }





      }

      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]]

      if {$percent != $lastPercent} then {
        if {![info exists ::no(runPercent)]} then {
          reportTestPercent $channel $percent \
              $total [llength $failed] [llength $leaked]
        }

        set lastPercent $percent
      }
    }

    #
................................................................................
        return [expr \
            {100.0 * ($::eagle_tests(Skipped) / \
            double($::eagle_tests(Total)))}]
      }

      return 0; # no tests were run, etc.
    }








































 
    proc cleanupThread { thread {timeout 2000} } {
      if {[$thread IsAlive]} then {
        if {[catch {$thread Interrupt} error]} then {
          tputs $::test_channel [appendArgs \
              "---- failed to interrupt test thread \"" $thread "\": " \
              $error \n]
................................................................................
        getCachedConstraints useCachedConstraints removeConstraint \
        fixConstraints fixTimingConstraints calculateBogoCops \
        calculateRelativePerformance formatTimeStamp formatElapsedTime \
        sourceIfValid processTestArguments getTclShellFileName \
        getTemporaryPath getFiles getTestFiles getTestRunId getTestLogId \
        getDefaultTestLog getTestLog getLastTestLog getTestSuite \
        getTestMachine getTestPlatform getTestConfiguration getTestSuffix \
        getTestUncountedLeaks getTestAssemblyName canTestExec testExec \
        testClrExec execTestShell isRandomOrder isBreakOnDemand isBreakOnLeak \
        isStopOnFailure isStopOnLeak isExitOnComplete returnInfoScript \
        runTestPrologue runTestEpilogue hookPuts unhookPuts runTest \
        testDebugBreak testArrayGet testShim tsource recordTestStatistics \

        reportTestStatistics formatList formatListAsDict pathToRegexp \
        inverseLsearchGlob removePathFromFileNames formatDecimal \
        clearTestPercent reportTestPercent runAllTests isTestSuiteRunning \
        getTestChannelOrDefault tryVerifyTestPath checkForAndSetTestPath \
        configureTcltest machineToPlatform getPassPercentage \
        getSkipPercentage] false false

    ###########################################################################







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


<
>
>
>
>
>







 







|
>

|
|
>


>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|













|
>
|







 







|







 







|




|







 







<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<







 







|




|







 







>
>
>
>
>
>




|




|







 







>
>
>
>
>






|




|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
>
|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
...
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795

796
797
798
799
800
801
802
803
804
805
806
807
....
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
....
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
....
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
....
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
....
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
....
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
....
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
....
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
....
2622
2623
2624
2625
2626
2627
2628











2629
2630
2631
2632
2633
2634
2635
....
2692
2693
2694
2695
2696
2697
2698





2699
2700
2701
2702
2703
2704
2705
....
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
....
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
....
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
....
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
....
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179

    foreach name [eval $command] {
      lappend result $name $array($name)
    }

    return $result
  }
 
  proc testArrayGet2 { varName {pattern ""} {integer false} } {
    #
    # NOTE: Returns the results of [array get] in a well-defined order.
    #
    if {[string length $varName] == 0} then {
      return [list]
    }

    #
    # NOTE: Refer to the array in the context of the caller.
    #
    upvar 1 $varName array

    #
    # NOTE: Build the command that will sort the array names into order.
    #
    set command [list lsort]
    if {$integer} then {lappend command -integer}

    #
    # NOTE: If there is a pattern, use it; otherwise, all elements are
    #       returned.
    #
    if {[string length $pattern] > 0} then {
      lappend command [array names array $pattern]
    } else {
      lappend command [array names array]
    }

    set result [list]

    foreach name [eval $command] {
      lappend result $name $array($name)
    }

    return $result
  }
 
  proc testResultGet { script } {
    set code [catch {uplevel 1 $script} result]
    return [expr {$code == 0 ? $result : "<error>"}]
  }
 
  proc testValueGet { varName {integer false} } {
................................................................................
    #
    # NOTE: Return the nested list of unknown arguments, formatted as
    #       name/value pairs, to the caller.
    #
    return $result
  }
 
  proc getTclShellFileName { automatic kits machine } {
    #
    # NOTE: Start out with an empty list of candiate Tcl shells.
    #
    set shells [list]

    #
    # NOTE: Figure out the environment variables to be checked.  If
    #       there was a machine specified, it will be used to check
    #       for machine-specific Tcl shells.
    #
    set names [list]

    foreach name [list Eagle_Tcl_Shell Tcl_Shell EAGLE_TCLSH TCLSH] {
      if {[string length $machine] > 0} then {
        set platform [machineToPlatform $machine true]

        if {[string length $platform] > 0} then {
          lappend names [appendArgs $name _ $platform]
        }

        set platform [machineToPlatform $machine false]

        if {[string length $platform] > 0} then {
          lappend names [appendArgs $name _ $platform]
        }

        lappend names [appendArgs $name _ $machine]
      }

      lappend names $name
    }

    #
    # NOTE: Check all environment variables (we know about) that
    #       may contain the path where the Tcl shell is located.
    #

    foreach name $names {
      #
      # NOTE: Grab the value of the environment variable.  This
      #       will be an empty string if it was not set.
      #
      set value [getEnvironmentVariable $name]

      #
      # TODO: Possibly add a check if the file actually exists
      #       here.
      #
      if {[string length $value] > 0} then {
................................................................................
      return $::test_flags(-suffix)
    } elseif {[info exists ::test_suffix]} then {
      #
      # NOTE: Use the test suffix.  There is no default value for
      #       this variable (i.e. by default, it does not exist).
      #
      return $::test_suffix
    } elseif {[info exists ::eagle_platform(text)] && \
        [string length $::eagle_platform(text)] > 0} then {
      #
      # NOTE: Use the build "text" of Eagle itself.  This value
      #       will typically be "NetFx20", "NetFx40", etc.  The
      #       default value of this element is an empty string.
      #
      return $::eagle_platform(text)
    } elseif {[info exists ::eagle_platform(suffix)] && \
        [string length $::eagle_platform(suffix)] > 0} then {
      #
      # NOTE: Use the build suffix of Eagle itself.  This value
      #       will typically be "NetFx20", "NetFx40", etc.  The
      #       default value of this element is an empty string.
      #
      return $::eagle_platform(suffix)
    } else {
      #
      # NOTE: We are missing the suffix, return nothing.
      #
      return ""
    }
  }
................................................................................
    if {[info exists ::test_uncounted_leaks] && \
        [string length $::test_uncounted_leaks] > 0} then {
      return $::test_uncounted_leaks
    }

    return [list]
  }
 
  proc getRuntimeAssemblyName {} {
    if {[isEagle]} then {
      if {[isDotNetCore]} then {
        if {[llength [info commands object]] > 0} then {
          #
          # HACK: The core runtime assembly (i.e. the one containing
          #       System.Object, et al) must have already been loaded
          #       (?), so just abuse the [object load] sub-command to
          #       return its assembly name.
          #
          return [lindex [object load System.Private.CoreLib] 0]
        } else {
          #
          # HACK: The [object] command is unavailable, just fake it.
          #
          return "System.Private.CoreLib, Version=4.0.0.0,\
              Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
        }
      } else {
        if {[llength [info commands object]] > 0} then {
          #
          # HACK: The core runtime assembly (i.e. the one containing
          #       System.Object, et al) must have already been loaded
          #       (?), so just abuse the [object load] sub-command to
          #       return its assembly name.
          #
          return [lindex [object load mscorlib] 0]
        } else {
          #
          # HACK: The [object] command is unavailable, just fake it.
          #
          if {[info exists ::eagle_platform(runtimeVersion)] && \
              [string index $::eagle_platform(runtimeVersion) 0] >= 4} then {
            #
            # BUGBUG: Does not handle a major CLR version greater than
            #         four (4).
            #
            return "mscorlib, Version=4.0.0.0, Culture=neutral,\
                PublicKeyToken=b77a5c561934e089"
          } else {
            return "mscorlib, Version=2.0.0.0, Culture=neutral,\
                PublicKeyToken=b77a5c561934e089"
          }
        }
      }
    } else {
      #
      # HACK: Native Tcl has no runtime assembly name as it is native.
      #
      return ""
    }
  }
 
  proc getTestAssemblyName {} {
    if {[isEagle]} then {
      return [lindex [split [lindex [info assembly] 0] ,] 0]
    } else {
      return Eagle
    }
................................................................................
    #
    # HACK: Assume that Mono is somewhere along the PATH.
    #
    if {[isMono]} then {
      lappend command mono \
          [appendArgs \" [file nativename $commandName] \"]
    } else {
      #
      # HACK: When running on .NET Core, need to insert "dotnet exec"
      #       command line arguments before command to execute.
      #
      if {[isDotNetCore]} then {
        lappend command dotnet exec \
            [appendArgs \" [file nativename $commandName] \"]
      } else {
        lappend command $commandName
      }
    }

    if {[llength $args] > 0} then {eval lappend command $args}
    set procName [lindex [info level [info level]] 0]

    if {![canTestExec $procName]} then {
      tputs $::test_channel [appendArgs "---- skipping command: " $command \n]
................................................................................
      hookPuts
    }

    set code [catch {uplevel 1 $script} result]
    set error [expr {$code == 0 ? false : true}]

    if {[isEagle]} then {
      #
      # NOTE: Initially, the call to [tresult] (i.e. [host result]) will
      #       use the actual return code from the test command; however,
      #       if that return code was 3 (i.e. break), that indicates the
      #       test results should be highlighted in yellow -AND- that the
      #       test should still be considered successful even though the
      #       test was skipped.  If the return code was 4 (i.e. continue),
      #       that indicates the test results should be highlighted in
      #       dark yellow -AND- that the test should still be considered
      #       successful because failures are being ignored for it.
      #
      set tresultCode $code

      if {$code == 3} then {
        set code 0; set error false
      } elseif {$code == 4} then {
        set code 0
      }

      #
      # NOTE: If the return code from the test command indicates success
      #       and the test results contain a clear indication of failure,
      #       reset both return codes to indicate that failure.
      #
      if {$code == 0 && [regexp -- {\s==== (.*?) FAILED\s} $result]} then {
        set code 1; set tresultCode $code
      }

      #
      # NOTE: Display and/or log the results for the test that we just
      #       completed.
      #
      if {[shouldWriteTestData $code]} then {
        tresult $tresultCode $result
      } else {
        tlog $result
      }

      #
      # NOTE: If the test failed with an actual error (i.e. not just a
      #       test failure), make sure we do not obscure the error
................................................................................
    #
    set map [list \
        \\ \\\\ \$ \\\$ ( \\( ) \\) * \\* + \\+ - \\- . \\. \
        ? \\? \[ \\\[ \] \\\] ^ \\^ \{ \\\{ \} \\\}]

    return [string map $map [expr {$list ? [list $path] : $path}]]
  }
 
  proc assemblyNameToRegexp { assemblyName {list false} } {
    #
    # NOTE: This procedure needs to escape all characters that
    #       have any special meaning to the regular expression
    #       engine -AND- that can actually appear in a legal
    #       assembly name.  Normally, this would only include
    #       the period character.
    #
    # HACK: For now, just abuse the [pathToRegexp] procedure
    #       for this.
    #
    return [pathToRegexp $assemblyName $list]
  }
 
  proc inverseLsearchGlob { noCase patterns element } {
    #
    # NOTE: Perform the inverse of [lsearch -glob], attempt
    #       to match an element against a list of patterns.
    #
    set command [list string match]
................................................................................
  proc clearTestPercent { channel } {
    if {[isEagle]} then {
      host title ""
    }
  }
 
  proc reportTestPercent {
          channel percent doneFiles totalFiles failedFiles leakedFiles } {
    if {[isEagle]} then {
      set totalTests $::eagle_tests(Total)
      set failedTests $::eagle_tests(Failed)
      set skippedTests $::eagle_tests(Skipped)
    } else {
      set totalTests $::tcltest::numTests(Total)
      set failedTests $::tcltest::numTests(Failed)
      set skippedTests $::tcltest::numTests(Skipped)
    }

    set status [appendArgs \
        "---- test suite running, about " $percent "% complete (" \
        $totalTests " tests total, " $failedTests " tests failed, " \
        $skippedTests " tests skipped, " $doneFiles " files done, " \
        $totalFiles " files total, " $failedFiles " files failed, " \
        $leakedFiles " files leaked)..."]

    tputs $channel [appendArgs $status \n]

    if {[isEagle]} then {
      host title $status
    }
  }
................................................................................
    #
    set failed [list]
    set leaked [list]

    #
    # NOTE: Process each file name we have been given by the caller...
    #
    set total [llength $fileNames]; set lastPercent -1

    foreach fileName $fileNames {
      #
      # NOTE: If configured to break into the debugger before running the
      #       test file, do it now.
      #
      if {[isBreakOnDemand]} then {
................................................................................
        testDebugBreak
      }

      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 0}]]

      if {$percent != $lastPercent} then {
        if {![info exists ::no(runPercent)]} then {
          reportTestPercent $channel $percent \
              $count $total [llength $failed] [llength $leaked]
        }

        set lastPercent $percent
      }

      #
      # NOTE: If the starting file names have been specified by the caller,
................................................................................
            #
            # NOTE: Log that this test file has ended.
            #
            if {![info exists ::no(runEndFile)]} then {
              tputs $channel [appendArgs "==== \"" $fileName "\" END\n"]
            }












            #
            # NOTE: Are we being prevented from waiting after the file?
            #
            if {![info exists ::no(postWait)]} then {
              if {[info exists ::test_wait(post)] && \
                  [string is integer -strict $::test_wait(post)]} then {
                if {![info exists ::no(runMetadata)]} then {
................................................................................
              #       the failure.  Set a special variable for the epilogue
              #       to pick up on (later).
              #
              lappend ::test_suite_errors [list $fileName $error]
            }
          }






          #
          # NOTE: Record failed test count after this file.
          #
          if {[isEagle]} then {
            set after $::eagle_tests(Failed)
          } else {
            set after $::tcltest::numTests(Failed)
................................................................................
            lappend failed [file tail $fileName]
          }

          #
          # NOTE: In terms of files, not tests, what percent done are we now?
          #
          set percent [formatDecimal \
              [expr {$total != 0 ? 100.0 * ($count / double($total)) : 0}]]

          if {$percent != $lastPercent} then {
            if {![info exists ::no(runPercent)]} then {
              reportTestPercent $channel $percent \
                  $count $total [llength $failed] [llength $leaked]
            }

            set lastPercent $percent
          }

          #
          # NOTE: Unset the current test file name, it is no longer
................................................................................
          #
          if {![info exists ::no(runNonTestFile)]} then {
            tputs $channel [appendArgs \
                "==== \"" $fileName "\" NON_TEST_FILE\n"]
          }
        }

        #
        # NOTE: Another file of some kind was processed.  It may have been
        #       skipped; however, that does not matter.
        #
        incr count

        #
        # NOTE: In terms of files, not tests, what percent done are we now?
        #
        set percent [formatDecimal \
            [expr {$total != 0 ? 100.0 * ($count / double($total)) : 0}]]

        if {$percent != $lastPercent} then {
          if {![info exists ::no(runPercent)]} then {
            reportTestPercent $channel $percent \
                $count $total [llength $failed] [llength $leaked]
          }

          set lastPercent $percent
        }

        #
        # NOTE: If the test file raised an error (i.e. to indicate a
................................................................................
        #
        # NOTE: This entire file has been skipped.  Record that fact in the
        #       test suite log file.
        #
        if {![info exists ::no(runSkippedFile)]} then {
          tputs $channel [appendArgs "==== \"" $fileName "\" SKIPPED\n"]
        }

        #
        # NOTE: This file was skipped.
        #
        incr count
      }

      #
      # NOTE: In terms of files, not tests, what percent done are we now?
      #
      set percent [formatDecimal \
          [expr {$total != 0 ? 100.0 * ($count / double($total)) : 0}]]

      if {$percent != $lastPercent} then {
        if {![info exists ::no(runPercent)]} then {
          reportTestPercent $channel $percent \
              $count $total [llength $failed] [llength $leaked]
        }

        set lastPercent $percent
      }
    }

    #
................................................................................
        return [expr \
            {100.0 * ($::eagle_tests(Skipped) / \
            double($::eagle_tests(Total)))}]
      }

      return 0; # no tests were run, etc.
    }
 
    proc createThread { script {parameterized false} {maxStackSize ""} } {
      if {[isDotNetCore]} then {
        #
        # HACK: This seems to make .NET Core happier for reasons
        #       that are not entirely clear.
        #
        set typeName "System.Threading.Thread, mscorlib"
      } else {
        set typeName System.Threading.Thread
      }

      if {$parameterized} then {
        if {[string length $maxStackSize] > 0} then {
          return [object create -alias -objectflags +NoReturnReference \
              -parametertypes System.Threading.ParameterizedThreadStart \
              $typeName $script $maxStackSize]
        } else {
          return [object create -alias -objectflags +NoReturnReference \
              -parametertypes System.Threading.ParameterizedThreadStart \
              $typeName $script]
        }
      } else {
        if {[string length $maxStackSize] > 0} then {
          return [object create -alias -objectflags +NoReturnReference \
              $typeName $script $maxStackSize]
        } else {
          return [object create -alias -objectflags +NoReturnReference \
              $typeName $script]
        }
      }
    }
 
    proc startThread { thread {parameterized false} {parameter null} } {
      if {$parameterized} then {
        $thread Start $parameter
      } else {
        $thread Start
      }
    }
 
    proc cleanupThread { thread {timeout 2000} } {
      if {[$thread IsAlive]} then {
        if {[catch {$thread Interrupt} error]} then {
          tputs $::test_channel [appendArgs \
              "---- failed to interrupt test thread \"" $thread "\": " \
              $error \n]
................................................................................
        getCachedConstraints useCachedConstraints removeConstraint \
        fixConstraints fixTimingConstraints calculateBogoCops \
        calculateRelativePerformance formatTimeStamp formatElapsedTime \
        sourceIfValid processTestArguments getTclShellFileName \
        getTemporaryPath getFiles getTestFiles getTestRunId getTestLogId \
        getDefaultTestLog getTestLog getLastTestLog getTestSuite \
        getTestMachine getTestPlatform getTestConfiguration getTestSuffix \
        getTestUncountedLeaks getRuntimeAssemblyName getTestAssemblyName \
        canTestExec testExec testClrExec execTestShell isRandomOrder \
        isBreakOnDemand isBreakOnLeak isStopOnFailure isStopOnLeak \
        isExitOnComplete returnInfoScript runTestPrologue runTestEpilogue \
        hookPuts unhookPuts runTest testDebugBreak testArrayGet testShim \
        tsource recordTestStatistics reportTestStatistics formatList \
        formatListAsDict pathToRegexp assemblyNameToRegexp \
        inverseLsearchGlob removePathFromFileNames formatDecimal \
        clearTestPercent reportTestPercent runAllTests isTestSuiteRunning \
        getTestChannelOrDefault tryVerifyTestPath checkForAndSetTestPath \
        configureTcltest machineToPlatform getPassPercentage \
        getSkipPercentage] false false

    ###########################################################################

Changes to Externals/Eagle/lib/Eagle1.0/unzip.eagle.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161



162
163

164
165
166
167
168
169
170
    # NOTE: The base URI used to build the URIs for the unzip command line
    #       tool downloads.
    #
    variable baseUri; # DEFAULT: [getAuxiliaryBaseUri] -OR- https://urn.to/r

    if {$force || ![info exists baseUri]} then {
      if {[isEagle]} then {
        package require Eagle.Update
        set baseUri [getAuxiliaryBaseUri]
      } else {
        set baseUri https://urn.to/r
      }
    }

    #
................................................................................
  # NOTE: This procedure attempts to use the unzip command line tool in order
  #       to extract a ZIP archive file.  The archiveFileName argument is the
  #       ZIP archive file to extract.  The extractRootDirectory argument is
  #       the location of a directory that should contain a new temporary
  #       extraction directory.  The actual temporary extraction directory is
  #       returned.
  #
  proc extractZipArchive { archiveFileName extractRootDirectory } {
    setupUnzipVars false

    variable baseUri
    variable unzipExtractCommand
    variable unzipUri
    variable unzipUrn
    variable unzipVersionCommand

    set fileName [file nativename $archiveFileName]




    set extractDirectory [file join $extractRootDirectory \
        [appendArgs ea-uz-xa- [pid] - [string trim [clock seconds] -]]]


    set directory [file nativename $extractDirectory]

    if {[isEagle]} then {
      #
      # HACK: On Windows only, when the unzip command line tool does
      #       not appear to be installed, attempt to download it to a







<







 







|










>
>
>
|
|
>







34
35
36
37
38
39
40

41
42
43
44
45
46
47
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    # NOTE: The base URI used to build the URIs for the unzip command line
    #       tool downloads.
    #
    variable baseUri; # DEFAULT: [getAuxiliaryBaseUri] -OR- https://urn.to/r

    if {$force || ![info exists baseUri]} then {
      if {[isEagle]} then {

        set baseUri [getAuxiliaryBaseUri]
      } else {
        set baseUri https://urn.to/r
      }
    }

    #
................................................................................
  # NOTE: This procedure attempts to use the unzip command line tool in order
  #       to extract a ZIP archive file.  The archiveFileName argument is the
  #       ZIP archive file to extract.  The extractRootDirectory argument is
  #       the location of a directory that should contain a new temporary
  #       extraction directory.  The actual temporary extraction directory is
  #       returned.
  #
  proc extractZipArchive { archiveFileName extractRootDirectory rootOnly } {
    setupUnzipVars false

    variable baseUri
    variable unzipExtractCommand
    variable unzipUri
    variable unzipUrn
    variable unzipVersionCommand

    set fileName [file nativename $archiveFileName]

    if {$rootOnly} then {
      set extractDirectory $extractRootDirectory
    } else {
      set extractDirectory [file join $extractRootDirectory \
          [appendArgs ea-uz-xa- [pid] - [string trim [clock seconds] -]]]
    }

    set directory [file nativename $extractDirectory]

    if {[isEagle]} then {
      #
      # HACK: On Windows only, when the unzip command line tool does
      #       not appear to be installed, attempt to download it to a

Changes to Externals/Eagle/lib/Eagle1.0/update.eagle.

21
22
23
24
25
26
27
28



29






30
31
32
33
34
35
36
...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
197
198
199
200
201
202
203





204
205

















206
207




















208
209
210
211
212
213
214
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#
namespace eval ::Eagle {
  #
  # NOTE: This procedure returns non-zero if the specified public key token
  #       matches the one in use by the Eagle script engine.
  #
  proc matchEnginePublicKeyToken { publicKeyToken } {
    return [expr {[string length $publicKeyToken] == 0 || \



        $publicKeyToken eq [info engine PublicKeyToken]}]






  }
 
  #
  # NOTE: This procedure returns non-zero if the specified engine name
  #       matches the Eagle script engine.
  #
  proc matchEngineName { name } {
................................................................................
    if {[llength $args] > 0} then {
      #
      # NOTE: Start trusting ONLY our self-signed SSL certificate.
      #
      set trusted true

      if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
        uri softwareupdates true
      } else {
        set trusted false; # NOTE: Already trusted.
      }

      try {
        #
        # NOTE: Download the file from the web site.
................................................................................
        eval uri download $args; # synchronous.
      } finally {
        if {$trusted && \
            [lindex [uri softwareupdates] end] eq "trusted"} then {
          #
          # NOTE: Stop trusting ONLY our self-signed SSL certificate.
          #
          uri softwareupdates false
        }
      }

      #
      # NOTE: Return a result indicating what was done.
      #
      return [appendArgs "downloaded URI " [lindex $args 0] \
................................................................................
  #
  # NOTE: This procedure runs the updater tool and then immediately exits
  #       the process.
  #
  proc runUpdateAndExit { {automatic false} } {
    global tcl_platform






    set directory [file dirname [info nameofexecutable]]


















    set command [list exec -shell -- \
        [file join $directory Hippogriff.exe] -delay 2000]





















    #
    # HACK: The native StrongNameSignatureVerificationEx() function does
    #       not appear to work on WOA (Windows-on-ARM) on the Surface RT
    #       tablet; therefore, attempt to disable its use when calling
    #       into the updater on that platform.
    #
................................................................................
  proc getUpdateData { uri } {
    #
    # NOTE: Start trusting ONLY our own self-signed SSL certificate.
    #
    set trusted true

    if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
      uri softwareupdates true
    } else {
      set trusted false; # NOTE: Already trusted.
    }

    try {
      #
      # NOTE: Download the tag file from the web site.
................................................................................
      return [uri download -inline $uri]; # synchronous.
    } finally {
      if {$trusted && \
          [lindex [uri softwareupdates] end] eq "trusted"} then {
        #
        # NOTE: Stop trusting ONLY our own self-signed SSL certificate.
        #
        uri softwareupdates false
      }
    }
  }
 
  #
  # NOTE: This procedure downloads an update script and then returns it
  #       verbatim.
................................................................................
  proc getUpdateScriptData { uri } {
    #
    # NOTE: Start trusting ONLY our own self-signed SSL certificate.
    #
    set trusted true

    if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
      uri softwareupdates true
    } else {
      set trusted false; # NOTE: Already trusted.
    }

    try {
      #
      # NOTE: Download the script file from the web site.
................................................................................
      return [interp readorgetscriptfile -- "" $uri]; # synchronous.
    } finally {
      if {$trusted && \
          [lindex [uri softwareupdates] end] eq "trusted"} then {
        #
        # NOTE: Stop trusting ONLY our own self-signed SSL certificate.
        #
        uri softwareupdates false
      }
    }
  }
 
  #
  # NOTE: This procedure returns the base URI that should be used to download
  #       available updates, if a specific base URI is not specified via the







|
>
>
>
|
>
>
>
>
>
>







 







|







 







|







 







>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|







 







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
...
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#
namespace eval ::Eagle {
  #
  # NOTE: This procedure returns non-zero if the specified public key token
  #       matches the one in use by the Eagle script engine.
  #
  proc matchEnginePublicKeyToken { publicKeyToken } {
    if {[string length $publicKeyToken] == 0} then {
      return true
    }

    set enginePublicKeyToken [info engine PublicKeyToken]

    if {[string length $enginePublicKeyToken] == 0} then {
      return true
    }

    return [expr {$publicKeyToken eq $enginePublicKeyToken}]
  }
 
  #
  # NOTE: This procedure returns non-zero if the specified engine name
  #       matches the Eagle script engine.
  #
  proc matchEngineName { name } {
................................................................................
    if {[llength $args] > 0} then {
      #
      # NOTE: Start trusting ONLY our self-signed SSL certificate.
      #
      set trusted true

      if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
        catch {uri softwareupdates true}
      } else {
        set trusted false; # NOTE: Already trusted.
      }

      try {
        #
        # NOTE: Download the file from the web site.
................................................................................
        eval uri download $args; # synchronous.
      } finally {
        if {$trusted && \
            [lindex [uri softwareupdates] end] eq "trusted"} then {
          #
          # NOTE: Stop trusting ONLY our self-signed SSL certificate.
          #
          catch {uri softwareupdates false}
        }
      }

      #
      # NOTE: Return a result indicating what was done.
      #
      return [appendArgs "downloaded URI " [lindex $args 0] \
................................................................................
  #
  # NOTE: This procedure runs the updater tool and then immediately exits
  #       the process.
  #
  proc runUpdateAndExit { {automatic false} } {
    global tcl_platform

    #
    # NOTE: Determine the fully qualified file name for the updater.  If
    #       it is not available, we cannot continue.
    #
    set fileName [file join [file normalize \
        [file dirname [info nameofexecutable]]] Hippogriff.exe]

    if {![file exists $fileName]} then {
      error [appendArgs \
          "updater executable \"" $fileName "\" is not available"]
    }

    #
    # NOTE: For .NET Core, updating via the updater tool is unsupported.
    #
    if {[isDotNetCore]} then {
      error [appendArgs \
          "updater executable \"" $fileName "\" unsupported on .NET Core"]
    }

    #
    # NOTE: Start out with just the base [exec] command, -shell option,
    #       and the end-of-options marker.
    #
    set command [list exec -shell --]


    #
    # NOTE: Check for native Tcl and Mono because this impacts how the
    #       shell executable name is determined.
    #
    if {[isEagle] && [isMono]} then {
      #
      # HACK: Assume that Mono is somewhere along the PATH.
      #
      lappend command mono \
          [appendArgs \" [file nativename $fileName] \"]
    } else {
      lappend command $fileName
    }

    #
    # NOTE: Add the base options to the updater executable.  Typically,
    #       this only includes the initial (mutex checking) delay.
    #
    lappend command -delay 2000

    #
    # HACK: The native StrongNameSignatureVerificationEx() function does
    #       not appear to work on WOA (Windows-on-ARM) on the Surface RT
    #       tablet; therefore, attempt to disable its use when calling
    #       into the updater on that platform.
    #
................................................................................
  proc getUpdateData { uri } {
    #
    # NOTE: Start trusting ONLY our own self-signed SSL certificate.
    #
    set trusted true

    if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
      catch {uri softwareupdates true}
    } else {
      set trusted false; # NOTE: Already trusted.
    }

    try {
      #
      # NOTE: Download the tag file from the web site.
................................................................................
      return [uri download -inline $uri]; # synchronous.
    } finally {
      if {$trusted && \
          [lindex [uri softwareupdates] end] eq "trusted"} then {
        #
        # NOTE: Stop trusting ONLY our own self-signed SSL certificate.
        #
        catch {uri softwareupdates false}
      }
    }
  }
 
  #
  # NOTE: This procedure downloads an update script and then returns it
  #       verbatim.
................................................................................
  proc getUpdateScriptData { uri } {
    #
    # NOTE: Start trusting ONLY our own self-signed SSL certificate.
    #
    set trusted true

    if {[lindex [uri softwareupdates] end] eq "untrusted"} then {
      catch {uri softwareupdates true}
    } else {
      set trusted false; # NOTE: Already trusted.
    }

    try {
      #
      # NOTE: Download the script file from the web site.
................................................................................
      return [interp readorgetscriptfile -- "" $uri]; # synchronous.
    } finally {
      if {$trusted && \
          [lindex [uri softwareupdates] end] eq "trusted"} then {
        #
        # NOTE: Stop trusting ONLY our own self-signed SSL certificate.
        #
        catch {uri softwareupdates false}
      }
    }
  }
 
  #
  # NOTE: This procedure returns the base URI that should be used to download
  #       available updates, if a specific base URI is not specified via the

Changes to Externals/Eagle/lib/Test1.0/constraints.eagle.

18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
...
161
162
163
164
165
166
167





























































168
169
170
171
172
173
174
...
343
344
345
346
347
348
349








350
351
352
353
354
355
356
....
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
....
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
....
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
....
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
....
2976
2977
2978
2979
2980
2981
2982
2983

2984















2985
2986
2987
2988
2989

2990
2991
2992
2993
2994
2995
2996
2997
2998

2999
3000
3001
3002
3003
3004
3005
....
3116
3117
3118
3119
3120
3121
3122



3123
3124






3125
3126
3127



3128
3129
3130



3131
3132
3133
3134
3135
3136
3137
....
3153
3154
3155
3156
3157
3158
3159




















3160
3161
3162
3163
3164
3165
3166
3167
....
3504
3505
3506
3507
3508
3509
3510


















3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
....
3713
3714
3715
3716
3717
3718
3719























































































































































































































3720
3721
3722
3723
3724
3725
3726
....
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
....
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
....
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
# 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 getKnownBuildTypes {} {
    return [list \
        NetFx20 NetFx35 NetFx40 NetFx45 NetFx451 NetFx452 \
        NetFx46 NetFx461 NetFx462 NetFx47 NetFx471 Bare \

        LeanAndMean Database MonoOnUnix Development]
  }
 
  proc getKnownCompileOptions {} {
    return [list \
        APPDOMAINS APPROVED_VERBS ARGUMENT_CACHE ARM ARM64 ASSEMBLY_DATETIME \
        ASSEMBLY_RELEASE ASSEMBLY_STRONG_NAME_TAG ASSEMBLY_TAG ASSEMBLY_TEXT \
        ASSEMBLY_URI BREAK_ON_EXITING BREAKPOINTS CACHE_ARGUMENT_TOSTRING \
        CACHE_ARGUMENTLIST_TOSTRING CACHE_DICTIONARY CACHE_RESULT_TOSTRING \
        CACHE_STATISTICS CACHE_STRINGLIST_TOSTRING CALLBACK_QUEUE CAS_POLICY \
        CERTIFICATE_PLUGIN CERTIFICATE_POLICY CERTIFICATE_RENEWAL \
        CODE_ANALYSIS COM_TYPE_CACHE CONSOLE DAEMON DATA DEAD_CODE DEBUG \
        DEBUGGER DEBUGGER_ARGUMENTS DEBUGGER_ENGINE DEBUGGER_EXECUTE \
        DEBUGGER_EXPRESSION DEBUGGER_VARIABLE DEBUG_TRACE DEBUG_WRITE \
        DEMO_EDITION DRAWING DYNAMIC EAGLE EMBEDDED_LIBRARY \
        EMBED_CERTIFICATES ENTERPRISE_LOCKDOWN EXECUTE_CACHE EXPRESSION_FLAGS \
        FAST_ERRORCODE FAST_ERRORINFO FOR_TEST_USE_ONLY HAVE_SIZEOF HISTORY \
        IA64 INTERACTIVE_COMMANDS INTERNALS_VISIBLE_TO ISOLATED_INTERPRETERS \
        ISOLATED_PLUGINS LIBRARY LICENSING LICENSE_MANAGER LIMITED_EDITION \
        LIST_CACHE MONO MONO_BUILD MONO_HACKS MONO_LEGACY NATIVE \
        NATIVE_PACKAGE NATIVE_THREAD_ID NATIVE_UTILITY NATIVE_UTILITY_BSTR \
        NETWORK NET_20 NET_20_FAST_ENUM NET_20_ONLY NET_20_SP1 NET_20_SP2 \
        NET_30 NET_35 NET_40 NET_45 NET_451 NET_452 NET_46 NET_461 NET_462 \

        NET_47 NET_471 NON_WORKING_CODE NOTIFY NOTIFY_ACTIVE NOTIFY_ARGUMENTS \
        NOTIFY_EXCEPTION NOTIFY_EXECUTE NOTIFY_EXPRESSION NOTIFY_GLOBAL \
        NOTIFY_OBJECT OBSOLETE OBFUSCATION OFFICIAL PARSE_CACHE PATCHLEVEL \
        PLUGIN_COMMANDS POLICY_TRACE PREVIOUS_RESULT RANDOMIZE_ID REMOTING \
        RESULT_LIMITS SAMPLE SECURITY SERIALIZATION SHARED_ID_POOL SHELL \
        SOURCE_ID SOURCE_TIMESTAMP STATIC TCL TCL_KITS TCL_THREADED \
        TCL_THREADS TCL_UNICODE TCL_WRAPPER TEST TEST_PLUGIN THREADING \
        THROW_ON_DISPOSED TRACE TYPE_CACHE UNIX USE_APPDOMAIN_FOR_ID \
................................................................................
    #
    if {$force || ![info exists ::no(monoVersions)]} then {
      return [list \
          [list 2 0] [list 2 2] [list 2 4] [list 2 6] [list 2 8] [list 2 10] \
          [list 2 11] [list 3 0] [list 3 1] [list 3 2] [list 3 4] [list 3 6] \
          [list 3 8] [list 3 10] [list 3 12] [list 4 0] [list 4 2] [list 4 4] \
          [list 4 6] [list 4 8] [list 5 0] [list 5 2] [list 5 4] [list 5 8] \
          [list 5 10]]
    } else {
      return [list]
    }
  }
 
  proc addKnownMonoConstraints { generic } {
    #
................................................................................
      }

      lappend result $version
    }

    return $result
  }





























































 
  proc getDottedVersion { version } {
    return [join $version .]
  }
 
  proc getDotlessVersion { version } {
    if {[string first . $version] != -1} then {
................................................................................
  #
  # NOTE: This procedure should return non-zero if the test suite should be
  #       considered to be running on Mono.
  #
  proc isTestMono {} {
    return [expr {![info exists ::no(mono)] && [isMono]}]
  }








 
  proc isTestAdministrator { {force false} } {
    #
    # NOTE: This is a workaround for the [isAdministrator] procedure being
    #       inaccurate for Mono on Windows, primarily due to the inability
    #       of Mono to call a P/Invoke method by ordinal.  Also, this can
    #       be used for native Tcl on Windows.  This only works on Windows.
................................................................................
    }
 
    proc checkForStrongName { channel } {
      tputs $channel "---- checking for strong name... "

      if {[catch {
        object invoke Interpreter.GetActive GetStrongName
      } strongName] == 0 && [string length $strongName] > 0} then {
        #
        # NOTE: Yes, it appears that the core library was signed with a
        #       strong name key.
        #
        addConstraint strongName

        tputs $channel yes\n
................................................................................
    }
 
    proc checkForCertificate { channel } {
      tputs $channel "---- checking for certificate... "

      if {[catch {
        object invoke Interpreter.GetActive GetCertificate
      } certificate] == 0 && [string length $certificate] > 0} then {
        #
        # NOTE: Yes, it appears that the core library was signed with a
        #       code-signing certificate.
        #
        addConstraint certificate

        #
................................................................................
        tputs $channel no\n
      }
    }
 
    proc checkForCompileCSharp { channel } {
      tputs $channel "---- checking for test use of C# compiler... "

      if {![info exists ::no(compileCSharp)]} then {
        addConstraint compileCSharp

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }
................................................................................
    }
 
    proc checkForDefaultAppDomain { channel } {
      tputs $channel "---- checking for default application domain... "

      if {[catch {
        object invoke AppDomain CurrentDomain
      } appDomain] == 0 && [string length $appDomain] > 0} then {
        if {[catch {
          object invoke $appDomain IsDefaultAppDomain
        } default] || [string length $default] == 0} then {
          set default false
        }

        if {[catch {object invoke $appDomain Id} id] || \
................................................................................
      }
    }
 
    proc checkForRuntime { channel } {
      tputs $channel "---- checking for runtime... "

      #
      # NOTE: Are we running inside Mono (regardless of operating system)?

      #















      if {[isTestMono]} 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.
        #
        addKnownMonoConstraints true; # running on .NET.

        tputs $channel [appendArgs [expr {[info exists \
................................................................................

            addConstraint dotnetMatchFramework
            addConstraint [appendArgs dotnetMatchFramework $version(1)]

            addConstraint monoMatchFramework
            addConstraint [appendArgs monoMatchFramework $version(1)]




            tputs $channel yes\n
          } else {






            if {[isMono]} then {
              addConstraint dotnetMatchFramework
              addConstraint [appendArgs dotnetMatchFramework $version(1)]



            } else {
              addConstraint monoMatchFramework
              addConstraint [appendArgs monoMatchFramework $version(1)]



            }

            tputs $channel no\n
          }
        } else {
          tputs $channel "no, missing image runtime version\n"
        }
................................................................................

        #
        # NOTE: Now create a version string for use in the constraint name
        #       (remove the periods).
        #
        set version [string map [list . ""] $dotVersion]





















        if {[isTestMono]} then {
          #
          # NOTE: If the runtime version was found, add a test constraint
          #       for it now.
          #
          if {[string length $version] > 0} then {
              #
              # NOTE: We are running on Mono.  Keep track of the specific
................................................................................
        addConstraint [appendArgs 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 {[isWindows] || ([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 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 {
        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 {
          catch {object flags $debugger +NoDispose}
        }

        if {[regexp -- {^Debugger#\d+$} $debugger]} then {
          #
          # NOTE: Yes, it appears that it is 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 {
          catch {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 {
            catch {object flags $interp +NoDispose}
          }

          if {[regexp -- {^Interpreter#\d+$} $interp]} then {
            #
            # NOTE: Yes, it appears that it is available.
            #
................................................................................
    # NOTE: We need several of our test constraint related commands in the
    #       global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list \
        getKnownBuildTypes getKnownCompileOptions getKnownMonoVersions \
        addKnownMonoConstraints lpermute alwaysFullInterpReady canExecComSpec \
        canExecWhoAmI canExecTclShell canExecFossil canExecVsWhere isTestMono \
        isTestAdministrator canPing cleanConstraintName cleanPackageName \
        haveTclPlatformOsExtraUpdateName checkForTestSuiteFiles \
        checkForPlatform checkForWindowsVersion checkForOperatingSystemUpdate \
        checkForScriptLibrary checkForVariable checkForTclOptions \
        checkForWindowsCommandProcessor checkForPackage checkForFossil \
        checkForVisualStudioViaVsWhere checkForEagle checkForSymbols \
        checkForLogFile checkForGaruda checkForShell \
        checkForOfficialStableReleaseInProgress checkForDebug checkForTk \
        checkForVersion checkForCommand checkForSubCommand checkForNamespaces \
        checkForTestExec checkForTestMachine checkForTestPlatform \
        checkForTestConfiguration checkForTestSuffix checkForFile \
        checkForPathFile checkForNativeCode checkForTip127 checkForTip194 \
        checkForTip207 checkForTip241 checkForTip285 checkForTip405 \
        checkForTip421 checkForTip426 checkForTip429 checkForTip440 \







|
|
>
|










|
|
|
|
|
|
|
|
|
|
|
|
>
|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







|







 







|







 







|







 







|







 







|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




>






|


>







 







>
>
>


>
>
>
>
>
>
|


>
>
>



>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|








|







 







|
|
|
|
|
|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
....
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
....
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
....
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
....
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
....
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
....
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
....
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
....
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662

3663
3664
3665
3666
3667
3668
3669
....
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
....
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
....
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
....
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
# 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 getKnownBuildTypes {} {
    return [list \
        NetFx20 NetFx35 NetFx40 NetFx45 NetFx451 \
        NetFx452 NetFx46 NetFx461 NetFx462 NetFx47 \
        NetFx471 NetStandard20 Bare LeanAndMean \
        Database MonoOnUnix Development]
  }
 
  proc getKnownCompileOptions {} {
    return [list \
        APPDOMAINS APPROVED_VERBS ARGUMENT_CACHE ARM ARM64 ASSEMBLY_DATETIME \
        ASSEMBLY_RELEASE ASSEMBLY_STRONG_NAME_TAG ASSEMBLY_TAG ASSEMBLY_TEXT \
        ASSEMBLY_URI BREAK_ON_EXITING BREAKPOINTS CACHE_ARGUMENT_TOSTRING \
        CACHE_ARGUMENTLIST_TOSTRING CACHE_DICTIONARY CACHE_RESULT_TOSTRING \
        CACHE_STATISTICS CACHE_STRINGLIST_TOSTRING CALLBACK_QUEUE CAS_POLICY \
        CERTIFICATE_PLUGIN CERTIFICATE_POLICY CERTIFICATE_RENEWAL \
        CODE_ANALYSIS COM_TYPE_CACHE CONFIGURATION CONSOLE DAEMON DATA \
        DEAD_CODE DEBUG DEBUGGER DEBUGGER_ARGUMENTS DEBUGGER_ENGINE \
        DEBUGGER_EXECUTE DEBUGGER_EXPRESSION DEBUGGER_VARIABLE DEBUG_TRACE \
        DEBUG_WRITE DEMO_EDITION DRAWING DYNAMIC EAGLE EMBEDDED_LIBRARY \
        EMBED_CERTIFICATES EMIT ENTERPRISE_LOCKDOWN EXECUTE_CACHE \
        EXPRESSION_FLAGS FAST_ERRORCODE FAST_ERRORINFO FOR_TEST_USE_ONLY \
        HAVE_SIZEOF HISTORY IA64 INTERACTIVE_COMMANDS INTERNALS_VISIBLE_TO \
        ISOLATED_INTERPRETERS ISOLATED_PLUGINS LIBRARY LICENSING \
        LICENSE_MANAGER LIMITED_EDITION LIST_CACHE MONO MONO_BUILD MONO_HACKS \
        MONO_LEGACY NATIVE NATIVE_PACKAGE NATIVE_THREAD_ID NATIVE_UTILITY \
        NATIVE_UTILITY_BSTR NETWORK NET_20 NET_20_FAST_ENUM NET_20_ONLY \
        NET_20_SP1 NET_20_SP2 NET_30 NET_35 NET_40 NET_45 NET_451 NET_452 \
        NET_46 NET_461 NET_462 NET_47 NET_471 NET_STANDARD_20 \
        NON_WORKING_CODE NOTIFY NOTIFY_ACTIVE NOTIFY_ARGUMENTS \
        NOTIFY_EXCEPTION NOTIFY_EXECUTE NOTIFY_EXPRESSION NOTIFY_GLOBAL \
        NOTIFY_OBJECT OBSOLETE OBFUSCATION OFFICIAL PARSE_CACHE PATCHLEVEL \
        PLUGIN_COMMANDS POLICY_TRACE PREVIOUS_RESULT RANDOMIZE_ID REMOTING \
        RESULT_LIMITS SAMPLE SECURITY SERIALIZATION SHARED_ID_POOL SHELL \
        SOURCE_ID SOURCE_TIMESTAMP STATIC TCL TCL_KITS TCL_THREADED \
        TCL_THREADS TCL_UNICODE TCL_WRAPPER TEST TEST_PLUGIN THREADING \
        THROW_ON_DISPOSED TRACE TYPE_CACHE UNIX USE_APPDOMAIN_FOR_ID \
................................................................................
    #
    if {$force || ![info exists ::no(monoVersions)]} then {
      return [list \
          [list 2 0] [list 2 2] [list 2 4] [list 2 6] [list 2 8] [list 2 10] \
          [list 2 11] [list 3 0] [list 3 1] [list 3 2] [list 3 4] [list 3 6] \
          [list 3 8] [list 3 10] [list 3 12] [list 4 0] [list 4 2] [list 4 4] \
          [list 4 6] [list 4 8] [list 5 0] [list 5 2] [list 5 4] [list 5 8] \
          [list 5 10] [list 5 12]]
    } else {
      return [list]
    }
  }
 
  proc addKnownMonoConstraints { generic } {
    #
................................................................................
      }

      lappend result $version
    }

    return $result
  }
 
  proc getDotNetCoreDirectoryNameOnly { path } {
    #
    # HACK: Obtain parent directory name that matches "net*", if any (e.g.
    #       "netcoreapp2.0", "netstandard2.0", etc).
    #
    if {[string length $path] > 0} then {
      set tail [file tail $path]

      if {[string match net* $tail]} then {
        return $tail
      }
    }

    return ""
  }
 
  proc getDotNetCoreLibPathDirectoryNameOnly { {name ""} } {
    #
    # NOTE: Search for matching directories based on the globally detected
    #       library path associated with the current core library.
    #
    if {[info exists ::core_lib_path] && \
        [string length $::core_lib_path] > 0} then {
      #
      # NOTE: Grab all directories that are directly beneath the detected
      #       library path, if any.
      #
      foreach directory [glob \
          -nocomplain -types {d} -- [file join $::core_lib_path *]] {
        #
        # NOTE: If the caller specified a (plugin) name to match against,
        #       make sure it matches; otherwise, skip this directory.
        #
        if {[string length $name] > 0 && \
            ![string match $name [file tail $directory]]} then {
          continue
        }

        #
        # NOTE: Find directories beneath the current candidate directory
        #       that are .NET Core output directories.
        #
        set directories [glob \
            -nocomplain -types {d} -- [file join $directory net*]]

        #
        # NOTE: If there is at least one match, we are done.  Return the
        #       final path segment of the directory name to the caller.
        #
        if {[llength $directories] > 0} then {
          return [file tail [lindex $directories 0]]
        }
      }
    }

    #
    # NOTE: There was no match, just return something obviously invalid.
    #
    return ""
  }
 
  proc getDottedVersion { version } {
    return [join $version .]
  }
 
  proc getDotlessVersion { version } {
    if {[string first . $version] != -1} then {
................................................................................
  #
  # NOTE: This procedure should return non-zero if the test suite should be
  #       considered to be running on Mono.
  #
  proc isTestMono {} {
    return [expr {![info exists ::no(mono)] && [isMono]}]
  }
 
  #
  # NOTE: This procedure should return non-zero if the test suite should be
  #       considered to be running on .NET Core.
  #
  proc isTestDotNetCore {} {
    return [expr {![info exists ::no(dotNetCore)] && [isDotNetCore]}]
  }
 
  proc isTestAdministrator { {force false} } {
    #
    # NOTE: This is a workaround for the [isAdministrator] procedure being
    #       inaccurate for Mono on Windows, primarily due to the inability
    #       of Mono to call a P/Invoke method by ordinal.  Also, this can
    #       be used for native Tcl on Windows.  This only works on Windows.
................................................................................
    }
 
    proc checkForStrongName { channel } {
      tputs $channel "---- checking for strong name... "

      if {[catch {
        object invoke Interpreter.GetActive GetStrongName
      } strongName] == 0 && [isNonNullObjectHandle $strongName]} then {
        #
        # NOTE: Yes, it appears that the core library was signed with a
        #       strong name key.
        #
        addConstraint strongName

        tputs $channel yes\n
................................................................................
    }
 
    proc checkForCertificate { channel } {
      tputs $channel "---- checking for certificate... "

      if {[catch {
        object invoke Interpreter.GetActive GetCertificate
      } certificate] == 0 && [isNonNullObjectHandle $certificate]} then {
        #
        # NOTE: Yes, it appears that the core library was signed with a
        #       code-signing certificate.
        #
        addConstraint certificate

        #
................................................................................
        tputs $channel no\n
      }
    }
 
    proc checkForCompileCSharp { channel } {
      tputs $channel "---- checking for test use of C# compiler... "

      if {![info exists ::no(compileCSharp)] && ![isTestDotNetCore]} then {
        addConstraint compileCSharp

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }
................................................................................
    }
 
    proc checkForDefaultAppDomain { channel } {
      tputs $channel "---- checking for default application domain... "

      if {[catch {
        object invoke AppDomain CurrentDomain
      } appDomain] == 0 && [isNonNullObjectHandle $appDomain]} then {
        if {[catch {
          object invoke $appDomain IsDefaultAppDomain
        } default] || [string length $default] == 0} then {
          set default false
        }

        if {[catch {object invoke $appDomain Id} id] || \
................................................................................
      }
    }
 
    proc checkForRuntime { channel } {
      tputs $channel "---- checking for runtime... "

      #
      # NOTE: Are we running inside Mono -OR- on .NET Core (regardless
      #       of operating system)?
      #
      if {[isTestDotNetCore]} then {
        #
        # NOTE: Yes, it appears that we are running on .NET Core.
        #
        addConstraint dotNetCore; # running on .NET Core.
        addConstraint dotNetOrDotNetCore

        #
        # NOTE: We do not want to skip Mono bugs on .NET Core.
        #
        addKnownMonoConstraints true; # running on .NET Core.

        tputs $channel [appendArgs [expr {[info exists \
            ::eagle_platform(runtime)] ? \
            $::eagle_platform(runtime) : ".NET Core"}] \n]
      } elseif {[isTestMono]} then {
        #
        # NOTE: Yes, it appears that we are running inside Mono.
        #
        addConstraint mono; # running on Mono.
        addConstraint monoOrDotNetCore

        tputs $channel [appendArgs [expr {[info exists \
            ::eagle_platform(runtime)] ? \
            $::eagle_platform(runtime) : "Mono"}] \n]
      } else {
        #
        # NOTE: It appears that we are running on the full .NET.
        #
        addConstraint dotNet; # running on .NET.
        addConstraint dotNetOrDotNetCore

        #
        # NOTE: We do not want to skip Mono bugs on .NET.
        #
        addKnownMonoConstraints true; # running on .NET.

        tputs $channel [appendArgs [expr {[info exists \
................................................................................

            addConstraint dotnetMatchFramework
            addConstraint [appendArgs dotnetMatchFramework $version(1)]

            addConstraint monoMatchFramework
            addConstraint [appendArgs monoMatchFramework $version(1)]

            addConstraint dotnetCoreMatchFramework
            addConstraint [appendArgs dotnetCoreMatchFramework $version(1)]

            tputs $channel yes\n
          } else {
            if {[isTestDotNetCore]} then {
              addConstraint dotnetMatchFramework
              addConstraint [appendArgs dotnetMatchFramework $version(1)]

              addConstraint monoMatchFramework
              addConstraint [appendArgs monoMatchFramework $version(1)]
            } elseif {[isTestMono]} then {
              addConstraint dotnetMatchFramework
              addConstraint [appendArgs dotnetMatchFramework $version(1)]

              addConstraint dotnetCoreMatchFramework
              addConstraint [appendArgs dotnetCoreMatchFramework $version(1)]
            } else {
              addConstraint monoMatchFramework
              addConstraint [appendArgs monoMatchFramework $version(1)]

              addConstraint dotnetCoreMatchFramework
              addConstraint [appendArgs dotnetCoreMatchFramework $version(1)]
            }

            tputs $channel no\n
          }
        } else {
          tputs $channel "no, missing image runtime version\n"
        }
................................................................................

        #
        # NOTE: Now create a version string for use in the constraint name
        #       (remove the periods).
        #
        set version [string map [list . ""] $dotVersion]

        if {[isTestDotNetCore]} then {
          #
          # NOTE: If the runtime version was found, add a test constraint
          #       for it now.
          #
          if {[string length $version] > 0} then {
            #
            # NOTE: We are running on the .NET Core.  Keep track of the
            #       specific version for usage in test constraints.
            #
            addConstraint [appendArgs dotNetCore $version]
            addConstraint [appendArgs dotNetCore $version OrHigher]
          }

          #
          # NOTE: We do not want to skip any Mono bugs on .NET Core.  Add
          #       the necessary constraints for each version of Mono we
          #       know about.
          #
          addKnownMonoConstraints false; # running on .NET.
        } elseif {[isTestMono]} then {
          #
          # NOTE: If the runtime version was found, add a test constraint
          #       for it now.
          #
          if {[string length $version] > 0} then {
              #
              # NOTE: We are running on Mono.  Keep track of the specific
................................................................................
        addConstraint [appendArgs runtime. $option]

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }
 
    proc testForDynamicLoading { {fileName ""} } {
      if {[catch {
        if {[isWindows] && [string length $fileName] == 0} then {
          set fileName kernel32; # HACK: Always pre-loaded?
        }

        set error null

        object invoke -flags +NonPublic \
            Eagle._Components.Private.NativeOps TestLoadLibrary \
            $fileName error
      } code] == 0 && $code eq "Ok"} then {
        return true
      }

      return false
    }
 
    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 {[isWindows] || [testForDynamicLoading]} then {

        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint dynamic

        tputs $channel yes\n
      } else {
................................................................................
        }

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }
 
    proc checkForExcelUsable { channel } {
      tputs $channel "---- checking for usable instance of Excel... "

      #
      # NOTE: As of this writing, this check is only supported on Windows.
      #
      if {[isWindows]} then {
        #
        # NOTE: This constraint check must run after the interop assembly for
        #       Excel has been detected, because this check makes use of it.
        #
        if {[haveConstraint Microsoft.Office.Interop.Excel]} then {
          #
          # NOTE: This constraint check requires the (optional) interpreter
          #       isolation feature of Eagle in order to keep the primary
          #       interpreter and AppDomain tidy.  It also requires access
          #       to native Windows support in order to use the [info hwnd]
          #       sub-command.
          #
          if {[haveConstraint compile.ISOLATED_INTERPRETERS] && \
              [haveConstraint compile.NATIVE] && \
              [haveConstraint compile.WINDOWS]} then {
            try {
              if {[catch {
                #
                # NOTE: In an attempt to limit the assemblies loaded into the
                #       primary AppDomain, create an isolated interpreter.
                #
                set interp [interp create -isolated]

                #
                # NOTE: Give the newly created (isolated) interpreter a means
                #       to set variables in the parent (this) interpreter.
                #
                interp alias $interp pset {} set; # parent set

                #
                # NOTE: Evaluate all the Excel interop assembly related code
                #       in the other AppDomain.
                #
                interp eval $interp {
                  #
                  # NOTE: First, attempt to load the Excel interop assembly.
                  #       If this fails, we cannot continue and Excel is not
                  #       considered usable.
                  #
                  set assembly [object load -import -declare \
                      Microsoft.Office.Interop.Excel]

                  #
                  # NOTE: Next, attempt to run the Excel application using
                  #       its automation object model.  If this fails, we
                  #       cannot continue and Excel is not considered usable.
                  #
                  set application [object create -alias \
                      Microsoft.Office.Interop.Excel.ApplicationClass]; # run

                  #
                  # NOTE: Next, attempt to extract the process ID associated
                  #       with the Excel application window.  This is used to
                  #       help make sure the running Excel instance is closed
                  #       after our testing is complete.  Generally, this will
                  #       not fail because we know the [info hwnd] sub-command
                  #       should be available, due to define constant checks.
                  #
                  pset pid [getDictionaryValue \
                      [info hwnd [$application Hwnd]] processId]

                  #
                  # NOTE: Next, attempt to make sure that the Excel instance
                  #       is not visible and will not display alerts/prompts.
                  #       If this fails, Excel is not considered usable.
                  #
                  $application Visible false
                  $application DisplayAlerts false

                  #
                  # NOTE: Next, create a value of an enumerated type exposed
                  #       by the Excel automation object model so that we can
                  #       add a new workbook.  Generally, this does not fail.
                  #       If this fails, Excel is not considered usable.
                  #
                  set enumValue [object invoke -create \
                      Enum Parse XlWBATemplate xlWBATWorksheet]

                  #
                  # NOTE: Next, attempt to add a new workbook.  If this fails,
                  #       Excel is not considered usable.
                  #
                  set workbook [object invoke -alias \
                      $application.Workbooks Add $enumValue]

                  #
                  # NOTE: The test package is needed in order to make use of
                  #       the [getTemporaryFileName] procedure.
                  #
                  package require Eagle.Test

                  #
                  # NOTE: Setup a temporary file name that can be used to save
                  #       the Excel spreadsheet.
                  #
                  pset fileName [set fileName [file nativename \
                      [appendArgs [getTemporaryFileName] .xls]]]

                  #
                  # NOTE: Next, attempt to save a new workbook.  If this fails,
                  #       Excel is not considered usable.
                  #
                  $workbook SaveAs $fileName

                  #
                  # NOTE: Next, attempt to close Excel.  If this fails, Excel
                  #       is not considered usable.
                  #
                  $application Quit; # close

                  #
                  # NOTE: Finally, cleanup our local state just to be tidy.
                  #
                  unset workbook enumValue application assembly; # dispose
                }
              } result] == 0} then {
                #
                # NOTE: It appears the Excel instance is usable.
                #
                addConstraint excel.usable

                #
                # NOTE: Show that a usable Excel instance was found.
                #
                tputs $channel yes\n
              } else {
                #
                # NOTE: This is the list of error message patterns that may
                #       indicate a trial version of Excel is being used.
                #
                set patterns [list \
                    "* 0x800AC472*" "* 0x800A03EC*" \
                    "* application has expired.*"]

                #
                # NOTE: Check each error message pattern.  Upon finding any
                #       match, mark Excel as unusable due to being a trial
                #       edition and then stop.
                #
                foreach pattern $patterns {
                  #
                  # TODO: For now, just use [string match] here; eventually,
                  #       regular expressions may be needed.
                  #
                  if {[string match $pattern $result]} then {
                    #
                    # NOTE: It appears that Excel is a trial edition.
                    #
                    addConstraint excel.trial

                    #
                    # NOTE: Show that the Excel trial edition was found.
                    #
                    tputs $channel "no, trial\n"

                    #
                    # NOTE: We are done here, return now.
                    #
                    return
                  }
                }

                #
                # NOTE: It appears the Excel instance is not usable.
                #
                addConstraint excel.unusable

                #
                # NOTE: Show that a unusable Excel instance was found.
                #
                tputs $channel "no, broken\n"
              }
            } finally {
              #
              # NOTE: Make sure the isolated interpreter is deleted if it was
              #       actually created.
              #
              if {[info exists interp] && [interp exists $interp]} then {
                catch {interp delete $interp}
              }

              #
              # NOTE: Make sure the Excel process is (forcibly) closed if it
              #       is still running at this point.
              #
              if {[info exists pid] && $pid in [getProcesses excel]} then {
                catch {kill -force $pid}
              }

              #
              # NOTE: Make sure the temporary spreadsheet file is deleted if
              #       it was actually created.
              #
              if {[info exists fileName] && [file exists $fileName]} then {
                catch {file delete $fileName}
              }
            }
          } else {
            tputs $channel "unknown, missing optional feature\n"
          }
        } else {
          tputs $channel "unknown, no Excel interop assembly\n"
        }
      } else {
        tputs $channel "unknown, not running on Windows\n"
      }
    }
 
    proc checkForTclInstalls { channel } {
      tputs $channel "---- checking for Tcl installs... "

      #
      # NOTE: Check for dynamically loadable Tcl libraries (for this
      #       architecture only).
................................................................................
      #
      if {[catch {
        object invoke -flags +NonPublic Interpreter.GetActive Debugger
      } debugger] == 0} then {
        #
        # NOTE: We do not own this, do not dispose it.
        #
        if {[isNonNullObjectHandle $debugger]} then {
          catch {object flags $debugger +NoDispose}
        }

        if {[regexp -- {^Debugger#\d+$} $debugger]} then {
          #
          # NOTE: Yes, it appears that it is available.
          #
................................................................................
      #
      if {[catch {
        object invoke -flags +NonPublic Interpreter.GetActive Debugger
      } debugger] == 0} then {
        #
        # NOTE: We do not own this, do not dispose it.
        #
        if {[isNonNullObjectHandle $debugger]} then {
          catch {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 {[isNonNullObjectHandle $interp]} then {
            catch {object flags $interp +NoDispose}
          }

          if {[regexp -- {^Interpreter#\d+$} $interp]} then {
            #
            # NOTE: Yes, it appears that it is available.
            #
................................................................................
    # NOTE: We need several of our test constraint related commands in the
    #       global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list \
        getKnownBuildTypes getKnownCompileOptions getKnownMonoVersions \
        addKnownMonoConstraints lpermute alwaysFullInterpReady canExecComSpec \
        canExecWhoAmI canExecTclShell canExecFossil canExecVsWhere isTestMono \
        isTestDotNetCore isTestAdministrator canPing cleanConstraintName \
        cleanPackageName haveTclPlatformOsExtraUpdateName \
        checkForTestSuiteFiles checkForPlatform checkForWindowsVersion \
        checkForOperatingSystemUpdate checkForScriptLibrary checkForVariable \
        checkForTclOptions checkForWindowsCommandProcessor checkForPackage \
        checkForFossil checkForVisualStudioViaVsWhere checkForEagle \
        checkForSymbols checkForLogFile checkForGaruda checkForShell \
        checkForOfficialStableReleaseInProgress checkForDebug checkForTk \
        checkForVersion checkForCommand checkForSubCommand checkForNamespaces \
        checkForTestExec checkForTestMachine checkForTestPlatform \
        checkForTestConfiguration checkForTestSuffix checkForFile \
        checkForPathFile checkForNativeCode checkForTip127 checkForTip194 \
        checkForTip207 checkForTip241 checkForTip285 checkForTip405 \
        checkForTip421 checkForTip426 checkForTip429 checkForTip440 \

Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.

170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187


















































188
189
190
191
192
193
194
...
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
...
945
946
947
948
949
950
951



952
953
954
955
956
957
958
....
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
....
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
....
1385
1386
1387
1388
1389
1390
1391











1392
1393
1394
1395
1396
1397
1398
....
1489
1490
1491
1492
1493
1494
1495




































1496
1497
1498
1499
1500
1501
1502
....
1616
1617
1618
1619
1620
1621
1622





















1623
1624
1625
1626
1627
1628
1629
....
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
....
1711
1712
1713
1714
1715
1716
1717







1718
1719
1720
1721
1722
1723
1724
....
1935
1936
1937
1938
1939
1940
1941



1942
1943
1944
1945
1946
1947
1948
....
1950
1951
1952
1953
1954
1955
1956



1957
1958
1959
1960
1961
1962
1963
....
2084
2085
2086
2087
2088
2089
2090











2091
2092
2093
2094
2095
2096
2097
....
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
....
2438
2439
2440
2441
2442
2443
2444
























2445
2446
2447
2448
2449
2450
2451
....
2463
2464
2465
2466
2467
2468
2469










2470
2471
2472
2473
2474
2475
2476
....
3027
3028
3029
3030
3031
3032
3033
3034


3035
3036
3037
3038
3039
3040
3041
  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
  }
................................................................................
                ![haveConstraint quiet]} then {
              tputs $test_channel \
                  "==== WARNING: attempting automatic Tcl shell selection...\n"
            }

            set test_tclsh [getTclShellFileName \
                [expr {![info exists no(automaticTclShell)]}] \
                [expr {![info exists no(tclKit)]}]]

          } else {
            #
            # NOTE: Skip detection and use the fallback default.
            #
            set test_tclsh tclsh
          }
        }
................................................................................
      $root_path \"\n]

  tputs $test_channel [appendArgs "---- binary path: \"" \
      $bin_path \"\n]

  tputs $test_channel [appendArgs "---- library path: \"" \
      $lib_path \"\n]




  tputs $test_channel [appendArgs "---- test suite files located in: \"" \
      $test_all_path \"\n]

  tputs $test_channel [appendArgs "---- test script files located in: \"" \
      $test_path \"\n]

................................................................................

    #
    # NOTE: If the "no(mono)" variable is set (to anything) then any
    #       special test suite hacks for Mono will be disabled. This
    #       does not control or change any hacks for Mono that may
    #       be present in the library itself.
    #
    # if {[isTestMono]} then {
    #   set no(mono) true
    # }

    ###########################################################################
    ######################### BEGIN Eagle Constraints #########################
    ###########################################################################

................................................................................
      #
      # NOTE: For tests "excel-*", "object-2.*", "object-7.1", "object-8.*",
      #       and "object-98.*".
      #
      checkForReferenceCountTracking $test_channel
    }

    #
    # NOTE: Has testing using the C# compiler been disabled?
    #
    if {![info exists no(checkForCompileCSharp)]} then {
      checkForCompileCSharp $test_channel
    }

    #
    # NOTE: Has compile/runtime option testing support been disabled?
    #
    if {![info exists no(compileOptions)]} then {
      #
      # NOTE: Has "known" compile option testing support been disabled?
      #
................................................................................
        #
        if {![info exists no(compileCasPolicy)]} then {
          #
          # NOTE: For tests "load-1.6" and "load-1.7".
          #
          checkForCompileOption $test_channel CAS_POLICY
        }












        #
        # NOTE: Has console support been enabled (at compile-time)?
        #
        if {![info exists no(compileConsole)]} then {
          #
          # NOTE: For test "host-1.2".
................................................................................
        #
        if {![info exists no(compileApprovedVerbs)]} then {
          #
          # NOTE: For test "object-4.8".
          #
          checkForCompileOption $test_channel APPROVED_VERBS
        }





































        #
        # NOTE: Has Mono support been enabled (at compile-time)?
        #
        if {![info exists no(compileMono)]} then {
          #
          # NOTE: For test "object-4.13".
................................................................................
        if {![info exists no(compileSerialization)]} then {
          #
          # NOTE: For test "interp-1.10".
          #
          checkForCompileOption $test_channel SERIALIZATION
        }






















        #
        # NOTE: Has dedicated test support been enabled (at compile-time)?
        #
        if {![info exists no(compileTest)]} then {
          #
          # NOTE: For tests "basic-1.20", "basic-1.21", "function-1.1",
          #       "object-2.1", "object-3.1", "object-4.1", "object-7.1",
................................................................................
        #
        # NOTE: Has GDI+ drawing support been enabled (at compile-time)?
        #
        if {![info exists no(compileDrawing)]} then {
          checkForCompileOption $test_channel DRAWING
        }

        #
        # NOTE: Has WinForms support been enabled (at compile-time)?
        #
        if {![info exists no(compileWinForms)]} then {
          checkForCompileOption $test_channel WINFORMS
        }

        #
        # NOTE: Has runtime license checking support been disabled (at
        #       compile-time)?  This only applies to third-party plugins
        #       and applications.
        #
        if {![info exists no(compileLicensing)]} then {
          #
................................................................................
          #
          # NOTE: This is not currently used by any tests.
          #
          checkForCompileOption $test_channel DEMO_EDITION
        }
      }
    }








    #
    # NOTE: Has dynamic loading testing support been disabled?
    #
    if {![info exists no(dynamic)]} then {
      #
      # NOTE: For tests "commands-1.1.*", "library-3.*", and "tcl*-*.*".
................................................................................
            *TestCallDynamicCallback1*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallDynamicCallback2*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallDynamicCallback3*




        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestGetDynamicCallbacks*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback0*

................................................................................
            *TestCallStaticDynamicCallback1*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback2*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback3*




        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestGetStaticDynamicCallbacks*
      }

      #
      # NOTE: Has DateTime testing support been disabled?
................................................................................
        #
        # NOTE: This is not currently used by any tests.
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSetComplain*
      }












      #
      # NOTE: Has enumerable variable testing support been disabled?
      #
      if {![info exists no(testEnumerableVariables)]} then {
        #
        # NOTE: For test "basic-1.105".
        #
................................................................................
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSaveObjects*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRestoreObjects*

        #
        # NOTE: For test "basic-1.29".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteStaticDelegates*

        #
        # NOTE: For tests "basic-1.30" and "basic-1.31".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteDelegateCommands*

        #
        # NOTE: For test "namespace-97.10".
        #
................................................................................

        #
        # NOTE: For test "basic-1.75".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default+Listener \
            * Eagle._Tests.Default.Listener
      }
























    }

    #
    # NOTE: Has MSBuild testing support been disabled?
    #
    if {![info exists no(msBuild)]} then {
      #
................................................................................
    # NOTE: Has Excel testing support been disabled?
    #
    if {![info exists no(excel)]} then {
      #
      # NOTE: For tests "excel-*.*".
      #
      checkForAssembly $test_channel Microsoft.Office.Interop.Excel










    }

    #
    # NOTE: Has speech testing support been disabled?
    #
    if {![info exists no(speech)]} then {
      #
................................................................................
      checkForFile $test_channel [file join $test_data_path settings.xml]
    }

    #
    # NOTE: For tests "load-1.1.*".
    #
    if {![info exists no(Plugin.dll)]} then {
      checkForFile $test_channel [file join $lib_path Plugin1.0 Plugin.dll]


    }

    #
    # NOTE: For test "object-6.1".
    #
    if {![info exists no(Sample.exe)]} then {
      checkForFile $test_channel [file join $bin_path Sample.exe]







|
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>







 







>
>
>







 







|







 







<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<







 







>
>
>
>
>
>
>







 







>
>
>







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>







 







|





|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







|
>
>







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
....
1401
1402
1403
1404
1405
1406
1407







1408
1409
1410
1411
1412
1413
1414
....
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
....
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
....
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
....
1783
1784
1785
1786
1787
1788
1789







1790
1791
1792
1793
1794
1795
1796
....
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
....
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
....
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
....
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
....
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
....
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
....
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
....
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
  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.  This variant is based on where the process
  #       executable is located.
  #
  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 location of the [non-script] library directory
  #       (i.e. the directory where the plugins are located), if
  #       necessary.  This variant is based on where the Eagle
  #       core library -OR- Tcl core library assembly is located.
  #
  if {![info exists core_lib_path]} then {
    #
    # NOTE: Attempt to obtain the information for the Eagle core
    #       library assembly.  This will not work for native Tcl.
    #
    if {[catch {info assembly} lib_dir] == 0} then {
      #
      # NOTE: Grab the directory for the core library assembly.
      #
      set core_lib_path [file dirname [lindex $lib_dir end]]

      #
      # NOTE: Perform a check for the .NET Core output directories
      #       (e.g. "netcoreapp2.0", etc), which must be removed
      #       if present, prior to further checks.
      #
      if {![info exists no(dotNetCoreLibPath)] && \
          [string match net* [file tail $core_lib_path]]} then {
        #
        # NOTE: Remove the .NET Core output directory name.
        #
        set core_lib_path [file dirname $core_lib_path]
      }

      #
      # NOTE: Go up one level, to remove the "bin" directory and
      #       then append the "lib" directory.  This gives us the
      #       final path we need.
      #
      set core_lib_path [file normalize \
          [file join [file dirname $core_lib_path] lib]]
    } else {
      #
      # NOTE: This is native Tcl.  There is no way to query the
      #       path for the Tcl core library itself (e.g. "tcl*.dll",
      #       "libtcl*.so", etc); however, using [info library] is
      #       close enough.
      #
      set core_lib_path [file normalize [file dirname [info library]]]
    }

    unset lib_dir
  }

  #
  # NOTE: Set the web host to test against, if necessary.
  #
  if {![info exists test_host]} then {
    set test_host eagle.to
  }
................................................................................
                ![haveConstraint quiet]} then {
              tputs $test_channel \
                  "==== WARNING: attempting automatic Tcl shell selection...\n"
            }

            set test_tclsh [getTclShellFileName \
                [expr {![info exists no(automaticTclShell)]}] \
                [expr {![info exists no(tclKit)]}] \
                [expr {[info exists test_machine] ? $test_machine : ""}]]
          } else {
            #
            # NOTE: Skip detection and use the fallback default.
            #
            set test_tclsh tclsh
          }
        }
................................................................................
      $root_path \"\n]

  tputs $test_channel [appendArgs "---- binary path: \"" \
      $bin_path \"\n]

  tputs $test_channel [appendArgs "---- library path: \"" \
      $lib_path \"\n]

  tputs $test_channel [appendArgs "---- core library path: \"" \
      $core_lib_path \"\n]

  tputs $test_channel [appendArgs "---- test suite files located in: \"" \
      $test_all_path \"\n]

  tputs $test_channel [appendArgs "---- test script files located in: \"" \
      $test_path \"\n]

................................................................................

    #
    # NOTE: If the "no(mono)" variable is set (to anything) then any
    #       special test suite hacks for Mono will be disabled. This
    #       does not control or change any hacks for Mono that may
    #       be present in the library itself.
    #
    # if {[isMono]} then {
    #   set no(mono) true
    # }

    ###########################################################################
    ######################### BEGIN Eagle Constraints #########################
    ###########################################################################

................................................................................
      #
      # NOTE: For tests "excel-*", "object-2.*", "object-7.1", "object-8.*",
      #       and "object-98.*".
      #
      checkForReferenceCountTracking $test_channel
    }








    #
    # NOTE: Has compile/runtime option testing support been disabled?
    #
    if {![info exists no(compileOptions)]} then {
      #
      # NOTE: Has "known" compile option testing support been disabled?
      #
................................................................................
        #
        if {![info exists no(compileCasPolicy)]} then {
          #
          # NOTE: For tests "load-1.6" and "load-1.7".
          #
          checkForCompileOption $test_channel CAS_POLICY
        }

        #
        # NOTE: Has configuration support been enabled (at compile-time)?
        #
        if {![info exists no(compileConfiguration)]} then {
          #
          # NOTE: For tests "debug-1.3", "object-99.1", "object-11.4",
          #       and "garuda-1.2".
          #
          checkForCompileOption $test_channel CONFIGURATION
        }

        #
        # NOTE: Has console support been enabled (at compile-time)?
        #
        if {![info exists no(compileConsole)]} then {
          #
          # NOTE: For test "host-1.2".
................................................................................
        #
        if {![info exists no(compileApprovedVerbs)]} then {
          #
          # NOTE: For test "object-4.8".
          #
          checkForCompileOption $test_channel APPROVED_VERBS
        }

        #
        # NOTE: Has embedded library support been enabled (at
        #       compile-time)?
        #
        if {![info exists no(compileEmbeddedLibrary)]} then {
          #
          # NOTE: For test "interp-1.400".
          #
          checkForCompileOption $test_channel EMBEDDED_LIBRARY
        }

        #
        # NOTE: Has System.Reflection.Emit support been enabled (at
        #       compile-time)?
        #
        if {![info exists no(compileEmit)]} then {
          #
          # NOTE: For tests "commands-1.1.*", "debug-9.1", "library-*",
          #       "object-4.10", "object-4.11", "object-4.12",
          #       "object-8.1??", and "perf-101.0".
          #
          checkForCompileOption $test_channel EMIT
        }

        #
        # NOTE: Has .NET Standard 2.0 support been enabled (at
        #       compile-time)?
        #
        if {![info exists no(compileNetStandard20)]} then {
          #
          # NOTE: For tests "basic-1.29.*", "basic-1.30.*", "host-1.1",
          #       "interp-1.601", "redefine-6.2", and "sql-1.17".
          #
          checkForCompileOption $test_channel NET_STANDARD_20
        }

        #
        # NOTE: Has Mono support been enabled (at compile-time)?
        #
        if {![info exists no(compileMono)]} then {
          #
          # NOTE: For test "object-4.13".
................................................................................
        if {![info exists no(compileSerialization)]} then {
          #
          # NOTE: For test "interp-1.10".
          #
          checkForCompileOption $test_channel SERIALIZATION
        }

        #
        # NOTE: Has remoting support been enabled (at compile-time)?
        #
        if {![info exists no(compileRemoting)]} then {
          #
          # NOTE: For tests "remotingServer-1.*".
          #
          checkForCompileOption $test_channel REMOTING
        }

        #
        # NOTE: Has result size limit support been enabled (at
        #       compile-time)?
        #
        if {![info exists no(compileResultLimits)]} then {
          #
          # NOTE: For tests "interp-1.500" and "interp-1.501".
          #
          checkForCompileOption $test_channel RESULT_LIMITS
        }

        #
        # NOTE: Has dedicated test support been enabled (at compile-time)?
        #
        if {![info exists no(compileTest)]} then {
          #
          # NOTE: For tests "basic-1.20", "basic-1.21", "function-1.1",
          #       "object-2.1", "object-3.1", "object-4.1", "object-7.1",
................................................................................
        #
        # NOTE: Has GDI+ drawing support been enabled (at compile-time)?
        #
        if {![info exists no(compileDrawing)]} then {
          checkForCompileOption $test_channel DRAWING
        }








        #
        # NOTE: Has runtime license checking support been disabled (at
        #       compile-time)?  This only applies to third-party plugins
        #       and applications.
        #
        if {![info exists no(compileLicensing)]} then {
          #
................................................................................
          #
          # NOTE: This is not currently used by any tests.
          #
          checkForCompileOption $test_channel DEMO_EDITION
        }
      }
    }

    #
    # NOTE: Has testing using the C# compiler been disabled?
    #
    if {![info exists no(checkForCompileCSharp)]} then {
      checkForCompileCSharp $test_channel
    }

    #
    # NOTE: Has dynamic loading testing support been disabled?
    #
    if {![info exists no(dynamic)]} then {
      #
      # NOTE: For tests "commands-1.1.*", "library-3.*", and "tcl*-*.*".
................................................................................
            *TestCallDynamicCallback1*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallDynamicCallback2*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallDynamicCallback3*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallDynamicCallback4*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestGetDynamicCallbacks*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback0*

................................................................................
            *TestCallStaticDynamicCallback1*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback2*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback3*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestCallStaticDynamicCallback4*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestGetStaticDynamicCallbacks*
      }

      #
      # NOTE: Has DateTime testing support been disabled?
................................................................................
        #
        # NOTE: This is not currently used by any tests.
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSetComplain*
      }

      #
      # NOTE: Has special variable testing support been disabled?
      #
      if {![info exists no(testSetVariable)]} then {
        #
        # NOTE: For test "basic-1.107".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSetVariableWithTypedValue*
      }

      #
      # NOTE: Has enumerable variable testing support been disabled?
      #
      if {![info exists no(testEnumerableVariables)]} then {
        #
        # NOTE: For test "basic-1.105".
        #
................................................................................
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestSaveObjects*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRestoreObjects*

        #
        # NOTE: For test "basic-1.29.*".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteStaticDelegates*

        #
        # NOTE: For tests "basic-1.30.*" and "basic-1.31".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestExecuteDelegateCommands*

        #
        # NOTE: For test "namespace-97.10".
        #
................................................................................

        #
        # NOTE: For test "basic-1.75".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default+Listener \
            * Eagle._Tests.Default.Listener
      }

      #
      # NOTE: Has script event thread testing support been disabled?
      #
      if {![info exists no(testScriptEventThread)]} then {
        #
        # NOTE: For test "interp-1.801".
        #
        checkForObjectMember $test_channel \
            Eagle._Tests.Default+ScriptEventState \
            *ToString* Eagle._Tests.Default.ScriptEventState.ToString

        checkForObjectMember $test_channel \
            Eagle._Tests.Default+ScriptEventThread \
            *ToString* Eagle._Tests.Default.ScriptEventThread.ToString

        checkForObjectMember $test_channel \
            Eagle._Tests.Default+ScriptThreadClientData \
            *ToString* Eagle._Tests.Default.ScriptThreadClientData.ToString

        checkForObjectMember $test_channel \
            Eagle._Tests.Default+ScriptTimeoutThread \
            *ToString* Eagle._Tests.Default.ScriptTimeoutThread.ToString
      }
    }

    #
    # NOTE: Has MSBuild testing support been disabled?
    #
    if {![info exists no(msBuild)]} then {
      #
................................................................................
    # NOTE: Has Excel testing support been disabled?
    #
    if {![info exists no(excel)]} then {
      #
      # NOTE: For tests "excel-*.*".
      #
      checkForAssembly $test_channel Microsoft.Office.Interop.Excel

      #
      # NOTE: Has Excel usability testing been disabled?
      #
      if {![info exists no(excelUsable)]} then {
        #
        # NOTE: For tests "excel-*.*".
        #
        checkForExcelUsable $test_channel
      }
    }

    #
    # NOTE: Has speech testing support been disabled?
    #
    if {![info exists no(speech)]} then {
      #
................................................................................
      checkForFile $test_channel [file join $test_data_path settings.xml]
    }

    #
    # NOTE: For tests "load-1.1.*".
    #
    if {![info exists no(Plugin.dll)]} then {
      checkForFile $test_channel [file join \
          $core_lib_path Plugin1.0 [getDotNetCoreLibPathDirectoryNameOnly \
          Plugin1.0] Plugin.dll]
    }

    #
    # NOTE: For test "object-6.1".
    #
    if {![info exists no(Sample.exe)]} then {
      checkForFile $test_channel [file join $bin_path Sample.exe]