#############################################################################
##
#W  omget.g             OpenMath Package         Andrew Solomon
##
#H  @(#)$Id: omget.g,v 1.17 2006/01/27 15:01:24 gap Exp $
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
##
##  Reads an OpenMath object from an input stream and returns
##  a GAP object.
##
##

Revision.("openmath/gap/omget.g") :=
"@(#)$Id: omget.g,v 1.17 2006/01/27 15:01:24 gap Exp $";


# create a temporary directory that will be used by OMGetObject

BindGlobal( "OMDirectoryTemporary", DirectoryTemporary() );


#############################################################################
##
#F  OMGetObject 
##
##  <stream> is an input stream with an OpenMath object on it.
##  Takes precisely one object off <stream> (using pipeobj)
##  and puts it onto an output stream connected to a named
##  pipe (from.gap) to gpipe, which parses the object into
##  a byte stream and returns it on "to.gap". 
##  From there the byte stream is turned into a GAP object
##  by OMgetObjectByteStream.
##


## This is the old version, that uses 'Exec'


#InstallGlobalFunction("OMGetObject",
#function(stream)
#  local
#    instream, outstream, # streams from gpipe and to gpipe
#    fromgap, togap, # named pipes 
#		gpipe_exec, # filename of gpipe executable
#		success, # whether PipeOpenMathObject worked
#		gap_obj;
#
#  gpipe_exec := Filename(DirectoriesPackagePrograms("openmath"), "gpipe");
#
#  if gpipe_exec = fail  then
#      Error( "package ``openmath'': the program `gpipe' is not compiled;\n",
#      "see the README file or the dvi/ps/pdf manual of the package ``openmath''.\n",
#      "Without this program, conversion from OpenMath to GAP cannot be performed.\n" );
#  fi;
#
#  
#  # make names for the named pipes: pout: GAP->gpipe, pin: gpipe->GAP
#  fromgap := Filename( OMDirectoryTemporary, "from.gap" );
#  togap := Filename( OMDirectoryTemporary, "to.gap" );
#
#  # remove pipes, in case they exist from a previous call of OMGetObject
#  RemoveFile(fromgap);
#  RemoveFile(togap);
#  
#  # create the pipes
#  Exec(Concatenation(["mkfifo ",fromgap]));
#  Exec(Concatenation(["mkfifo ",togap]));
#
#  # now run gpipe in the background
#  Exec(Concatenation(["cat ",fromgap," | ",gpipe_exec," -u -  ",togap," &"]));
#
#  instream := InputTextFile(togap);
#  outstream := OutputTextFile(fromgap, false);
#  SetPrintFormattingStatus(outstream, false);
#  success := PipeOpenMathObject(stream, outstream);
#  CloseStream( outstream );
#  if success <> true  then
#    CloseStream( instream );
#    Error( "OpenMath object not retrieved" );
#  fi;
#
#  # feed in the object to outstream
#  gap_obj := OMgetObjectByteStream(instream);
#  CloseStream( instream );
#  return gap_obj;
#
#end);


## This is the new version, that uses 'Process'
## by Marco Costantini


InstallGlobalFunction( "OMGetObject",
function( stream )
    local
        togap_stream, fromgap_stream, # streams from gpipe and to gpipe
        fromgap, togap, # strings
        gpipe_exec, # filename of gpipe executable
        success, # whether PipeOpenMathObject worked
        gap_obj;

    if IsClosedStream( stream )  then
        Error( "closed stream" );
    elif IsEndOfStream( stream )  then
        Error( "end of stream" );
    fi;

    gpipe_exec := Filename( DirectoriesPackagePrograms( "openmath" ), "gpipe" );

    if gpipe_exec = fail  then
        Error( "package ``openmath'': the program `gpipe' is not compiled;\n",
         "see the README file or the dvi/ps/pdf manual of the package ``openmath''.\n",
         "Without this program, conversion from OpenMath to GAP cannot be performed.\n" );
    fi;

    fromgap := "";
    togap := "";

    # Get one OpenMath object from 'stream' and put into 'fromgap',
    # using PipeOpenMathObject

    fromgap_stream := OutputTextString( fromgap, false );
    SetPrintFormattingStatus( fromgap_stream, false );

    success := PipeOpenMathObject( stream, fromgap_stream );

    CloseStream( fromgap_stream );
    if success <> true  then
        Error( "OpenMath object not retrieved" );
    fi;


    # Pipe 'fromgap' to 'gpipe', getting 'togap'

    fromgap_stream := InputTextString( fromgap );
    togap_stream := OutputTextString( togap, false );
    SetPrintFormattingStatus( togap_stream, false );

    Process( OMDirectoryTemporary, gpipe_exec,
             fromgap_stream, togap_stream, [ "-u", "-", "-" ] );

    CloseStream( fromgap_stream );
    CloseStream( togap_stream );


    # Send 'togap' to OMgetObjectByteStream, getting a Gap object

    togap_stream := InputTextString( togap );

    gap_obj := OMgetObjectByteStream( togap_stream );

    CloseStream( togap_stream );
    return gap_obj;

end );

