Пример #1
0
        static async Task runCoqtop(string coqtopBin, string mainChannel, string controlChannel, bool ideSlave, IEnumerable <string> args, string traceFile)
        {
            var editorMain = await openChannelSocket(mainChannel);

            var editorControl = await openChannelSocket(controlChannel);

            Stream coqtopMain;
            Stream coqtopControl;
            var    coqtop = new Process();

            coqtop.StartInfo.UseShellExecute        = false;
            coqtop.StartInfo.RedirectStandardError  = false;
            coqtop.StartInfo.RedirectStandardInput  = true;
            coqtop.StartInfo.RedirectStandardOutput = false;
            //if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
            //{// coqtop expects a dedicated read and write socket for each channel on Windows due to a bug in OCaml
            var coqtopMainR    = new TcpListener(IPAddress.Loopback, 0);
            var coqtopMainW    = new TcpListener(IPAddress.Loopback, 0);
            var coqtopControlR = new TcpListener(IPAddress.Loopback, 0);
            var coqtopControlW = new TcpListener(IPAddress.Loopback, 0);

            coqtopMainR.Start(1);
            coqtopMainW.Start(1);
            coqtopControlR.Start(1);
            coqtopControlW.Start(1);
            var coqtopMainAddr    = ((IPEndPoint)coqtopMainR.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopMainR.LocalEndpoint).Port + ":" + ((IPEndPoint)coqtopMainW.LocalEndpoint).Port;
            var coqtopControlAddr = ((IPEndPoint)coqtopControlR.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopControlR.LocalEndpoint).Port + ":" + ((IPEndPoint)coqtopControlW.LocalEndpoint).Port;
            var arguments         = String.Format("{0} -main-channel {1} -control-channel {2} ", ideSlave ? "-ideslave" : "", coqtopMainAddr, coqtopControlAddr)
                                    + String.Join(" ", args);

            coqtop.StartInfo.FileName  = coqtopBin;
            coqtop.StartInfo.Arguments = arguments;
            coqtop.Start();
            //var stderr = Console.OpenStandardError();
            //coqtop.StandardError.BaseStream.CopyToAsync(stderr);
            //coqtop.StandardOutput.BaseStream.CopyToAsync(stderr);

            var connections = await Task.WhenAny(new Task <Tuple <Stream, Stream> >[]
                                                 { AcceptCoqTopConnections(coqtopMainR, coqtopMainW, coqtopControlR, coqtopControlW)
                                                   , Task.Run <Tuple <Stream, Stream> >(() => { System.Threading.Thread.Sleep(5000); return((Tuple <Stream, Stream>)null); }) }).Result;

            if (connections == null)
            {
                await Console.Error.WriteLineAsync("No response from coqtop.");

                System.Environment.Exit(-1);
            }

            coqtopMain    = connections.Item1;
            coqtopControl = connections.Item2;

            coqtopMainR.Stop();
            coqtopMainW.Stop();
            coqtopControlR.Stop();
            coqtopControlW.Stop();
            //} else {
            //  var coqtopMainRW = new TcpListener(IPAddress.Loopback, 0);
            //  var coqtopControlRW = new TcpListener(IPAddress.Loopback, 0);
            //  var coqtopMainAddr = ((IPEndPoint)coqtopMainRW.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopMainRW.LocalEndpoint).Port;
            //  var coqtopControlAddr = ((IPEndPoint)coqtopControlRW.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopControlRW.LocalEndpoint).Port;
            //  var arguments = String.Format("{0} -main-channel {1} -control-channel {2}", ideSlave ? "-ideslave" : "", coqtopMainAddr, coqtopControlAddr)
            //    + String.Join(" ", args);
            //  coqtopMainRW.Start();
            //  coqtopControlRW.Start();

            //  coqtop = Process.Start(coqtopBin, arguments);

            //  var coqtopMainConnection = await coqtopMainRW.AcceptTcpClientAsync();
            //  var coqtopControlConnection = await coqtopControlRW.AcceptTcpClientAsync();
            //  coqtopMain = coqtopMainConnection.GetStream();
            //  coqtopControl = coqtopControlConnection.GetStream();
            //  coqtopMainRW.Stop();
            //  coqtopControlRW.Stop();
            //}

            FileStream trace = null;

            if (traceFile != null)
            {
                try
                {
                    File.Delete(traceFile);
                    trace = new FileStream(traceFile, FileMode.Create);
                    var header      = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n</root>";
                    var headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
                    trace.Write(headerBytes, 0, headerBytes.Length);
                    trace.Position = header.IndexOf("\n</root>");
                }
                catch (Exception)
                {
                    trace = null;
                }
            }

            if (trace != null)
            {
                var closeXml      = "\n</root>";
                var closeXmlBytes = System.Text.Encoding.UTF8.GetBytes(closeXml);
                coqtopMain    = new TraceStream(coqtopMain, System.Text.Encoding.UTF8.GetBytes("\n<!-- editor->coqtop main-channel: -->\n"), closeXmlBytes, trace);
                editorMain    = new TraceStream(editorMain, System.Text.Encoding.UTF8.GetBytes("\n<!-- coqtop->editor main-channel: -->\n"), closeXmlBytes, trace);
                coqtopControl = new TraceStream(coqtopControl, System.Text.Encoding.UTF8.GetBytes("\n<!-- editor->coqtop control-channel: -->\n"), closeXmlBytes, trace);
                editorControl = new TraceStream(editorControl, System.Text.Encoding.UTF8.GetBytes("\n<!-- coqtop->editor control-channel: -->\n"), closeXmlBytes, trace);
            }

            var tasks = new List <Task>();

            tasks.Add(coqtopMain.CopyToAsync(editorMain));
            if (!ideSlave)
            {
                tasks.Add(editorMain.CopyToAsync(coqtopMain));
            }
            else
            {
                tasks.Add(copyStreamWithInterrupt(coqtop, editorMain, coqtopMain));
            }
            if (controlChannel != null)
            {
                tasks.Add(coqtopControl.CopyToAsync(editorControl));
                tasks.Add(editorControl.CopyToAsync(coqtopControl));
            }

            await Task.WhenAny(tasks);
        }
