#******************************************************************************
#***
#*** This file is part of XTeXShell; see file xtexsh for details
#*** Version 0.91 (21.2.94)
#***
#******************************************************************************
#******************************************************************************
#*** Execute Programs in a TCL window *****************************************
#******************************************************************************
proc ExecProg {command} {
#***
#*** Execute command. Command may include the symbol :fname, which
#*** will be replaced by the filname of the file loaded in the editor
#*** or, if specified, by the main filename. :fnamewoext will be replaced
#*** by filename without extension.
#*** If fname == "", use mainname or editfname without extension
#*** Before executing, change to directory of fname
#***
global editfname editwin
global mainflag mainname
global readchild readchierr writechild
global childpid
global boldl_font
global chisaveflag chireloadflag
global critsect
#*** Is there another programm running ?
if {![info exist critsect]} {set critsect 0}
if {[childstat] || $critsect} {
DisplayInfo "Sorry:\nThere is another program running\n\nKill other program first" "$boldl_font"
return
}
set critsect 1
#*** Determine fname as explained above
set fname ""
if {[info exists editfname]} {
set fname $editfname
}
if {$mainflag} {set fname $mainname}
set chisaveflag false
set chireloadflag false
set filenameneeded 0
while {1} {
set pos [string first ":" "$command"]
if {$pos==-1} {break}
set sstr [expr {$pos ? [crange "$command" 0 "$pos-1" ] : ""}]
set estr [crange "$command" "$pos+1" end]
set mstr [string tolower [ctoken estr " .,:"]]
if {[cequal "$mstr" "fnamewoext"]} {
set mstr [strip_extension $fname]
set filenameneeded 1
}
if {[cequal "$mstr" "fname"]} {
set mstr $fname
set filenameneeded 1
}
if {[cequal "$mstr" "save"]} {
set mstr ""
set chisaveflag true
}
if {[cequal "$mstr" "reload"]} {
set mstr ""
set chireloadflag true
}
set command [format "%s%s%s" "$sstr" "$mstr" "$estr"]
}
#*** Does the command need a file name? If yes, check if we have a valid filename
if {$filenameneeded && [cequal "" $fname]} {
if {[info exists editwin] && [winfo exists $editwin]} {
DisplayInfo "Please save your file before executing this command.\n I don't know the name of your file yet" $boldl_font
} else {
DisplayInfo "No File has been specified so far.\nCannot execute command!\nPlease load a file in the editor or specify a main file!" $boldl_font
}
set critsect 0
return
}
if {[set childpid [fork]] == 0} {
dup $readpar stdin; #*** Child process, set IO to pipes
close $readpar
dup $writepar stdout
close $writepar
dup $writeparerr stderr
close $writeparerr
pushd $childpath; #*** Change to data file directory
execl $progname $command
puts stderr "*** Sorry: Programm could not be started"
kill [id process]
exit 255
}
#*** Disable buffering and install driver to update window 5x per second
set critsect 0
after 250 {childIO $childpid}
}
proc childkill {} {
#*** Kill the child process
global childpid
if {[childstat]} {
kill 9 $childpid
}
}
proc childstat {} {
#*** Get status of child. (0 = child does not exist)
#*** If child exists: Read stdout and stderr from child and append to the
#*** variables chistdout and chistderr.
#*** Then check status of child with the wait function and write return value
#*** to chistatus. Return 0 if wait returns end of process condition.
global childpid chireloadflag
global childpid readchild readchierr writechild
global exec_win
if {![info exists childpid]} {set childpid 0; return 0}
if {!$childpid} {return 0}
#*** Read Standard-Error and Standard-Output from child and write it on exec-window
global editor
if {$chireloadflag} {
if {[cequal $editor "xtex"]} { ReLoadFile }
}
set childpid 0
}
}
proc childIO {reqchipid} {
#*** This process runs in background during execution of a unix command
#*** It calls childstat which updates the exec window and restarts itself
#*** after a delay of 200ms
global childpid
if {[childstat]==1 && $reqchipid==$childpid} {
after 200 childIO $reqchipid
}
}