summaryrefslogtreecommitdiff
path: root/lib/external_command.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/external_command.tcl')
-rwxr-xr-xlib/external_command.tcl143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/external_command.tcl b/lib/external_command.tcl
new file mode 100755
index 0000000..959cd29
--- /dev/null
+++ b/lib/external_command.tcl
@@ -0,0 +1,143 @@
+#!/usr/bin/tclsh
+# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
+
+############################################################################
+# Copyright (C) 2007-2009 by Martin Ošmera #
+# martin.osmera@gmail.com #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+# --------------------------------------------------------------------------
+# DESCRIPTION
+# Send input read from strandard input to certain Tk application via
+# send command
+#
+# USAGE:
+# set pid [exec -- some_command ?args? |& tclsh external_command.tcl [tk appname] final_cmd line_cmd &]
+# * pid - Process indentifier of $some_command
+# * some_command - Command which output should be couth
+# * args - Arguments for $some_command
+# * final_cmd - Command in local Tcl program to execute once when $some_command finish
+# * line_cmd - Command in local Tcl program to execute everytime when $some_command outputs one line
+# --------------------------------------------------------------------------
+
+# Initialize
+package require Tk
+wm withdraw .
+wm command . "$argv0 $argv"
+wm client . [info hostname]
+
+# Partse agruments
+set target_app [lindex $argv 0]
+set final_cmd [lindex $argv 1]
+set line_cmd [lindex $argv 2]
+unset argv
+
+## Determinate the host OS
+set ::MICROSOFT_WINDOWS 0
+if {[string first {Windows} ${tcl_platform(os)}] != -1} {
+ # Note:
+ # Microsoft Windows is NOT a POSIX system and because of that we need
+ # to do some workarounds here in order to make the IDE functional there.
+ set ::MICROSOFT_WINDOWS 1
+}
+
+# Load dde - Dynamic Data Exchange on Microsoft Windows
+if {$::MICROSOFT_WINDOWS} {
+ package require dde
+}
+
+## Perform secure send command
+ # Secure means that it will not crash or something like that in case of any errors.
+ # But instead it will popup an error message to the user (Tk dialog).
+ # @parm List args - Arguments for the send command
+ # @return void
+proc secure_send args {
+ if {[catch {
+ eval "send $args"
+ } result]} {
+ puts "Unknown IO Error :: $result"
+ tk_messageBox \
+ -title "Unknown IO Error" \
+ -icon error \
+ -type ok \
+ -message "$result"
+
+ if {[ \
+ tk_messageBox \
+ -title "X server security workaround" \
+ -icon warning \
+ -type yesno \
+ -message "If the error was related to X server security, it is possible to temporarily workaround it by running this command: \"/bin/sh << 'for i in `xhost`; do xhost -\$i; done'\"\n\nDo you want to do it ?"
+ ] == {yes}} then {
+ catch {
+ exec -- /bin/sh << {xhost -; for i in `xhost`; do xhost -$i; done}
+ }
+ } else {
+ exit 1
+ }
+
+ if {[catch {
+ eval "send $args"
+ }]} {
+ tk_messageBox \
+ -title "Workaround failed" \
+ -icon error \
+ -type ok \
+ -message "Sorry this doesn't work ...\nIt's a strange bug somewhere in your operating system"
+ exit 1
+ }
+
+ return 1
+
+ } else {
+ return 1
+ }
+}
+
+## Read standard input
+ # All output will be sended at once
+if {$line_cmd == {}} {
+ set result {}
+ while {![eof stdin]} {
+ append result [gets stdin] "\n"
+ }
+
+ if {!${::MICROSOFT_WINDOWS}} {
+ secure_send $target_app $final_cmd "{" [regsub -all {[\{\}]} $result {\\&}] "}"
+ } {
+ dde eval $target_app $final_cmd "{ [regsub -all {[\{\}]} $result {\\&}] }"
+ }
+
+ # Output will be sended line by line as executed command generates it
+} else {
+ while {![eof stdin]} {
+ if {!${::MICROSOFT_WINDOWS}} {
+ secure_send $target_app $line_cmd "{" [regsub -all {[\{\}]} [gets stdin] {\\&}] "}"
+ } {
+ dde eval $target_app $line_cmd "{ [regsub -all {[\{\}]} [gets stdin] {\\&}] }"
+ }
+ }
+
+ if {!${::MICROSOFT_WINDOWS}} {
+ secure_send $target_app $final_cmd
+ } {
+ dde eval $target_app $final_cmd
+ }
+}
+
+exit 0