## server.tcl - Communication with the OdeServer
## ==============
##
## Authors:
## Joseph Wang, Department of Astronomy, University of Texas at Austin
## (joe@athena.mit.edu)
##
## History:
## 12 Aug 1992 Separated this file from proc.tcl
##
## Copyright:
## Copyright (C) 1992 Joseph Wang
##
## 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., 675 Mass Ave, Cambridge, MA 02139, USA.
##

## Conventions:
##   all globally visible objects in this file should begin with
##     OdeServer
##   all interaction with the Ode server should occur through the
##     procedures in this file

## Global Variables

# the file handle of the server

## *************************
## Procedures for communicating with the Ode server
##    OdeServerOpen - opens a connection with the Ode server and
##       returns the opening message
##    OdeServerSend - sends a string to the Ode server
##    OdeServerReceive - receives a string from the Ode server
##    OdeServerClose - shuts down the Ode server
## There are likely to be a lot of problems with deadlock here
## *************************

## OdeServerOpen: Open connection with OdeServer
## ----------
## On entry,
##   exec_string: string to execute
## On exit,
##   the introductory message given by the server
## Side effects,
##   resets the variable OdeServer

proc OdeServerOpen {exec_string} {
   global OdeServer
# open connection with server
# There should be some way of figuring out if the server responds
   set OdeServer [open "| $exec_string" w+]
   return [OdeServerReceive]
}

## OdeServerSend: Send message to Ode Server
## ----------
## On entry,
##   w: message to server
## On exit,
##   returns response from server
## WARNING:
##   SERVER MUST MAKE SOME SORT OF RESPONSE OR ELSE THERE WILL BE DEADLOCK

proc OdeServerSend {w} {
   global OdeServer
   puts $OdeServer $w
   return [OdeServerReceive]
}

## OdeServerReceive: Wait for response from server
## ----------
## On exit,
##   returns response from server
## WARNING:
##   SERVER MUST MAKE SOME SORT OF RESPONSE OR ELSE THERE WILL BE DEADLOCK

proc OdeServerReceive {} {
  global OdeServer
  set return_string ""

# *** THIS FLUSH IS VERY IMPORTANT
# *** If this isn't put here, you are likely to send the application
# ***    into deadlock

  flush $OdeServer

# Get stuff from the server until the prompt string is detected
# Then return everything.  WARNING.  This will freeze if the prompt
# string is never detected

  while {1} {
    gets $OdeServer string
    if {[regexp ".*ode:.*" $string] == 1} {
       break;
    }
    append return_string "$string\n"
  }
  return $return_string;
}

## OdeServerClose: Close connection with server
## ----------
## Side effects:
##   Closes the pipe to the server, resets the server value

proc OdeServerClose {} {
   global OdeServer
# Tell the server to exit
   puts $OdeServer "exit"
# Make sure the message gets there
   flush $OdeServer
# Close the pipe
   close $OdeServer
# reset the server value
   set OdeServer ""
}
