diff options
Diffstat (limited to 'lib/external_command.tcl')
-rwxr-xr-x | lib/external_command.tcl | 143 |
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 |