예제 #1
0
 /// <param name="cmd">what command is executing this handler</param>
 /// <param name="tokenizer">parsed tokens from a command string. use <see cref="Tokenizer.Tokenize"/></param>
 /// <param name="source"></param>
 /// <param name="printFunction"></param>
 public Exec(Command cmd, Tokenizer tokenizer, object source, Show.PrintFunc printFunction)
 {
     this.cmd   = cmd;
     this.tok   = tokenizer;
     this.src   = source;
     this.print = printFunction;
 }
예제 #2
0
        public static bool ShowErrorTo(this ITokenErrLog self, Show.PrintFunc show)
        {
            string errStr = self.GetErrorString();

            if (string.IsNullOrEmpty(errStr))
            {
                return(false);
            }
            show.Invoke(errStr); return(true);
        }
예제 #3
0
        public void ParseCommand(Instruction instruction, Show.PrintFunc print, out Tokenizer tokenizer)
        {
            tokenizer = null;
            string trimmed = instruction.text?.Trim();

            if (string.IsNullOrEmpty(trimmed))
            {
                return;
            }
            //Tokenizer tok = new Tokenizer();
            //CodeConvert.TryParseArgs(trimmed, out List<object> parsedCommand, instruction.source, tok);
            //Show.Log(trimmed+":::"+parsedCommand.Stringify());
            string firstWord = Tokenizer.FirstWord(trimmed);

            if (firstWord == null)
            {
                firstWord = trimmed;
            }
            //Show.Log("1stword " + firstWord.StringifySmall());
            Command command = GetCommand(firstWord);

            if (command != null)
            {
                tokenizer = command.Tokenize(trimmed);
                //Show.Log(tokenizer);
                if (tokenizer.HasError())
                {
                    return;
                }
                command.handler.Invoke(new Command.Exec(command, tokenizer, instruction.source, print));
            }
            else
            {
                print.Invoke("unknown command \'" + firstWord + "\'\n");
                tokenizer = new Tokenizer();
                tokenizer.Tokenize(trimmed, Command.BaseArgumentParseRules);
            }
            if (tokenizer.HasError())
            {
                return;
            }
            Instruction next = NextInstruction(tokenizer, instruction.source);

            if (next == null)
            {
                return;
            }
            ParseCommand(next, print, out tokenizer);             // make this a do-while loop instead of tail recursion?
        }
예제 #4
0
 public void ReadLine(Show.PrintFunc lineInputListener)
 {
     tempLineInputListeners.Add(lineInputListener);
 }
예제 #5
0
        public void DoCommand(string s, object whosAsking, Show.PrintFunc cb = null)        //, CmdLine_base cmd = null)
        {
            if (thread == null)
            {
                //_cmd = cmd;
                currentCommand          = s.Trim();
                currentCommand_callback = cb;
                log    = new List <string>();
                err    = new List <string>();
                thread = new System.Threading.Thread(delegate() {
                    string commandName = commandExecutable;
                    if (activeDir == null || activeDir == "")
                    {
                        activeDir = PWD();
                    }
                    system_process = new System.Diagnostics.Process {
                        StartInfo = new ProcessStartInfo {
                            FileName               = commandName,
                            Arguments              = "",
                            UseShellExecute        = false,
                            RedirectStandardOutput = true,
                            RedirectStandardInput  = true,
                            RedirectStandardError  = true,
                            CreateNoWindow         = true,
                            WorkingDirectory       = activeDir
                        }
                    };
                    // find the semaphore file that is used to determine if a command is still running
                    string tempF      = tempFile();
                    string myTempFile = tempF;
                    int fileChecks    = -1;
                    do
                    {
                        if (fileChecks++ > 1000)
                        {
                            throw new System.Exception("could not create valid command line semaphore file");
                        }
                        myTempFile           = tempF + fileChecks;
                        cmdLineSemaphoreFile = new System.IO.FileInfo(myTempFile);
                    } while (cmdLineSemaphoreFile.Exists);
                    StreamWriter sw = new StreamWriter(myTempFile); sw.Close();
                    // make sure the file is unlocked (which signifies that a command is ready to execute)
                    File.SetAttributes(myTempFile, File.GetAttributes(myTempFile) & ~FileAttributes.ReadOnly);

                    system_process.Start();
                    // output data to ignored
                    List <string> outputToIgnore = new List <string>();
                    // asynchronous callback for output. Needs a separate structure to manage what gets output (outputToIgnore)
                    system_process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) {
                        //UnityEngine.Debug.Log("processing '" + e.Data + "' vs ['"+string.Join("', '",outputToIgnore)+"']");
                        if (outputToIgnore.Count > 0)
                        {
                            int ignoreIndex = outputToIgnore.FindIndex(str => e.Data.EndsWith(str));                            //outputToIgnore.IndexOf(e.Data);
                            if (ignoreIndex >= 0)
                            {
                                //UnityEngine.Debug.Log("Ignored " + e.Data+" @" + ignoreIndex);
                                outputToIgnore.RemoveAt(ignoreIndex);
                                return;
                            }
                        }
                        if (currentCommand_callback == null)
                        {
                            log.Add(e.Data);
                            probablyFinishedCommand = true;
                        }
                        else
                        {
                            currentCommand_callback(e.Data);
                            currentCommand_callback = null;
                        }
                    };
                    system_process.BeginOutputReadLine();
                    bool ignoreErrors = true;
                    system_process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) {
                        if (ignoreErrors)
                        {
                            return;
                        }
                        err.Add(e.Data);
                        probablyFinishedCommand = true;
                    };
                    system_process.BeginErrorReadLine();
                    system_process.StandardInput.WriteLine(' ');                     // force an error, because the StandardInput has a weird character in it to start with
                    system_process.StandardInput.Flush();

                    isInitialized      = true;
                    promptNeedsRedraw  = true;
                    string lastCommand = null;
                    while (!system_process.HasExited)
                    {
                        if (!string.IsNullOrEmpty(currentCommand))
                        {
                            ignoreErrors            = false;
                            probablyFinishedCommand = false;
                            BlockOnFileLock(true, outputToIgnore, myTempFile, 1000, "setting up for " + currentCommand);

                            system_process.StandardInput.WriteLine(currentCommand);
                            system_process.StandardInput.Flush();

                            if (!system_process.HasExited)
                            {
                                BlockOnFileLock(false, outputToIgnore, myTempFile, 1000 * 60 * 5, currentCommand + " took longer than 5 minutes");
                            }
                            probablyFinishedCommand = true;
                            promptNeedsRedraw       = true;
                            lastCommand             = currentCommand;
                            currentCommand          = "";
                        }
                        else
                        {
                            Thread.Sleep(10);
                        }
                    }
                    Release();
                });
                thread.Start();
            }
            else
            {
                if (!string.IsNullOrEmpty(s))
                {
                    s += "\n";
                    currentCommand          = s;
                    currentCommand_callback = cb;
                }
            }
        }