Пример #2
0
    static async Task runCoqtop(string coqtopBin, string mainChannel, string controlChannel, bool ideSlave, IEnumerable<string> args, string traceFile)
    {
      var editorMain = await openChannelSocket(mainChannel);
      var editorControl = await openChannelSocket(controlChannel);
      Stream coqtopMain;
      Stream coqtopControl;
      var coqtop = new Process();
      coqtop.StartInfo.UseShellExecute = false;
      coqtop.StartInfo.RedirectStandardError = false;
      coqtop.StartInfo.RedirectStandardInput = true;
      coqtop.StartInfo.RedirectStandardOutput = false;
      //if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
      //{// coqtop expects a dedicated read and write socket for each channel on Windows due to a bug in OCaml
        var coqtopMainR = new TcpListener(IPAddress.Loopback, 0);
        var coqtopMainW = new TcpListener(IPAddress.Loopback, 0);
        var coqtopControlR = new TcpListener(IPAddress.Loopback, 0);
        var coqtopControlW = new TcpListener(IPAddress.Loopback, 0);
        coqtopMainR.Start(1);
        coqtopMainW.Start(1);
        coqtopControlR.Start(1);
        coqtopControlW.Start(1);
        var coqtopMainAddr = ((IPEndPoint)coqtopMainR.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopMainR.LocalEndpoint).Port + ":" + ((IPEndPoint)coqtopMainW.LocalEndpoint).Port;
        var coqtopControlAddr = ((IPEndPoint)coqtopControlR.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopControlR.LocalEndpoint).Port + ":" + ((IPEndPoint)coqtopControlW.LocalEndpoint).Port;
        var arguments = String.Format("{0} -main-channel {1} -control-channel {2} ", ideSlave ? "-ideslave" : "", coqtopMainAddr, coqtopControlAddr)
          + String.Join(" ", args);

        coqtop.StartInfo.FileName = coqtopBin;
        coqtop.StartInfo.Arguments = arguments;
        coqtop.Start();
        //var stderr = Console.OpenStandardError();
        //coqtop.StandardError.BaseStream.CopyToAsync(stderr);
        //coqtop.StandardOutput.BaseStream.CopyToAsync(stderr);

        var connections = await Task.WhenAny(new Task<Tuple<Stream,Stream>>[]
          { AcceptCoqTopConnections(coqtopMainR, coqtopMainW, coqtopControlR, coqtopControlW)
          , Task.Run<Tuple<Stream,Stream>>(() => {System.Threading.Thread.Sleep(5000); return (Tuple<Stream,Stream>)null; })
          }).Result;
        if (connections == null)
        {
          await Console.Error.WriteLineAsync("No response from coqtop.");
          System.Environment.Exit(-1);
        }

        coqtopMain = connections.Item1;
        coqtopControl = connections.Item2;

        coqtopMainR.Stop();
        coqtopMainW.Stop();
        coqtopControlR.Stop();
        coqtopControlW.Stop();
      //} else {
      //  var coqtopMainRW = new TcpListener(IPAddress.Loopback, 0);
      //  var coqtopControlRW = new TcpListener(IPAddress.Loopback, 0);
      //  var coqtopMainAddr = ((IPEndPoint)coqtopMainRW.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopMainRW.LocalEndpoint).Port;
      //  var coqtopControlAddr = ((IPEndPoint)coqtopControlRW.LocalEndpoint).Address.ToString() + ":" + ((IPEndPoint)coqtopControlRW.LocalEndpoint).Port;
      //  var arguments = String.Format("{0} -main-channel {1} -control-channel {2}", ideSlave ? "-ideslave" : "", coqtopMainAddr, coqtopControlAddr)
      //    + String.Join(" ", args);
      //  coqtopMainRW.Start();
      //  coqtopControlRW.Start();

      //  coqtop = Process.Start(coqtopBin, arguments);

      //  var coqtopMainConnection = await coqtopMainRW.AcceptTcpClientAsync();
      //  var coqtopControlConnection = await coqtopControlRW.AcceptTcpClientAsync();
      //  coqtopMain = coqtopMainConnection.GetStream();
      //  coqtopControl = coqtopControlConnection.GetStream();
      //  coqtopMainRW.Stop();
      //  coqtopControlRW.Stop();
      //}

      FileStream trace = null;
      if (traceFile != null)
      {
        try
        {
          File.Delete(traceFile);
          trace = new FileStream(traceFile, FileMode.Create);
          var header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n</root>";
          var headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
          trace.Write(headerBytes, 0, headerBytes.Length);
          trace.Position = header.IndexOf("\n</root>"); 
        }
        catch (Exception)
        {
          trace = null;
        }
      }

      if (trace != null)
      {
        var closeXml = "\n</root>";
        var closeXmlBytes = System.Text.Encoding.UTF8.GetBytes(closeXml);
        coqtopMain = new TraceStream(coqtopMain, System.Text.Encoding.UTF8.GetBytes("\n<!-- editor->coqtop main-channel: -->\n"), closeXmlBytes, trace);
        editorMain = new TraceStream(editorMain, System.Text.Encoding.UTF8.GetBytes("\n<!-- coqtop->editor main-channel: -->\n"), closeXmlBytes, trace);
        coqtopControl = new TraceStream(coqtopControl, System.Text.Encoding.UTF8.GetBytes("\n<!-- editor->coqtop control-channel: -->\n"), closeXmlBytes, trace);
        editorControl = new TraceStream(editorControl, System.Text.Encoding.UTF8.GetBytes("\n<!-- coqtop->editor control-channel: -->\n"), closeXmlBytes, trace);
      }

      var tasks = new List<Task>();
      tasks.Add(coqtopMain.CopyToAsync(editorMain));
      if (!ideSlave)
        tasks.Add(editorMain.CopyToAsync(coqtopMain));
      else
        tasks.Add(copyStreamWithInterrupt(coqtop, editorMain, coqtopMain));
      if (controlChannel != null)
      {
        tasks.Add(coqtopControl.CopyToAsync(editorControl));
        tasks.Add(editorControl.CopyToAsync(coqtopControl));
      }

      await Task.WhenAny(tasks);        
    }