Tcl/Tk Cookbook - Tcl/Tk and FORTRAN


Step 3:Procedure definitions

Tcl Open

Tcl provides two commands exec and for creating new processes. Tcl open command creates a new process and then uses file I/O commands to communicate with the opened processes.

invokeQuads

Append all the Tcl/Tk script presented in this section to the quads.tcl file. Script listing below is interlaced with explanation (in italics) of specific lines of script. We think this will help you understand the script better would like to hear your comment.


proc invokeQuads { } {
	 set f [open |quads r+]
Tcl command open is called with | as the first character of the argument. This ensures that open is invoked as a command pipeline. The rest of the argument quads is used by open to create the named process.

The returned identifier from open, f in this case, is used for trnsferring data to and from the subprocess.

    foreach e {.f.a .f.b .f.c} {
        set entry [$e get]
	   if { [string compare $entry ""] == 0 } {
		puts stdout "Some entry(ies) are null .... enter them Now \n"
				close $f
				return
		  } else {
			puts $f $entry
		  }
	 }


     flush $f      
For each of the entry widgets ".f.a", ".f.b" and ".f.c", the "get" action gets the value entered. If the entry widget is empty then the user is prompted for input. The pipe is closed and the process returns from the procedure. If the value is non-null then it is written to the pipe. The pipe is flushed to pass the input values from the buffer to "quads".

Note that the entry widgets do not have the binding for the event.


    
    gets $f in_prompt  ;# Input the coefficients a,b,c
    gets $f disc       ;# DISC :     1.0000000000000
    gets $f iflag      ;# IFLAG =   0
    gets $f aux_msg    ;# ROOTS ARE REAL or ... Complex ...
    gets $f roots      ;# x1 =     2.0000000000000  x2 =     1.0000000000000
    close $f           ;# now you can close


The output buffer associated with quads is read to get one null-terminated string at a time and is assigned to a variable. These strings are messages generated by PRINT and WRITE commands by quads.

When all the output messages from quads are read, the pipe is closed.



    set w .info.dum    ;# a quick fix - reassignment avoids the need to declare
		       ;# w as a global

    if { [regexp {(COMPLEX|complex)} $aux_msg cmplx] == 1 } {
		  .zeros.x1 configure -text "Real Part"
        .zeros.x2 configure -text "Imaginary Part"
        $w.type config -text $aux_msg
    } else {
        .zeros.x1 configure -text x1
        .zeros.x2 configure -text x2
        $w.type config -text $aux_msg
	 }

    regexp {(x1 = [ ]*[+|-]*[0-9]*\.[0-9]*)} $roots val1
    regexp {(x2 = [ ]*[+|-]*[0-9]*\.[0-9]*)} $roots val2

    .zeros.x1val configure -text $val1
    .zeros.x2val configure -text $val2
    $w.disc configure -text $disc
}


The lines of script above make repeated use of Tcl regexp command to get the values needed to update the gui and display the result of the computation.

First the string "aux_msg" is parsed to check if the roots are complex (search will look for the substring COMPLEX or complex). If the substring "complex" is found then x1 nad x2 are presented as the real and imaginary parts of the two complex roots.

If not x1 and x2 are presented as the two real roots.

The gui also displays the discriminant. Tk widget configure action is invoked to set the label strings.

Procedure clearEntries


proc clearEntries { } {
	 foreach e {.f.a .f.b .f.c} {
		  $e delete 0 end
	 }
}



The procedure "clearEntries", deletes any input within the entry widgets by deleting all the characters from first to last position. You can invoke this and keep repeating the call to quads.