Beispiel #1
0
        private List <LogInfo> CheckCodeSection(ScriptSection section, string rawLine = null, int lineIdx = 0)
        {
            // If this section was already visited, return.
            if (_visitedSections.Contains(section.Name))
            {
                return(new List <LogInfo>());
            }
            _visitedSections.Add(section.Name);

            if (section.Lines == null)
            {
                string msg = $"Unable to load section [{section.Name}]";
                if (rawLine != null)
                {
                    msg += $" ({rawLine})";
                }
                if (0 < lineIdx)
                {
                    msg += $" (Line {lineIdx})";
                }

                return(new List <LogInfo> {
                    new LogInfo(LogState.Error, msg)
                });
            }

            CodeParser parser = new CodeParser(section, Global.Setting, section.Project.Compat);

            (CodeCommand[] cmds, List <LogInfo> logs) = parser.ParseStatements();
            RecursiveFindCodeSection(cmds, logs);

            return(logs);
        }
Beispiel #2
0
        public static UIControl ParseStatement(string line, ScriptSection section, out List <LogInfo> errorLogs)
        {
            int idx = 0;

            errorLogs = new List <LogInfo>();
            try
            {
                UIControl uiCtrl = ParseUIControl(new List <string> {
                    line
                }, section, ref idx);
                if (uiCtrl == null)
                {
                    return(null);
                }

                // Check uiCtrl.Type
                if (uiCtrl.Type == UIControlType.None)
                {
                    errorLogs.Add(new LogInfo(LogState.Error, $"Invalid interface control type ({uiCtrl.RawLine})"));
                    return(null);
                }

                return(uiCtrl);
            }
            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(null);
        }
Beispiel #3
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);
        }
Beispiel #4
0
        private List <LogInfo> ValidateCodeSection(ScriptSection section, string rawLine = null, int lineIdx = 0)
        {
            if (section.Lines == null)
            {
                string msg = $"Unable to load section [{section.Name}]";
                if (rawLine != null)
                {
                    msg += $" ({rawLine})";
                }
                if (0 < lineIdx)
                {
                    msg += $" (Line {lineIdx})";
                }

                return(new List <LogInfo> {
                    new LogInfo(LogState.Error, msg)
                });
            }

            CodeParser parser = new CodeParser(section, Global.Setting, section.Project.Compat);

            (CodeCommand[] cmds, List <LogInfo> logs) = parser.ParseStatements();
            InternalValidateCodes(cmds, logs);

            return(logs);
        }
Beispiel #5
0
 public static void DisableSetLocal(EngineState s, ScriptSection section)
 {
     if (s.SetLocalSection != null && s.SetLocalSection.Equals(section) &&
         s.LocalVarsBackup != null)
     {
         s.Variables.SetVarDict(VarsType.Local, s.LocalVarsBackup);
         s.LocalVarsBackup = null;
         s.SetLocalSection = null;
     }
 }
Beispiel #6
0
        public bool ReplaceScript(Script sc)
        {
            if (!sc.Sections.ContainsKey(Section.Name))
            {
                return(false);
            }

            Section = sc.Sections[Section.Name];
            return(true);
        }
Beispiel #7
0
        public List <LogInfo> LoadLocalMacroDict(Script sc, bool append, string sectionName = ScriptSection.Names.Variables)
        {
            if (sc.Sections.ContainsKey(sectionName))
            {
                ScriptSection section = sc.Sections[sectionName];

                // [Variables]'s type is SectionDataType.Lines
                // Pick key-value only if key is not wrapped by %
                Dictionary <string, string> dict = IniReadWriter.ParseIniLinesIniStyle(section.Lines);
                return(LoadLocalMacroDict(section, dict, append));
            }

            return(new List <LogInfo>());
        }
Beispiel #8
0
        public List <LogInfo> LoadMacroDict(MacroType type, Script sc, bool append, string sectionName = ScriptSection.Names.Variables)
        {
            if (!sc.Sections.ContainsKey(sectionName))
            {
                return(new List <LogInfo>());
            }

            ScriptSection section = sc.Sections[sectionName];

            // Pick key-value only if key is not wrapped by %
            Dictionary <string, string> dict = IniReadWriter.ParseIniLinesIniStyle(section.Lines);

            return(LoadMacroDict(type, section, dict, append));
        }
Beispiel #9
0
        public UIControl(string rawLine, ScriptSection section, string key)
        {
            RawLine = rawLine;
            Section = section;

            Key        = key;
            Text       = string.Empty;
            Visibility = false;
            Type       = UIControlType.None;
            X          = 0;
            Y          = 0;
            Width      = 0;
            Height     = 0;
            Info       = null;
            LineIdx    = 0;
        }
