###############################################################################
#
# exec.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Eagle Execute Package File
#
# Copyright (c) 2007-2012 by Joe Mistachkin. All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################
#
# NOTE: Use our own namespace here because even though we do not directly
# support namespaces ourselves, we do not want to pollute the global
# namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
#
# NOTE: This procedure executes a native Tcl or Eagle sub-shell using the
# specified arguments and returns the captured output, verbatim.
#
proc execShell { options args } {
#
# NOTE: Start out with just the base [exec] command.
#
set command [list exec]
#
# NOTE: Add options for the [exec] command, if any.
#
if {[llength $options] > 0} then {
eval lappend command $options
}
#
# NOTE: Always add the end-of-options marker.
#
lappend command --
#
# 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 [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.
#
if {[isEagle] && [llength [info commands object]] > 0} then {
if {[catch {
object invoke -flags +NonPublic Interpreter.GetActive HasSecurity
} security] == 0 && $security} then {
lappend command -security true
}
}
#
# NOTE: Add command line arguments to the shell command, if any.
#
if {[llength $args] > 0} then {
eval lappend command $args
}
#
# NOTE: Finally, execute the resulting [exec] command in the context
# of the caller, returning its result.
#
return [uplevel 1 $command]
}
#
# NOTE: This procedure is designed to extract the exit code for a child
# process run via [exec] using the value of $::errorCode. It will
# always return either a valid integer -OR- the specified default
# value, which may be an empty string.
#
proc maybeGetExitCode { value {default ""} } {
if {[lindex $value 0] eq "CHILDSTATUS"} then {
set status [lindex $value 2]
if {[string is integer -strict $status]} then {
return $status
}
}
return $default
}
#
# NOTE: Provide the Eagle "execute" package to the interpreter.
#
package provide Eagle.Execute \
[expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}