示例#1
0
        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);
        }
示例#2
0
        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());
        }
示例#3
0
        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"));
                    }
                }
            }
        }
示例#4
0
        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());
            }
        }
示例#5
0
        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);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
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;
        }
示例#10
0
        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();
        }
示例#11
0
        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));
        }
示例#12
0
        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));
        }
示例#13
0
        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>());
            }
        }
示例#14
0
        /// <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);
        }
示例#15
0
        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);
        }
示例#16
0
        /// <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);
        }
示例#17
0
        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());
        }
示例#18
0
        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;
        }
示例#19
0
        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());
            }
        }
示例#20
0
        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;
        }
示例#21
0
        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;
            }
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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;
            }
        }
示例#26
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));
        }
示例#27
0
        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";
            }
        }
示例#28
0
        /// <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);
        }
示例#29
0
        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);
                    });
                }
            }
        }
示例#30
0
        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);
        }