Beispiel #10
0
        public UIControl(string rawLine, ScriptSection section, string key, string text, bool visibility, UIControlType type, int x, int y, int width, int height, UIInfo info, int lineIdx)
        {
            RawLine = rawLine;
            Section = section;

            Key        = key;
            Text       = text;
            Visibility = visibility;
            Type       = type;
            X          = x;
            Y          = y;
            Width      = width;
            Height     = height;
            Info       = info;
            LineIdx    = lineIdx;
        }
Beispiel #11
0
        public List <LogInfo> LoadLocalMacroDict(Script p, bool append, string sectionName = "Variables")
        {
            if (p.Sections.ContainsKey(sectionName))
            {
                ScriptSection 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>());
            }
        }
Beispiel #12
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);
        }
Beispiel #13
0
        private List <LogInfo> LoadLocalMacroDict(ScriptSection section, Dictionary <string, string> dict, bool append)
        {
            List <LogInfo> logs = new List <LogInfo>();

            if (!append)
            {
                LocalDict.Clear();
            }

            if (0 < dict.Keys.Count)
            {
                int count = 0;
                logs.Add(new LogInfo(LogState.Info, $"Import Local Macro from [{section.Name}]", 0));
                foreach (var kv in dict)
                {
                    try
                    {
                        // Macro Name Validation
                        if (!Regex.Match(kv.Key, MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success)
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Invalid local macro name [{kv.Key}]"));
                            continue;
                        }

                        CodeParser parser = new CodeParser(section, Global.Setting, section.Project.Compat);
                        LocalDict[kv.Key] = parser.ParseStatement(kv.Value);
                        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.LogSeparator, 0));
            }

            return(logs);
        }
