public static void RunCommands(EngineState s, SectionAddress addr, List <CodeCommand> codes, Dictionary <int, string> sectionParams, int depth, bool callback = false) { if (codes.Count == 0) { s.Logger.Build_Write(s, new LogInfo(LogState.Warning, $"No code in [{addr.Plugin.ShortPath}]::[{addr.Section.SectionName}]", s.CurDepth + 1)); return; } CodeCommand curCommand; for (int idx = 0; idx < codes.Count; idx++) { try { curCommand = codes[idx]; s.CurDepth = depth; s.CurSectionParams = sectionParams; ExecuteCommand(s, curCommand); if (s.PassCurrentPluginFlag || s.ErrorHaltFlag || s.UserHaltFlag || s.CmdHaltFlag) { break; } } catch (CriticalErrorException) { // Critical Error, stop build s.ErrorHaltFlag = true; break; } } DisableSetLocal(s, addr.Section); }
public static List <UICommand> ParseRawLines(List <string> lines, SectionAddress addr, out List <LogInfo> errorLogs) { // Select Code sections and compile errorLogs = new List <LogInfo>(); List <UICommand> uiCmdList = new List <UICommand>(); for (int i = 0; i < lines.Count; i++) { try { uiCmdList.Add(ParseUICommand(lines, addr, ref i)); } catch (InvalidUICommandException e) { errorLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} ({e.UICmd.RawLine})")); } catch (InvalidCommandException e) { errorLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} ({e.RawLine})")); } catch (Exception e) { errorLogs.Add(new LogInfo(LogState.Error, e)); } } return(uiCmdList.Where(x => x.Type != UIType.None).ToList()); }
public LogInfo SetMacro(string macroName, string macroCommand, SectionAddress addr, bool permanent) { if (Regex.Match(macroName, Macro.MacroNameRegex, RegexOptions.Compiled).Success == false) // Macro Name Validation { return(new LogInfo(LogState.Error, $"Invalid macro name [{macroName}]")); } if (macroCommand != null) { // Insert // Try parsing CodeCommand cmd = CodeParser.ParseStatement(macroCommand, addr); if (cmd.Type == CodeType.Error) { Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Error)); CodeInfo_Error info = cmd.Info as CodeInfo_Error; return(new LogInfo(LogState.Error, info.ErrorMessage)); } // Put into dictionary if (permanent) // MacroDict { MacroDict[macroName] = cmd; return(new LogInfo(LogState.Success, $"Global Macro [{macroName}] set to [{cmd.RawCode}]")); } else { LocalDict[macroName] = cmd; return(new LogInfo(LogState.Success, $"Local Macro [{macroName}] set to [{cmd.RawCode}]")); } } else { // Delete // Put into dictionary if (permanent) // MacroDict { if (MacroDict.ContainsKey(macroName)) { MacroDict.Remove(macroName); return(new LogInfo(LogState.Success, $"Global Macro [{macroName}] deleted")); } else { return(new LogInfo(LogState.Error, $"Global Macro [{macroName}] not found")); } } else { if (LocalDict.ContainsKey(macroName)) { LocalDict.Remove(macroName); return(new LogInfo(LogState.Success, $"Local Macro [{macroName}] deleted")); } else { return(new LogInfo(LogState.Error, $"Local Macro [{macroName}] not found")); } } } }
public static void RunSection(EngineState s, SectionAddress addr, List <string> sectionParams, int depth, bool callback) { List <CodeCommand> codes = addr.Section.GetCodes(true); s.Logger.Build_Write(s, LogInfo.AddDepth(addr.Section.LogInfos, s.CurDepth + 1)); // Set CurrentSection s.CurrentSection = addr.Section; // Set SectionReturnValue to empty string s.SectionReturnValue = string.Empty; Dictionary <int, string> paramDict = new Dictionary <int, string>(); for (int i = 0; i < sectionParams.Count; i++) { paramDict[i + 1] = StringEscaper.ExpandSectionParams(s, sectionParams[i]); } RunCommands(s, addr, codes, paramDict, depth, callback); // Increase only if cmd resides in CurrentPlugin if (s.CurrentPlugin.Equals(addr.Plugin)) { s.ProcessedSectionHashes.Add(addr.Section.GetHashCode()); } }
private List <LogInfo> ValidateUISection(ScriptSection section) { // Force parsing of code, bypassing caching by section.GetUICtrls() List <string> lines = section.GetLines(); SectionAddress addr = new SectionAddress(p, section); List <UIControl> uiCtrls = UIParser.ParseRawLines(lines, addr, out List <LogInfo> logs); foreach (UIControl uiCmd in uiCtrls) { switch (uiCmd.Type) { case UIControlType.CheckBox: { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_CheckBox)); UIInfo_CheckBox info = uiCmd.Info as UIInfo_CheckBox; if (info.SectionName != null) { if (p.Sections.ContainsKey(info.SectionName)) // Only if section exists { logs.AddRange(ValidateCodeSection(p.Sections[info.SectionName])); } } } break; case UIControlType.Button: { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_Button)); UIInfo_Button info = uiCmd.Info as UIInfo_Button; if (info.SectionName != null) { if (p.Sections.ContainsKey(info.SectionName)) // Only if section exists { logs.AddRange(ValidateCodeSection(p.Sections[info.SectionName])); } } } break; case UIControlType.RadioButton: { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_RadioButton)); UIInfo_RadioButton info = uiCmd.Info as UIInfo_RadioButton; if (info.SectionName != null) { if (p.Sections.ContainsKey(info.SectionName)) // Only if section exists { logs.AddRange(ValidateCodeSection(p.Sections[info.SectionName])); } } } break; } } return(logs); }
/// <summary> /// Render RadioGroup control. /// Return true if failed. /// </summary> /// <param name="r.Canvas">Parent r.Canvas</param> /// <param name="uiCmd">UICommand</param> /// <returns>Success = false, Failure = true</returns> public static void RenderRadioButton(RenderInfo r, UICommand uiCmd, UICommand[] radioButtons) { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_RadioButton)); UIInfo_RadioButton info = uiCmd.Info as UIInfo_RadioButton; double fontSize = CalcFontPointScale(); RadioButton radio = new RadioButton() { GroupName = r.Plugin.FullPath, Content = uiCmd.Text, FontSize = fontSize, IsChecked = info.Selected, VerticalContentAlignment = VerticalAlignment.Center, }; if (info.SectionName != null) { radio.Click += (object sender, RoutedEventArgs e) => { if (r.Plugin.Sections.ContainsKey(info.SectionName)) // Only if section exists { SectionAddress addr = new SectionAddress(r.Plugin, r.Plugin.Sections[info.SectionName]); UIRenderer.RunOneSection(addr, $"{r.Plugin.Title} - RadioButton [{uiCmd.Key}]", info.HideProgress); } else { Application.Current.Dispatcher.Invoke((Action)(() => { MainWindow w = Application.Current.MainWindow as MainWindow; w.Logger.System_Write(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exists")); })); } }; } radio.Checked += (object sender, RoutedEventArgs e) => { RadioButton btn = sender as RadioButton; info.Selected = true; // Uncheck the other RadioButtons List <UICommand> updateList = radioButtons.Where(x => !x.Key.Equals(uiCmd.Key, StringComparison.Ordinal)).ToList(); foreach (UICommand uncheck in updateList) { Debug.Assert(uncheck.Info.GetType() == typeof(UIInfo_RadioButton)); UIInfo_RadioButton unInfo = uncheck.Info as UIInfo_RadioButton; unInfo.Selected = false; } updateList.Add(uiCmd); UICommand.Update(updateList); }; SetToolTip(radio, info.ToolTip); DrawToCanvas(r, radio, uiCmd.Rect); }
public void Beep_Template(EngineState s, string rawCode, BeepType beepType) { SectionAddress addr = EngineTests.DummySectionAddress(); CodeCommand cmd = CodeParser.ParseStatement(rawCode, addr); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Beep)); CodeInfo_Beep info = cmd.Info as CodeInfo_Beep; Assert.IsTrue(info.Type == beepType); }
public UICommand(string rawLine, SectionAddress addr, string key) { this.RawLine = rawLine; this.Addr = addr; this.Key = key; this.Text = string.Empty; this.Visibility = false; this.Type = UIType.None; this.Rect = new Rect(0, 0, 0, 0); }
public UICommand(string rawLine, SectionAddress addr, string key, string text, bool visibility, UIType type, Rect rect, UIInfo info) { this.RawLine = rawLine; this.Addr = addr; this.Key = key; this.Text = text; this.Visibility = visibility; this.Type = type; this.Rect = rect; this.Info = info; }
public void StrFormat_Date_4() { string rawCode = "StrFormat,Date,%Dest%,yyymdd_hhnnss.zzz"; SectionAddress addr = EngineTests.DummySectionAddress(); CodeCommand cmd = CodeParser.ParseStatement(rawCode, addr); // Successfully induced error if (cmd.Type == CodeType.Error) { return; } Assert.Fail(); }
public void StrFormat_Date_2() { string rawCode = "StrFormat,DATE,#9,yyyymmddhhnnsszzz"; SectionAddress addr = EngineTests.DummySectionAddress(); CodeCommand cmd = CodeParser.ParseStatement(rawCode, addr); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_StrFormat)); CodeInfo_StrFormat info = cmd.Info as CodeInfo_StrFormat; Debug.Assert(info.SubInfo.GetType() == typeof(StrFormatInfo_Date)); StrFormatInfo_Date subInfo = info.SubInfo as StrFormatInfo_Date; Assert.IsTrue(subInfo.FormatString.Equals("yyyyMMddHHmmssfff", StringComparison.Ordinal)); }
public void StrFormat_Date_1() { string rawCode = "StrFormat,Date,%Dest%,yyyy-mm-dd_hh:nn:ss.zzz"; SectionAddress addr = EngineTests.DummySectionAddress(); CodeCommand cmd = CodeParser.ParseStatement(rawCode, addr); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_StrFormat)); CodeInfo_StrFormat info = cmd.Info as CodeInfo_StrFormat; Debug.Assert(info.SubInfo.GetType() == typeof(StrFormatInfo_Date)); StrFormatInfo_Date subInfo = info.SubInfo as StrFormatInfo_Date; Assert.IsTrue(subInfo.FormatString.Equals("yyyy-MM-dd_HH:mm:ss.fff", StringComparison.Ordinal)); }
public List <LogInfo> LoadLocalMacroDict(Plugin p, bool append, string sectionName = "Variables") { if (p.Sections.ContainsKey(sectionName)) { PluginSection section = p.Sections[sectionName]; // [Variables]'s type is SectionDataType.Lines // Pick key-value only if key is not wrapped by % SectionAddress addr = new SectionAddress(p, section); Dictionary <string, string> dict = Ini.ParseIniLinesIniStyle(section.GetLines()); return(LoadLocalMacroDict(addr, dict, append)); } else { return(new List <LogInfo>()); } }
/// <summary> /// Render CheckBox control. /// Return true if failed. /// </summary> /// <param name="r.Canvas">Parent r.Canvas</param> /// <param name="uiCmd">UICommand</param> /// <returns>Success = false, Failure = true</returns> public static void RenderCheckBox(RenderInfo r, UICommand uiCmd) { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_CheckBox)); UIInfo_CheckBox info = uiCmd.Info as UIInfo_CheckBox; CheckBox checkBox = new CheckBox() { Content = uiCmd.Text, IsChecked = info.Value, FontSize = CalcFontPointScale(), VerticalContentAlignment = VerticalAlignment.Center, }; if (info.SectionName != null) { checkBox.Click += (object sender, RoutedEventArgs e) => { if (r.Plugin.Sections.ContainsKey(info.SectionName)) // Only if section exists { SectionAddress addr = new SectionAddress(r.Plugin, r.Plugin.Sections[info.SectionName]); UIRenderer.RunOneSection(addr, $"{r.Plugin.Title} - CheckBox [{uiCmd.Key}]", info.HideProgress); } else { r.Logger.System_Write(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exists")); } }; } checkBox.Checked += (object sender, RoutedEventArgs e) => { CheckBox box = sender as CheckBox; info.Value = true; uiCmd.Update(); }; checkBox.Unchecked += (object sender, RoutedEventArgs e) => { CheckBox box = sender as CheckBox; info.Value = false; uiCmd.Update(); }; SetToolTip(checkBox, info.ToolTip); DrawToCanvas(r, checkBox, uiCmd.Rect); }
private List <LogInfo> ValidateCodeSection(ScriptSection section) { // Already processed, so skip if (visitedSections.Contains(section)) { return(new List <LogInfo>()); } // Force parsing of code, bypassing caching by section.GetCodes() List <string> lines = section.GetLines(); SectionAddress addr = new SectionAddress(p, section); List <CodeCommand> codes = CodeParser.ParseStatements(lines, addr, out List <LogInfo> logs); visitedSections.Add(section); InternalValidateCodes(codes, logs); return(logs); }
/// <summary> /// Render ComboBox control. /// Return true if failed. /// </summary> /// <param name="r.Canvas">Parent r.Canvas</param> /// <param name="uiCmd">UICommand</param> /// <returns>Success = false, Failure = true</returns> public static void RenderComboBox(RenderInfo r, UICommand uiCmd) { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_ComboBox)); UIInfo_ComboBox info = uiCmd.Info as UIInfo_ComboBox; ComboBox comboBox = new ComboBox() { FontSize = CalcFontPointScale(), ItemsSource = info.Items, SelectedIndex = info.Index, VerticalContentAlignment = VerticalAlignment.Center, }; comboBox.LostFocus += (object sender, RoutedEventArgs e) => { ComboBox box = sender as ComboBox; if (info.Index != box.SelectedIndex) { info.Index = box.SelectedIndex; uiCmd.Text = info.Items[box.SelectedIndex]; uiCmd.Update(); } }; if (info.SectionName != null) { comboBox.SelectionChanged += (object sender, SelectionChangedEventArgs e) => { if (r.Plugin.Sections.ContainsKey(info.SectionName)) // Only if section exists { SectionAddress addr = new SectionAddress(r.Plugin, r.Plugin.Sections[info.SectionName]); UIRenderer.RunOneSection(addr, $"{r.Plugin.Title} - CheckBox [{uiCmd.Key}]", info.HideProgress); } else { r.Logger.System_Write(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exists")); } }; } SetToolTip(comboBox, info.ToolTip); DrawToCanvas(r, comboBox, uiCmd.Rect); }
public static List <UIControl> ParseRawLines(List <string> lines, SectionAddress addr, out List <LogInfo> errorLogs) { // Select Code sections and compile errorLogs = new List <LogInfo>(); List <UIControl> uiCtrls = new List <UIControl>(); for (int i = 0; i < lines.Count; i++) { try { UIControl uiCtrl = ParseUIControl(lines, addr, ref i); if (uiCtrl != null) { // Check if interface control's key is duplicated if (uiCtrls.Count(x => x.Key.Equals(uiCtrl.Key, StringComparison.OrdinalIgnoreCase)) == 0) { uiCtrls.Add(ParseUIControl(lines, addr, ref i)); } else { errorLogs.Add(new LogInfo(LogState.Error, $"Interface key [{uiCtrl.Key}] is duplicated ({uiCtrl.RawLine})")); } } } catch (InvalidUIControlException e) { errorLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} ({e.UICtrl.RawLine})")); } catch (InvalidCommandException e) { errorLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} ({e.RawLine})")); } catch (Exception e) { errorLogs.Add(new LogInfo(LogState.Error, e)); } } return(uiCtrls.Where(x => x.Type != UIControlType.None).ToList()); }
public static EngineState EvalLines(EngineState s, List<string> rawCodes, CodeType type, ErrorCheck check, out List<CodeCommand> cmds) { // Create CodeCommand SectionAddress addr = EngineTests.DummySectionAddress(); cmds = CodeParser.ParseStatements(rawCodes, addr, out List<LogInfo> errorLogs); if (0 < errorLogs.Where(x => x.State == LogState.Error).Count()) { Assert.IsTrue(check == ErrorCheck.ParserError); return s; } Assert.IsTrue(cmds[0].Type == type); // Run CodeCommand List<LogInfo> logs = Engine.ExecuteCommand(s, cmds[0]); // Assert EngineTests.CheckErrorLogs(logs, check); // Return EngineState return s; }
public static void RunSection(EngineState s, SectionAddress addr, Dictionary <int, string> paramDict, int depth, bool callback) { List <CodeCommand> codes = addr.Section.GetCodes(true); s.Logger.Build_Write(s, LogInfo.AddDepth(addr.Section.LogInfos, s.CurDepth + 1)); // Set CurrentSection s.CurrentSection = addr.Section; // Set SectionReturnValue to empty string s.SectionReturnValue = string.Empty; // Must copy ParamDict by value, not reference RunCommands(s, addr, codes, new Dictionary <int, string>(paramDict), depth, callback); // Increase only if cmd resides is CurrentPlugin if (s.CurrentPlugin.Equals(addr.Plugin)) { s.ProcessedSectionHashes.Add(addr.Section.GetHashCode()); } }
public static EngineState Eval(EngineState s, string rawCode, CodeType type, ErrorCheck check, out CodeCommand cmd) { // Create CodeCommand SectionAddress addr = EngineTests.DummySectionAddress(); cmd = CodeParser.ParseStatement(rawCode, addr); if (cmd.Type == CodeType.Error) { Console.WriteLine((cmd.Info as CodeInfo_Error).ErrorMessage); Assert.IsTrue(check == ErrorCheck.ParserError); return s; } Assert.IsTrue(cmd.Type == type); // Run CodeCommand List<LogInfo> logs = Engine.ExecuteCommand(s, cmd); // Assert EngineTests.CheckErrorLogs(logs, check); // Return EngineState return s; }
public void LogEndOfSection(EngineState s, SectionAddress addr, int depth, bool logPluginName, CodeCommand cmd = null, bool forceLog = false) { if (s.DisableLogger) { return; } bool turnOff = false; if (0 < TurnOff.Count) { if (TurnOff.TryPeek(out turnOff) == false) // Stack Failure { turnOff = false; } } bool TurnOffOriginalValue = turnOff; if (forceLog && TurnOffOriginalValue) { turnOff = false; } if (logPluginName) { LogEndOfSection(s, addr.Section.SectionName, depth, cmd); } else { LogEndOfSection(s, addr.Plugin.ShortPath, addr.Section.SectionName, depth, cmd); } if (forceLog && TurnOffOriginalValue) { turnOff = true; } }
private List <LogInfo> LoadLocalMacroDict(SectionAddress addr, Dictionary <string, string> dict, bool append) { List <LogInfo> logs = new List <LogInfo>(); if (append == false) { localDict.Clear(); } if (0 < dict.Keys.Count) { int count = 0; logs.Add(new LogInfo(LogState.Info, $"Import Local Macro from [{addr.Section.SectionName}]", 0)); foreach (var kv in dict) { try { if (Regex.Match(kv.Key, Macro.MacroNameRegex, RegexOptions.Compiled).Success == false) // Macro Name Validation { logs.Add(new LogInfo(LogState.Error, $"Invalid local macro name [{kv.Key}]")); continue; } localDict[kv.Key] = CodeParser.ParseStatement(kv.Value, addr); logs.Add(new LogInfo(LogState.Success, $"Local macro [{kv.Key}] set to [{kv.Value}]", 1)); count += 1; } catch (Exception e) { logs.Add(new LogInfo(LogState.Error, e)); } } logs.Add(new LogInfo(LogState.Info, $"Imported {count} Local Macro", 0)); logs.Add(new LogInfo(LogState.None, Logger.LogSeperator, 0)); } return(logs); }
public static List <LogInfo> AddVariables(EngineState s, CodeCommand cmd) { Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_AddVariables)); CodeInfo_AddVariables info = cmd.Info as CodeInfo_AddVariables; string pluginFile = StringEscaper.Preprocess(s, info.PluginFile); string sectionName = StringEscaper.Preprocess(s, info.SectionName); Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin); // Does section exists? if (!p.Sections.ContainsKey(sectionName)) { throw new ExecuteException($"Plugin [{pluginFile}] does not have section [{sectionName}]"); } // Directly read from file List <string> lines = Ini.ParseRawSection(p.FullPath, sectionName); // Add Variables Dictionary <string, string> varDict = Ini.ParseIniLinesVarStyle(lines); List <LogInfo> varLogs = s.Variables.AddVariables(info.Global ? VarsType.Global : VarsType.Local, varDict); // Add Macros SectionAddress addr = new SectionAddress(p, p.Sections[sectionName]); List <LogInfo> macroLogs = s.Macro.LoadLocalMacroDict(addr, lines, true); varLogs.AddRange(macroLogs); if (varLogs.Count == 0) // No variables { varLogs.Add(new LogInfo(LogState.Info, $"Plugin [{pluginFile}]'s section [{sectionName}] does not have any variables")); } return(varLogs); }
public static void RunExec(EngineState s, CodeCommand cmd, bool preserveCurParams, bool forceLog, bool callback) { Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_RunExec)); CodeInfo_RunExec info = cmd.Info as CodeInfo_RunExec; string scriptFile = StringEscaper.Preprocess(s, info.ScriptFile); string sectionName = StringEscaper.Preprocess(s, info.SectionName); List <string> paramList = StringEscaper.Preprocess(s, info.Parameters); Script p = Engine.GetScriptInstance(s, cmd, s.CurrentScript.FullPath, scriptFile, out bool inCurrentScript); // Does section exists? if (!p.Sections.ContainsKey(sectionName)) { throw new ExecuteException($"[{scriptFile}] does not have section [{sectionName}]"); } // Section Parameter Dictionary <int, string> paramDict = new Dictionary <int, string>(); if (preserveCurParams) { paramDict = s.CurSectionParams; } else { for (int i = 0; i < paramList.Count; i++) { paramDict[i + 1] = paramList[i]; } } // Branch to new section SectionAddress nextAddr = new SectionAddress(p, p.Sections[sectionName]); s.Logger.LogStartOfSection(s, nextAddr, s.CurDepth, inCurrentScript, paramDict, cmd, forceLog); Dictionary <string, string> localVars = null; Dictionary <string, string> fixedVars = null; Dictionary <string, CodeCommand> localMacros = null; if (cmd.Type == CodeType.Exec) { // Backup Varaibles and Macros localVars = s.Variables.GetVarDict(VarsType.Local); fixedVars = s.Variables.GetVarDict(VarsType.Fixed); localMacros = s.Macro.LocalDict; // Load Per-Script Variables s.Variables.ResetVariables(VarsType.Local); List <LogInfo> varLogs = s.Variables.LoadDefaultScriptVariables(p); s.Logger.Build_Write(s, LogInfo.AddDepth(varLogs, s.CurDepth + 1)); // Load Per-Script Macro s.Macro.ResetLocalMacros(); List <LogInfo> macroLogs = s.Macro.LoadLocalMacroDict(p, false); s.Logger.Build_Write(s, LogInfo.AddDepth(macroLogs, s.CurDepth + 1)); } // Run Section int depthBackup = s.CurDepth; int errorOffStartLineIdxBackup = s.ErrorOffStartLineIdx; int erroroffCountBackup = s.ErrorOffLineCount; Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, callback); if (cmd.Type == CodeType.Exec) { // Restore Variables s.Variables.SetVarDict(VarsType.Local, localVars); s.Variables.SetVarDict(VarsType.Fixed, fixedVars); // Restore Local Macros s.Macro.SetLocalMacros(localMacros); } s.CurDepth = depthBackup; s.ErrorOffStartLineIdx = errorOffStartLineIdxBackup; s.ErrorOffLineCount = erroroffCountBackup; s.Logger.LogEndOfSection(s, nextAddr, s.CurDepth, inCurrentScript, cmd, forceLog); }
public static void Loop(EngineState s, CodeCommand cmd) { Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Loop)); CodeInfo_Loop info = cmd.Info as CodeInfo_Loop; if (info.Break) { if (s.LoopState == LoopState.Off) { s.Logger.Build_Write(s, new LogInfo(LogState.Error, "Loop is not running", cmd, s.CurDepth)); } else { s.LoopState = LoopState.Off; s.Logger.Build_Write(s, new LogInfo(LogState.Info, "Breaking loop", cmd, s.CurDepth)); // Reset LoopCounter, to be sure s.LoopLetter = ' '; s.LoopCounter = 0; } } else if (s.LoopState != LoopState.Off) { // If loop is already turned on, throw error s.Logger.Build_Write(s, new LogInfo(LogState.Error, "Nested loop is not supported", cmd, s.CurDepth)); } else { string startStr = StringEscaper.Preprocess(s, info.StartIdx); string endStr = StringEscaper.Preprocess(s, info.EndIdx); // Prepare Loop string scriptFile = StringEscaper.Preprocess(s, info.ScriptFile); string sectionName = StringEscaper.Preprocess(s, info.SectionName); List <string> paramList = StringEscaper.Preprocess(s, info.Parameters); Script p = Engine.GetScriptInstance(s, cmd, s.CurrentScript.FullPath, scriptFile, out bool inCurrentScript); // Does section exists? if (!p.Sections.ContainsKey(sectionName)) { throw new ExecuteException($"[{scriptFile}] does not have section [{sectionName}]"); } // Section Parameter Dictionary <int, string> paramDict = new Dictionary <int, string>(); for (int i = 0; i < paramList.Count; i++) { paramDict[i + 1] = paramList[i]; } long loopCount = 0; long startIdx = 0, endIdx = 0; char startLetter = ' ', endLetter = ' '; switch (cmd.Type) { case CodeType.Loop: { // Integer Index if (!NumberHelper.ParseInt64(startStr, out startIdx)) { throw new ExecuteException($"Argument [{startStr}] is not a valid integer"); } if (!NumberHelper.ParseInt64(endStr, out endIdx)) { throw new ExecuteException($"Argument [{endStr}] is not a valid integer"); } loopCount = endIdx - startIdx + 1; } break; case CodeType.LoopLetter: { // Drive Letter if (!(startStr.Length == 1 && StringHelper.IsAlphabet(startStr[0]))) { throw new ExecuteException($"Argument [{startStr}] is not a valid drive letter"); } if (!(endStr.Length == 1 && StringHelper.IsAlphabet(endStr[0]))) { throw new ExecuteException($"Argument [{endStr}] is not a valid drive letter"); } startLetter = char.ToUpper(startStr[0]); endLetter = char.ToUpper(endStr[0]); if (endLetter < startLetter) { throw new ExecuteException($"StartLetter must be smaller than EndLetter in lexicographic order"); } loopCount = endLetter - startLetter + 1; } break; default: throw new InternalException("Internal Logic Error at CommandBranch.Loop"); } // Log Messages string logMessage; if (inCurrentScript) { logMessage = $"Loop Section [{sectionName}] [{loopCount}] times"; } else { logMessage = $"Loop [{p.Title}]'s Section [{sectionName}] [{loopCount}] times"; } s.Logger.Build_Write(s, new LogInfo(LogState.Info, logMessage, cmd, s.CurDepth)); // Loop it SectionAddress nextAddr = new SectionAddress(p, p.Sections[sectionName]); int loopIdx = 1; switch (cmd.Type) { case CodeType.Loop: for (s.LoopCounter = startIdx; s.LoopCounter <= endIdx; s.LoopCounter++) { // Counter Variable is [#c] s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"Entering Loop with [{s.LoopCounter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth)); s.Logger.LogSectionParameter(s, s.CurDepth, paramDict, cmd); int depthBackup = s.CurDepth; s.LoopState = LoopState.OnIndex; Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, true); if (s.LoopState == LoopState.Off) // Loop,Break { break; } s.LoopState = LoopState.Off; s.CurDepth = depthBackup; s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"End of Loop with [{s.LoopCounter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth)); loopIdx += 1; } break; case CodeType.LoopLetter: for (s.LoopLetter = startLetter; s.LoopLetter <= endLetter; s.LoopLetter++) { // Counter Variable is [#c] s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"Entering Loop with [{s.LoopLetter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth)); s.Logger.LogSectionParameter(s, s.CurDepth, paramDict, cmd); int depthBackup = s.CurDepth; s.LoopState = LoopState.OnDriveLetter; Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, true); if (s.LoopState == LoopState.Off) // Loop,Break { break; } s.LoopState = LoopState.Off; s.CurDepth = depthBackup; s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"End of Loop with [{s.LoopLetter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth)); loopIdx += 1; } break; default: throw new InternalException("Internal Logic Error at CommandBranch.Loop"); } // Reset LoopCounter, to be sure s.LoopLetter = ' '; s.LoopCounter = 0; } }
public static UICommand ParseUICommand(List <string> rawLines, SectionAddress addr, ref int idx) { UIType type = UIType.None; string rawLine = rawLines[idx].Trim(); // Check if rawCode is Empty if (rawLine.Equals(string.Empty)) { return(new UICommand(rawLine, addr, string.Empty)); } // Comment Format : starts with '//' or '#', ';' if (rawLine.StartsWith("//") || rawLine.StartsWith("#") || rawLine.StartsWith(";")) { return(new UICommand(rawLine, addr, string.Empty)); } // Find key of interface control string key = string.Empty; string rawValue = string.Empty; int equalIdx = rawLine.IndexOf('='); if (equalIdx != -1) { key = rawLine.Substring(0, equalIdx); rawValue = rawLine.Substring(equalIdx + 1); } else { throw new InvalidCommandException($"Interface control [{rawValue}] does not have name", rawLine); } // Parse Arguments List <string> args = new List <string>(); try { string remainder = rawValue; while (remainder != null) { Tuple <string, string> tuple = CodeParser.GetNextArgument(remainder); args.Add(tuple.Item1); remainder = tuple.Item2; } } catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); } // Check doublequote's occurence - must be 2n if (StringHelper.CountOccurrences(rawValue, "\"") % 2 == 1) { throw new InvalidCommandException($"Interface control [{rawValue}]'s doublequotes mismatch", rawLine); } // Check if last operand is \ - MultiLine check - only if one or more operands exists if (0 < args.Count) { while (args.Last().Equals(@"\", StringComparison.OrdinalIgnoreCase)) { // Split next line and append to List<string> operands if (rawLines.Count <= idx) // Section ended with \, invalid grammar! { throw new InvalidCommandException($@"Last interface control [{rawValue}] cannot end with '\' ", rawLine); } idx++; args.AddRange(rawLines[idx].Trim().Split(',')); } } // UICommand should have at least 7 operands // Text, Visibility, Type, X, Y, width, height, [Optional] if (args.Count < 7) { throw new InvalidCommandException($"Interface control [{rawValue}] must have at least 7 arguments", rawLine); } // Parse opcode try { type = UIParser.ParseControlType(args[2]); } catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); } // Remove UIControlType from operands // Leftover : Text, Visibility, X, Y, width, height, [Optional] args.RemoveAt(2); // Forge UICommand string text = StringEscaper.Unescape(args[0]); bool visibility = string.Equals(args[1], "1", StringComparison.Ordinal); NumberHelper.ParseInt32(args[2], out int x); NumberHelper.ParseInt32(args[3], out int y); NumberHelper.ParseInt32(args[4], out int width); NumberHelper.ParseInt32(args[5], out int height); Rect rect = new Rect(x, y, width, height); UIInfo info; try { info = ParseUICommandInfo(type, args); } catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); } return(new UICommand(rawLine, addr, key, text, visibility, type, rect, info)); }
private void SyntaxCheckButton_Click(object sender, RoutedEventArgs e) { if (m.Syntax_InputCode.Equals(string.Empty, StringComparison.Ordinal)) { m.Syntax_Output = "No Code"; return; } Project project = m.CodeBox_CurrentProject; Script p = project.MainScript; ScriptSection section; if (project.MainScript.Sections.ContainsKey("Process")) { section = p.Sections["Process"]; } else { section = new ScriptSection(p, "Process", SectionType.Code, new List <string>(), 1); } SectionAddress addr = new SectionAddress(p, section); List <string> lines = m.Syntax_InputCode.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList(); List <CodeCommand> cmds = CodeParser.ParseStatements(lines, addr, out List <LogInfo> errorLogs); // Check Macros Macro macro = new Macro(project, project.Variables, out List <LogInfo> macroLogs); if (macro.MacroEnabled) { foreach (CodeCommand cmd in cmds) { if (cmd.Type == CodeType.Macro) { Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Macro)); CodeInfo_Macro info = cmd.Info as CodeInfo_Macro; if (!macro.MacroDict.ContainsKey(info.MacroType)) { errorLogs.Add(new LogInfo(LogState.Error, $"Invalid CodeType or Macro [{info.MacroType}]", cmd)); } } } } if (0 < errorLogs.Count) { StringBuilder b = new StringBuilder(); for (int i = 0; i < errorLogs.Count; i++) { LogInfo log = errorLogs[i]; b.AppendLine($"[{i + 1}/{errorLogs.Count}] {log.Message} ({log.Command})"); } m.Syntax_Output = b.ToString(); } else { m.Syntax_Output = "No Error"; } }
/// <summary> /// Render RadioGroup control. /// Return true if failed. /// </summary> /// <param name="r.Canvas">Parent r.Canvas</param> /// <param name="uiCmd">UICommand</param> /// <returns>Success = false, Failure = true</returns> public static void RenderRadioGroup(RenderInfo r, UICommand uiCmd) { Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_RadioGroup)); UIInfo_RadioGroup info = uiCmd.Info as UIInfo_RadioGroup; double fontSize = CalcFontPointScale(); GroupBox box = new GroupBox() { Header = uiCmd.Text, FontSize = fontSize, BorderBrush = Brushes.LightGray, }; SetToolTip(box, info.ToolTip); Grid grid = new Grid(); box.Content = grid; for (int i = 0; i < info.Items.Count; i++) { RadioButton radio = new RadioButton() { GroupName = r.Plugin.FullPath + uiCmd.Key, Content = info.Items[i], Tag = i, FontSize = fontSize, VerticalContentAlignment = VerticalAlignment.Center, }; radio.IsChecked = (i == info.Selected); radio.Checked += (object sender, RoutedEventArgs e) => { RadioButton btn = sender as RadioButton; info.Selected = (int)btn.Tag; uiCmd.Update(); }; if (info.SectionName != null) { radio.Click += (object sender, RoutedEventArgs e) => { if (r.Plugin.Sections.ContainsKey(info.SectionName)) // Only if section exists { SectionAddress addr = new SectionAddress(r.Plugin, r.Plugin.Sections[info.SectionName]); UIRenderer.RunOneSection(addr, $"{r.Plugin.Title} - RadioGroup [{uiCmd.Key}]", info.HideProgress); } else { Application.Current.Dispatcher.Invoke(() => { MainWindow w = Application.Current.MainWindow as MainWindow; w.Logger.System_Write(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exists")); }); } }; } SetToolTip(radio, info.ToolTip); Grid.SetRow(radio, i); grid.RowDefinitions.Add(new RowDefinition()); grid.Children.Add(radio); } Rect rect = new Rect(uiCmd.Rect.Left, uiCmd.Rect.Top, uiCmd.Rect.Width, uiCmd.Rect.Height); DrawToCanvas(r, box, rect); }
private static async void RunOneSection(SectionAddress addr, string logMsg, bool hideProgress) { if (Engine.WorkingLock == 0) { Interlocked.Increment(ref Engine.WorkingLock); Logger logger = null; SettingViewModel setting = null; MainViewModel mainModel = null; Application.Current.Dispatcher.Invoke(() => { MainWindow w = Application.Current.MainWindow as MainWindow; logger = w.Logger; mainModel = w.Model; setting = w.Setting; // Populate BuildTree if (!hideProgress) { w.Model.BuildTree.Children.Clear(); w.PopulateOneTreeView(addr.Plugin, w.Model.BuildTree, w.Model.BuildTree); w.CurBuildTree = null; } }); mainModel.WorkInProgress = true; EngineState s = new EngineState(addr.Plugin.Project, logger, mainModel, addr.Plugin, addr.Section.SectionName); s.SetOption(setting); s.DisableLogger = setting.Log_DisableInInterface; Engine.WorkingEngine = new Engine(s); // Build Start, Switch to Build View if (!hideProgress) { mainModel.SwitchNormalBuildInterface = false; } // Run long buildId = await Engine.WorkingEngine.Run(logMsg); // Build Ended, Switch to Normal View if (!hideProgress) { mainModel.SwitchNormalBuildInterface = true; } // Turn off ProgressRing mainModel.WorkInProgress = false; Engine.WorkingEngine = null; Interlocked.Decrement(ref Engine.WorkingLock); if (!hideProgress) { Application.Current.Dispatcher.Invoke(() => { MainWindow w = Application.Current.MainWindow as MainWindow; w.DrawPlugin(w.CurMainTree.Plugin); }); } } }
public Task <long> Run(string runName) { task = Task.Run(() => { s.BuildId = s.Logger.Build_Init(s, runName); s.MainViewModel.BuildFullProgressBarMax = s.Plugins.Count; // Update project variables s.Project.UpdateProjectVariables(); while (true) { ReadyRunPlugin(s); // Run Main Section if (s.CurrentPlugin.Sections.ContainsKey(s.EntrySection)) { PluginSection mainSection = s.CurrentPlugin.Sections[s.EntrySection]; SectionAddress addr = new SectionAddress(s.CurrentPlugin, mainSection); s.Logger.LogStartOfSection(s, addr, 0, true, null, null); Engine.RunSection(s, new SectionAddress(s.CurrentPlugin, mainSection), new List <string>(), 1, false); s.Logger.LogEndOfSection(s, addr, 0, true, null); } // End of Plugin FinishRunPlugin(s); // OnPluginExit event callback Engine.CheckAndRunCallback(s, ref s.OnPluginExit, FinishEventParam(s), "OnPluginExit"); if (s.Plugins.Count - 1 <= s.CurrentPluginIdx || s.RunOnePlugin || s.ErrorHaltFlag || s.UserHaltFlag || s.CmdHaltFlag) { // End of Build bool alertErrorHalt = s.ErrorHaltFlag; bool alertUserHalt = s.UserHaltFlag; bool alertCmdHalt = s.CmdHaltFlag; if (s.UserHaltFlag) { s.MainViewModel.PluginDescriptionText = "Build stop requested by user"; s.Logger.Build_Write(s, Logger.LogSeperator); s.Logger.Build_Write(s, new LogInfo(LogState.Info, "Build stop requested by user")); } string eventParam = FinishEventParam(s); // Reset Halt Flags before running OnBuildExit s.ErrorHaltFlag = false; s.UserHaltFlag = false; s.CmdHaltFlag = false; // OnBuildExit event callback Engine.CheckAndRunCallback(s, ref s.OnBuildExit, eventParam, "OnBuildExit", true); if (alertUserHalt) { MessageBox.Show("Build Stopped by User", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information); } else if (alertCmdHalt) { MessageBox.Show("Build Stopped by Halt Command", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information); } else if (alertErrorHalt) { MessageBox.Show("Build Stopped by Error", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information); } break; } // Run Next Plugin s.CurrentPluginIdx += 1; s.CurrentPlugin = s.Plugins[s.CurrentPluginIdx]; s.PassCurrentPluginFlag = false; } s.Logger.Build_Finish(s); return(s.BuildId); }); return(task); }