/// <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; }
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); }
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? }
public void ReadLine(Show.PrintFunc lineInputListener) { tempLineInputListeners.Add(lineInputListener); }
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; } } }