Beispiel #14
0
        private List <LogInfo> LoadMacroDict(MacroType type, ScriptSection section, Dictionary <string, string> newDict, bool append)
        {
            List <LogInfo> logs = new List <LogInfo>();

            // Select proper macroDict
            Dictionary <string, CodeCommand> macroDict;

            switch (type)
            {
            case MacroType.Global:
                macroDict = GlobalDict;
                break;

            case MacroType.Local:
                macroDict = LocalDict;
                break;

            default:
                throw new CriticalErrorException($"Invalid MacroType {type}");
            }

            // Do not clear macroDict in the append mode
            if (!append)
            {
                macroDict.Clear();
            }

            // If the newDict is empty, skip the rest
            if (newDict.Keys.Count == 0)
            {
                return(logs);
            }

            // Parse and register commands to the macroDict
            int        count  = 0;
            CodeParser parser = new CodeParser(section, Global.Setting, section.Project.Compat);

            logs.Add(new LogInfo(LogState.Info, $"Import {type} Macro from [{section.Name}]", 0));
            foreach (var kv in newDict)
            {
                try
                {
                    // Macro Name Validation
                    if (!Regex.Match(kv.Key, MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success)
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Invalid macro name [{kv.Key}]"));
                        continue;
                    }

                    CodeCommand macroCmd = parser.ParseStatement(kv.Value);
                    macroDict[kv.Key] = macroCmd;
                    logs.Add(new LogInfo(LogState.Success, $"{type} 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} {type} Macro", 0));
            logs.Add(new LogInfo(LogState.None, Logger.LogSeparator, 0));

            return(logs);
        }
Beispiel #15
0
        public static (List <UIControl> uiCtrl, List <LogInfo> errLogs) ParseStatements(IList <string> lines, ScriptSection section)
        {
            // Select Code sections and compile
            List <LogInfo>   errLogs = new List <LogInfo>();
            List <UIControl> uiCtrls = new List <UIControl>();

            for (int i = 0; i < lines.Count; i++)
            {
                int lineIdx = section.LineIdx + 1 + i;

                try
                {
                    UIControl uiCtrl = ParseUIControl(lines, section, ref i);
                    if (uiCtrl == null)
                    {
                        continue;
                    }

                    // Check uiCtrl.Type
                    if (uiCtrl.Type == UIControlType.None)
                    {
                        errLogs.Add(new LogInfo(LogState.Error, $"Invalid interface control type ({uiCtrl.RawLine}) (Line {lineIdx})"));
                        continue;
                    }

                    // Check if interface control's key is duplicated
                    if (uiCtrls.Select(x => x.Key).Contains(uiCtrl.Key, StringComparer.OrdinalIgnoreCase))
                    {
                        errLogs.Add(new LogInfo(LogState.Error, $"Interface key [{uiCtrl.Key}] is duplicated ({uiCtrl.RawLine}) (Line {lineIdx})"));
                    }
                    else
                    {
                        uiCtrls.Add(uiCtrl);
                    }
                }
                catch (InvalidCommandException e)
                {
                    errLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} ({e.RawLine}) (Line {lineIdx})"));
                }
                catch (Exception e)
                {
                    errLogs.Add(new LogInfo(LogState.Error, $"{Logger.LogExceptionMessage(e)} (Line {section.LineIdx + 1 + i})"));
                }
            }

            return(uiCtrls, errLogs);
        }
Beispiel #16
0
        public Macro(Project project, Variables variables, out List <LogInfo> logs)
        {
            macroEnabled = true;
            logs         = new List <LogInfo>();
            if (project.MainScript.Sections.ContainsKey("Variables") == false)
            {
                macroEnabled = false;
                logs.Add(new LogInfo(LogState.Info, "Macro not defined"));
                return;
            }

            Dictionary <string, string> varDict = Ini.ParseIniLinesVarStyle(project.MainScript.Sections["Variables"].GetLines());

            if ((varDict.ContainsKey("API") && varDict.ContainsKey("APIVAR")) == false)
            {
                macroEnabled = false;
                logs.Add(new LogInfo(LogState.Info, "Macro not defined"));
                return;
            }

            // Get macroScript
            string rawScriptPath   = varDict["API"];
            string macroScriptPath = variables.Expand(varDict["API"]); // Need Expansion

            macroScript = project.AllScripts.Find(x => x.FullPath.Equals(macroScriptPath, StringComparison.OrdinalIgnoreCase));
            if (macroScript == null)
            {
                macroEnabled = false;
                logs.Add(new LogInfo(LogState.Error, $"Macro defined but unable to find macro script [{rawScriptPath}"));
                return;
            }

            // Get macroScript
            if (macroScript.Sections.ContainsKey(varDict["APIVAR"]) == false)
            {
                macroEnabled = false;
                logs.Add(new LogInfo(LogState.Error, $"Macro defined but unable to find macro section [{varDict["APIVAR"]}"));
                return;
            }
            macroSection = macroScript.Sections[varDict["APIVAR"]];
            variables.SetValue(VarsType.Global, "API", macroScriptPath);
            if (macroScript.Sections.ContainsKey("Variables"))
            {
                variables.AddVariables(VarsType.Global, macroScript.Sections["Variables"]);
            }

            // Import Section [APIVAR]'s variables, such as '%Shc_Mode%=0'
            variables.AddVariables(VarsType.Global, macroSection);

            // Parse Section [APIVAR] into MacroDict
            {
                SectionAddress addr = new SectionAddress(macroScript, macroSection);
                Dictionary <string, string> rawDict = Ini.ParseIniLinesIniStyle(macroSection.GetLines());
                foreach (var kv in rawDict)
                {
                    try
                    {
                        if (Regex.Match(kv.Key, Macro.MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success) // Macro Name Validation
                        {
                            macroDict[kv.Key] = CodeParser.ParseStatement(kv.Value, addr);
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Invalid macro name [{kv.Key}]"));
                        }
                    }
                    catch (Exception e)
                    {
                        logs.Add(new LogInfo(LogState.Error, e));
                    }
                }
            }

            // Parse MainScript's section [Variables] into MacroDict
            // (Written by SetMacro, ... ,PERMANENT
            if (project.MainScript.Sections.ContainsKey("Variables"))
            {
                ScriptSection  permaSection         = project.MainScript.Sections["Variables"];
                SectionAddress addr                 = new SectionAddress(project.MainScript, permaSection);
                Dictionary <string, string> rawDict = Ini.ParseIniLinesIniStyle(permaSection.GetLines());
                foreach (var kv in rawDict)
                {
                    try
                    {
                        if (Regex.Match(kv.Key, Macro.MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success) // Macro Name Validation
                        {
                            macroDict[kv.Key] = CodeParser.ParseStatement(kv.Value, addr);
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Invalid macro name [{kv.Key}]"));
                        }
                    }
                    catch (Exception e)
                    {
                        logs.Add(new LogInfo(LogState.Error, e));
                    }
                }
            }
        }
Beispiel #17
0
        public static UIControl ParseUIControl(IList <string> rawLines, ScriptSection section, ref int idx)
        {
            // UICommand's line number in physical file
            int lineIdx = section.LineIdx + 1 + idx;

            // Get rawLine
            string rawLine = rawLines[idx].Trim();

            // Check if rawLine is empty
            if (rawLine.Length == 0)
            {
                return(null);
            }

            // Line Comment Identifier : '//', '#', ';'
            if (rawLine.StartsWith("//", StringComparison.Ordinal) || rawLine[0] == '#' || rawLine[0] == ';')
            {
                return(null);
            }

            // Find key of interface control
            string key;
            string rawValue = string.Empty;
            int    equalIdx = rawLine.IndexOf('=');

            if (equalIdx != -1 && equalIdx != 0)
            {
                key      = rawLine.Substring(0, equalIdx);
                rawValue = rawLine.Substring(equalIdx + 1);
            }
            else
            {
                throw new InvalidCommandException($"Interface control [{rawValue}] must have a key", rawLine);
            }

            // Parse Arguments
            List <string> args = new List <string>();

            try
            {
                string remainder = rawValue;
                while (remainder != null)
                {
                    string next;
                    (next, remainder) = CodeParser.GetNextArgument(remainder);
                    args.Add(next);
                }
            }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }

            // Check double-quote's occurence - must be 2n
            if (StringHelper.CountSubStr(rawValue, "\"") % 2 == 1)
            {
                throw new InvalidCommandException("Double-quote's number should be even", 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 cannot end with '\'", rawLine);
                    }
                    idx++;
                    args.AddRange(rawLines[idx].Trim().Split(','));
                }
            }

            // UIControl 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 UIControlType
            UIControlType type;

            try { type = UIParser.ParseControlTypeVal(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 UIControl
            string text          = args[0];
            string visibilityStr = args[1];
            bool   visibility;

            if (visibilityStr.Equals("1", StringComparison.Ordinal) ||
                visibilityStr.Equals("True", StringComparison.OrdinalIgnoreCase))
            {
                visibility = true;
            }
            else if (visibilityStr.Equals("0", StringComparison.Ordinal) ||
                     visibilityStr.Equals("False", StringComparison.OrdinalIgnoreCase))
            {
                visibility = false;
            }
            else
            {
                throw new InvalidCommandException($"Invalid value in [{visibilityStr}]", rawLine);
            }

            bool intParse = true;

            intParse &= NumberHelper.ParseInt32(args[2], out int x);
            intParse &= NumberHelper.ParseInt32(args[3], out int y);
            intParse &= NumberHelper.ParseInt32(args[4], out int width);
            intParse &= NumberHelper.ParseInt32(args[5], out int height);
            if (!intParse)
            {
                throw new InvalidCommandException($"Invalid integers in [{rawValue}]", rawLine);
            }

            UIInfo info;

            try { info = ParseUIControlInfo(type, args); }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }
            return(new UIControl(rawLine, section, key, text, visibility, type, x, y, width, height, info, lineIdx));
        }
Beispiel #18
0
        public Macro(Project project, Variables variables, out List <LogInfo> logs)
        {
            logs = new List <LogInfo>();

            MacroEnabled = true;
            if (!project.MainScript.Sections.ContainsKey(ScriptSection.Names.Variables))
            {
                MacroEnabled = false;
                logs.Add(new LogInfo(LogState.Info, "Macro not defined"));
                return;
            }

            ScriptSection mainScriptVarSection = project.MainScript.Sections[ScriptSection.Names.Variables];

            Dictionary <string, string> varDict = IniReadWriter.ParseIniLinesVarStyle(mainScriptVarSection.Lines);

            if (!(varDict.ContainsKey(KnownVar.API) && varDict.ContainsKey(KnownVar.APIVAR)))
            {
                MacroEnabled = false;
                logs.Add(new LogInfo(LogState.Info, "Macro not defined"));
                return;
            }

            // Get macroScript
            string rawScriptPath   = varDict[KnownVar.API];
            string macroScriptPath = variables.Expand(varDict[KnownVar.API]); // Need expansion

            MacroScript = project.AllScripts.Find(x => x.RealPath.Equals(macroScriptPath, StringComparison.OrdinalIgnoreCase));
            if (MacroScript == null)
            {
                MacroEnabled = false;
                logs.Add(new LogInfo(LogState.Error, $"Macro defined but unable to find macro script [{rawScriptPath}"));
                return;
            }

            // Get macroScript
            if (!MacroScript.Sections.ContainsKey(varDict[KnownVar.APIVAR]))
            {
                MacroEnabled = false;
                logs.Add(new LogInfo(LogState.Error, $"Macro defined but unable to find macro section [{varDict[KnownVar.APIVAR]}"));
                return;
            }
            MacroSection = MacroScript.Sections[varDict[KnownVar.APIVAR]];
            variables.SetValue(VarsType.Global, KnownVar.API, macroScriptPath);
            if (MacroScript.Sections.ContainsKey(ScriptSection.Names.Variables))
            {
                logs.AddRange(variables.AddVariables(VarsType.Global, MacroScript.Sections[ScriptSection.Names.Variables]));
            }

            // Import Section [APIVAR]'s variables, such as '%Shc_Mode%=0'
            logs.AddRange(variables.AddVariables(VarsType.Global, MacroSection));

            // Parse Section [APIVAR] into MacroDict
            {
                ScriptSection section = MacroSection;
                Dictionary <string, string> rawDict = IniReadWriter.ParseIniLinesIniStyle(MacroSection.Lines);
                foreach (var kv in rawDict)
                {
                    try
                    {
                        if (Regex.Match(kv.Key, MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success)
                        { // Macro Name Validation
                            CodeParser parser = new CodeParser(section, Global.Setting, section.Project.Compat);
                            GlobalDict[kv.Key] = parser.ParseStatement(kv.Value);
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Invalid macro name [{kv.Key}]"));
                        }
                    }
                    catch (Exception e)
                    {
                        logs.Add(new LogInfo(LogState.Error, e));
                    }
                }
            }

            // Parse MainScript's section [Variables] into MacroDict
            // (Written by SetMacro, ... ,PERMANENT
            if (project.MainScript.Sections.ContainsKey(ScriptSection.Names.Variables))
            {
                ScriptSection permaSection          = project.MainScript.Sections[ScriptSection.Names.Variables];
                Dictionary <string, string> rawDict = IniReadWriter.ParseIniLinesIniStyle(permaSection.Lines);
                foreach (var kv in rawDict)
                {
                    try
                    {
                        if (Regex.Match(kv.Key, MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success)
                        { // Macro Name Validation
                            CodeParser parser = new CodeParser(permaSection, Global.Setting, permaSection.Project.Compat);
                            GlobalDict[kv.Key] = parser.ParseStatement(kv.Value);
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Invalid macro name [{kv.Key}]"));
                        }
                    }
                    catch (Exception e)
                    {
                        logs.Add(new LogInfo(LogState.Error, e));
                    }
                }
            }
        }
Beispiel #19
0
        public Task <long> Run(string runName)
        {
            task = Task.Run(() =>
            {
                s.BuildId = s.Logger.Build_Init(s, runName);

                s.MainViewModel.BuildFullProgressBarMax = s.Scripts.Count;

                // Update project variables
                s.Project.UpdateProjectVariables();

                while (true)
                {
                    ReadyRunScript(s);

                    // Run Main Section
                    string entrySection = Engine.GetEntrySection(s);
                    if (s.CurrentScript.Sections.ContainsKey(entrySection))
                    {
                        ScriptSection mainSection = s.CurrentScript.Sections[entrySection];
                        SectionAddress addr       = new SectionAddress(s.CurrentScript, mainSection);
                        s.Logger.LogStartOfSection(s, addr, 0, true, null, null);
                        Engine.RunSection(s, new SectionAddress(s.CurrentScript, mainSection), new List <string>(), 1, false);
                        s.Logger.LogEndOfSection(s, addr, 0, true, null);
                    }

                    // End of Script
                    FinishRunScript(s);

                    if (s.ErrorHaltFlag || s.UserHaltFlag || s.CmdHaltFlag)
                    {
                        s.MainViewModel.TaskbarProgressState = System.Windows.Shell.TaskbarItemProgressState.Error;
                    }

                    // OnScriptExit event callback
                    {
                        bool bakPassCurrentScriptFlag = s.PassCurrentScriptFlag;
                        bool bakErrorHalt             = s.ErrorHaltFlag;
                        bool bakUserHalt = s.UserHaltFlag;
                        bool bakCmdHalt  = s.CmdHaltFlag;

                        string eventParam = FinishEventParam(s);

                        // Reset Halt Flags before running OnScriptExit
                        // Otherwise only first command is executed
                        s.PassCurrentScriptFlag = false;
                        s.ErrorHaltFlag         = false;
                        s.UserHaltFlag          = false;
                        s.CmdHaltFlag           = false;

                        Engine.CheckAndRunCallback(s, ref s.OnScriptExit, eventParam, "OnScriptExit");

                        s.PassCurrentScriptFlag = bakPassCurrentScriptFlag;
                        s.ErrorHaltFlag         = bakErrorHalt;
                        s.UserHaltFlag          = bakUserHalt;
                        s.CmdHaltFlag           = bakCmdHalt;
                    }

                    bool runOneScriptExit = false;
                    if (s.RunMode == EngineMode.RunMainAndOne && s.CurrentScriptIdx != 0)
                    {
                        runOneScriptExit = true;
                    }
                    else if (s.RunMode == EngineMode.RunOne)
                    {
                        runOneScriptExit = true;
                    }

                    if (s.Scripts.Count - 1 <= s.CurrentScriptIdx ||
                        runOneScriptExit || s.ErrorHaltFlag || s.UserHaltFlag || s.CmdHaltFlag)
                    { // End of Build
                        bool alertPassCurrentScriptFlag = s.PassCurrentScriptFlag;
                        bool alertErrorHalt             = s.ErrorHaltFlag;
                        bool alertUserHalt = s.UserHaltFlag;
                        bool alertCmdHalt  = s.CmdHaltFlag;

                        if (s.UserHaltFlag)
                        {
                            s.MainViewModel.ScriptDescriptionText = "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
                        // Otherwise only first command is executed
                        s.PassCurrentScriptFlag = false;
                        s.ErrorHaltFlag         = false;
                        s.UserHaltFlag          = false;
                        s.CmdHaltFlag           = false;

                        // OnBuildExit event callback
                        if (s.RunMode == EngineMode.RunAll)
                        {
                            // OnBuildExit is not called on script interface control, or codebox
                            // (which uses EngineMode.RunMainAndOne or EngineMode.RunOne)
                            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 (alertErrorHalt)
                        {
                            MessageBox.Show("Build Stopped by Error", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        else if (alertCmdHalt)
                        {
                            MessageBox.Show("Build Stopped by Halt Command", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        else if (alertPassCurrentScriptFlag)
                        {
                            MessageBox.Show("Build Stopped by Exit Command", "Build Halt", MessageBoxButton.OK, MessageBoxImage.Information);
                        }

                        break;
                    }

                    // Run Next Script
                    s.CurrentScriptIdx     += 1;
                    s.CurrentScript         = s.Scripts[s.CurrentScriptIdx];
                    s.PassCurrentScriptFlag = false;
                }

                s.Logger.Build_Finish(s);

                return(s.BuildId);
            });

            return(task);
        }
Beispiel #20
0
        public List <LogInfo> LoadMacroDict(MacroType type, ScriptSection section, IEnumerable <string> lines, bool append)
        {
            Dictionary <string, string> dict = IniReadWriter.ParseIniLinesIniStyle(lines);

            return(LoadMacroDict(type, section, dict, append));
        }
Beispiel #21
0
        private List <LogInfo> ValidateInterfaceSection(ScriptSection section, string rawLine = null, int lineIdx = 0)
        {
            // Force parsing of code, bypassing caching by section.GetUICtrls()
            string[] lines = section.Lines;
            if (lines == null)
            {
                string msg = $"Section [{section.Name}] is not a valid interface section";
                if (rawLine != null)
                {
                    msg += $" ({rawLine})";
                }
                if (0 < lineIdx)
                {
                    msg += $" (Line {lineIdx})";
                }

                return(new List <LogInfo> {
                    new LogInfo(LogState.Error, msg)
                });
            }

            (List <UIControl> uiCtrls, List <LogInfo> logs) = UIParser.ParseStatements(lines, section);
            foreach (UIControl uiCtrl in uiCtrls)
            {
                switch (uiCtrl.Type)
                {
                case UIControlType.CheckBox:
                {
                    UIInfo_CheckBox info = uiCtrl.Info.Cast <UIInfo_CheckBox>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(ValidateCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.Image:
                    if (!uiCtrl.Text.Equals(UIInfo_Image.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, uiCtrl.Text))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Image resource [{uiCtrl.Text}] does not exist", uiCtrl));
                    }
                    break;

                case UIControlType.TextFile:
                    if (!uiCtrl.Text.Equals(UIInfo_TextFile.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, uiCtrl.Text))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Text resource [{uiCtrl.Text}] does not exist", uiCtrl));
                    }
                    break;

                case UIControlType.Button:
                {
                    UIInfo_Button info = uiCtrl.Info.Cast <UIInfo_Button>();

                    if (info.Picture != null &&
                        !info.Picture.Equals(UIInfo_Button.NoPicture, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, info.Picture))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Image resource [{info.Picture}] does not exist", uiCtrl));
                    }

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(ValidateCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioButton:
                {
                    UIInfo_RadioButton info = uiCtrl.Info.Cast <UIInfo_RadioButton>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(ValidateCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioGroup:
                {
                    UIInfo_RadioGroup info = uiCtrl.Info.Cast <UIInfo_RadioGroup>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(ValidateCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;
                }
            }
            return(logs);
        }
Beispiel #22
0
 public static void EnableSetLocal(EngineState s, ScriptSection section)
 {
     s.LocalVarsBackup = s.Variables.GetVarDict(VarsType.Local);
     s.SetLocalSection = section;
 }
Beispiel #23
0
        private List <LogInfo> CheckInterfaceSection(ScriptSection section, string rawLine = null, int lineIdx = 0)
        {
            // If this section was already visited, return.
            if (_visitedSections.Contains(section.Name))
            {
                return(new List <LogInfo>());
            }
            _visitedSections.Add(section.Name);

            // Force parsing of code, bypassing caching by section.GetUICtrls()
            string[] lines = section.Lines;
            if (lines == null)
            {
                string msg = $"Section [{section.Name}] is not a valid interface section";
                if (rawLine != null)
                {
                    msg += $" ({rawLine})";
                }
                if (0 < lineIdx)
                {
                    msg += $" (Line {lineIdx})";
                }

                return(new List <LogInfo> {
                    new LogInfo(LogState.Error, msg)
                });
            }

            (List <UIControl> uiCtrls, List <LogInfo> logs) = UIParser.ParseStatements(lines, section);
            foreach (UIControl uiCtrl in uiCtrls)
            {
                switch (uiCtrl.Type)
                {
                case UIControlType.CheckBox:
                {
                    UIInfo_CheckBox info = uiCtrl.Info.Cast <UIInfo_CheckBox>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.ComboBox:
                {
                    UIInfo_ComboBox info = uiCtrl.Info.Cast <UIInfo_ComboBox>();

                    // Practically, this means info.Index is -1 -> uiCtrl.Text not being one of info.Items
                    if (info.Index < 0 || info.Items.Count <= info.Index)
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Incorrect selected value [{uiCtrl.Text}]", uiCtrl));
                    }
                }
                break;

                case UIControlType.Image:
                {
                    // Check encoded image
                    string imageSection = StringEscaper.Unescape(uiCtrl.Text);
                    if (!imageSection.Equals(UIInfo_Image.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, imageSection))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Image resource [{imageSection}] does not exist", uiCtrl));
                    }

                    UIInfo_Image info = uiCtrl.Info.Cast <UIInfo_Image>();

                    // Check if image control have empty or invalid url.
                    // Ex) Colors_Image=ThemeColors.jpg,1,5,11,228,260,80,
                    if (info.Url != null)
                    {
                        string url = StringEscaper.Unescape(info.Url);
                        if (!StringEscaper.IsUrlValid(url))
                        {
                            if (url.IndexOf("://", StringComparison.Ordinal) != -1)
                            {
                                logs.Add(new LogInfo(LogState.Warning, $"Incorrect URL [{url}]", uiCtrl));
                            }
                            else
                            {
                                logs.Add(new LogInfo(LogState.Warning, "URL does not have a scheme. Did you omit \"http(s)://\"?", uiCtrl));
                            }
                        }
                    }
                }
                break;

                case UIControlType.TextFile:
                {
                    string textSection = StringEscaper.Unescape(uiCtrl.Text);
                    if (!textSection.Equals(UIInfo_TextFile.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, textSection))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Text resource [{textSection}] does not exist", uiCtrl));
                    }
                }
                break;

                case UIControlType.Button:
                {
                    UIInfo_Button info = uiCtrl.Info.Cast <UIInfo_Button>();

                    string pictureSection = info.Picture;
                    if (pictureSection != null &&
                        !pictureSection.Equals(UIInfo_Button.NoPicture, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, pictureSection))
                    {
                        if (pictureSection.Length == 0)         // Due to quirks of WinBuilder's editor, many buttons have '' instead of '0' in the place of <Picture>.
                        {
                            logs.Add(new LogInfo(LogState.Warning, "Image resource entry is empty. Use [0] to represent not having an image resource.", uiCtrl));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"Image resource [{pictureSection}] does not exist", uiCtrl));
                        }
                    }

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.WebLabel:
                {
                    UIInfo_WebLabel info = uiCtrl.Info.Cast <UIInfo_WebLabel>();

                    // Sometime developers forget to put proper scheme in WebLabel's url.
                    // Ex) PStart_WebLabel="PStart Homepage",1,10,668,122,98,18,www.pegtop.de/start/
                    string url = StringEscaper.Unescape(info.Url);
                    if (!StringEscaper.IsUrlValid(url))
                    {
                        if (url.IndexOf("://", StringComparison.Ordinal) != -1)
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"Incorrect URL [{url}]", uiCtrl));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Warning, "URL does not have scheme. Did you omit \"http(s)://\"?", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioButton:
                {
                    UIInfo_RadioButton info = uiCtrl.Info.Cast <UIInfo_RadioButton>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.FileBox:
                {
                    UIInfo_FileBox info = uiCtrl.Info.Cast <UIInfo_FileBox>();

                    if (info.IsFile)
                    {         // Select File
                        if (info.Filter != null)
                        {
                            string filter = StringEscaper.Unescape(info.Filter);
                            if (StringEscaper.IsFileFilterValid(filter) == false)
                            {
                                logs.Add(new LogInfo(LogState.Warning, $"File filter pattern [{filter}] is invalid", uiCtrl));
                            }
                        }
                    }
                    else
                    {         // Select Folder
                        if (info.Filter != null)
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"File filters cannot be used for folder selection", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioGroup:
                {
                    UIInfo_RadioGroup info = uiCtrl.Info.Cast <UIInfo_RadioGroup>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }

                    // Practically, this means info.Index is -1 -> uiCtrl.Text not being one of info.Items
                    if (info.Selected < 0 || info.Items.Count <= info.Selected)
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Incorrect selected index [{info.Selected}]", uiCtrl));
                    }
                }
                break;
                }
            }
            return(logs);
        }
Beispiel #24
0
        public LogInfo SetMacro(string macroName, string macroCommand, ScriptSection section, bool global, bool permanent)
        {
            // Macro Name Validation
            if (!Regex.Match(macroName, MacroNameRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant).Success)
            {
                return(new LogInfo(LogState.Error, $"Invalid macro name [{macroName}]"));
            }

            if (macroCommand != null)
            { // Insert
                // Try parsing
                CodeParser  parser = new CodeParser(section, Global.Setting, section.Project.Compat);
                CodeCommand cmd    = parser.ParseStatement(macroCommand);
                if (cmd.Type == CodeType.Error)
                {
                    CodeInfo_Error info = cmd.Info.Cast <CodeInfo_Error>();
                    return(new LogInfo(LogState.Error, info.ErrorMessage));
                }

                // Put into dictionary
                if (permanent) // MacroDict
                {
                    GlobalDict[macroName] = cmd;
                    if (IniReadWriter.WriteKey(section.Project.MainScript.RealPath, ScriptSection.Names.Variables, macroName, cmd.RawCode))
                    {
                        return(new LogInfo(LogState.Success, $"Permanent Macro [{macroName}] set to [{cmd.RawCode}]"));
                    }
                    else
                    {
                        return(new LogInfo(LogState.Error, $"Could not write macro into [{section.Project.MainScript.RealPath}]"));
                    }
                }

                if (global) // MacroDict
                {
                    GlobalDict[macroName] = cmd;
                    return(new LogInfo(LogState.Success, $"Global Macro [{macroName}] set to [{cmd.RawCode}]"));
                }

                LocalDict[macroName] = cmd;
                return(new LogInfo(LogState.Success, $"Local Macro [{macroName}] set to [{cmd.RawCode}]"));
            }
            else
            {
                // Delete
                // Put into dictionary
                if (permanent) // MacroDict
                {
                    if (GlobalDict.ContainsKey(macroName))
                    {
                        GlobalDict.Remove(macroName);
                        IniReadWriter.DeleteKey(section.Project.MainScript.RealPath, ScriptSection.Names.Variables, macroName);
                        return(new LogInfo(LogState.Success, $"Permanent Macro [{macroName}] deleted"));
                    }

                    return(new LogInfo(LogState.Error, $"Permanent Macro [{macroName}] not found"));
                }

                if (global) // MacroDict
                {
                    if (GlobalDict.ContainsKey(macroName))
                    {
                        GlobalDict.Remove(macroName);
                        return(new LogInfo(LogState.Success, $"Global Macro [{macroName}] deleted"));
                    }

                    return(new LogInfo(LogState.Error, $"Global Macro [{macroName}] not found"));
                }

                // LocalDict
                if (LocalDict.ContainsKey(macroName))
                {
                    LocalDict.Remove(macroName);
                    return(new LogInfo(LogState.Success, $"Local Macro [{macroName}] deleted"));
                }

                return(new LogInfo(LogState.Error, $"Local Macro [{macroName}] not found"));
            }
        }
Beispiel #25
0
        public EngineState(Project project, Logger logger, MainViewModel mainModel, EngineMode mode = EngineMode.RunAll, Script runSingle = null, string entrySection = "Process")
        {
            this.Project = project;
            this.Logger  = logger;

            Macro = new Macro(Project, Variables, out List <LogInfo> macroLogs);
            logger.Build_Write(BuildId, macroLogs);

            RunMode = mode;
            switch (RunMode)
            {
            case EngineMode.RunAll:
            {         // Run All
                Scripts = project.ActiveScripts;

                CurrentScript    = Scripts[0];      // MainScript
                CurrentScriptIdx = 0;

                RunOneEntrySection = null;
            }
            break;

            case EngineMode.RunMainAndOne:
            {         // Run one script, executing MainScript before it.
                if (runSingle.Equals(project.MainScript) && entrySection.Equals("Process", StringComparison.Ordinal))
                {
                    goto case EngineMode.RunOne;
                }

                Scripts = new List <Script>(2)
                {
                    project.MainScript, runSingle
                };

                CurrentScript    = Scripts[0];
                CurrentScriptIdx = 0;

                RunOneEntrySection = entrySection;
            }
            break;

            case EngineMode.RunOne:
            {         // Run only one script
                Scripts = new List <Script>(1)
                {
                    runSingle
                };

                CurrentScript    = runSingle;
                CurrentScriptIdx = Scripts.IndexOf(runSingle);

                RunOneEntrySection = entrySection;
            }
            break;
            }

            CurrentSection = null;

            CurSectionParams = new Dictionary <int, string>();

            MainViewModel = mainModel;
        }