Example #1
0
        public static List <LogInfo> ReadInterface(EngineState s, CodeCommand cmd)
        { // ReadInterface,<Element>,<PluginFile>,<Section>,<Key>,<DestVar>
            List <LogInfo> logs = new List <LogInfo>(1);

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_ReadInterface));
            CodeInfo_ReadInterface info = cmd.Info as CodeInfo_ReadInterface;

            string pluginFile = StringEscaper.Preprocess(s, info.PluginFile);
            string section    = StringEscaper.Preprocess(s, info.Section);
            string key        = StringEscaper.Preprocess(s, info.Key);

            Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin);

            if (!p.Sections.ContainsKey(section))
            {
                logs.Add(new LogInfo(LogState.Error, $"Plugin [{pluginFile}] does not have section [{section}]"));
                return(logs);
            }

            PluginSection    iface  = p.Sections[section];
            List <UICommand> uiCmds = iface.GetUICodes(true);
            UICommand        uiCmd  = uiCmds.Find(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase));

            if (uiCmd == null)
            {
                logs.Add(new LogInfo(LogState.Error, $"Interface [{key}] does not exist"));
                return(logs);
            }

            string destStr;

            switch (info.Element)
            {
            case InterfaceElement.Text:
                destStr = uiCmd.Text;
                break;

            case InterfaceElement.Visible:
                destStr = uiCmd.Visibility.ToString();
                break;

            case InterfaceElement.PosX:
                destStr = ((int)uiCmd.Rect.X).ToString();
                break;

            case InterfaceElement.PosY:
                destStr = ((int)uiCmd.Rect.Y).ToString();
                break;

            case InterfaceElement.Width:
                destStr = ((int)uiCmd.Rect.Width).ToString();
                break;

            case InterfaceElement.Height:
                destStr = ((int)uiCmd.Rect.Height).ToString();
                break;

            case InterfaceElement.Value:
                destStr = uiCmd.GetValue();
                if (destStr == null)
                {
                    logs.Add(new LogInfo(LogState.Error, $"Reading [Value] from [{uiCmd.Type}] is not supported"));
                    return(logs);
                }
                break;

            default:
                throw new InternalException($"Internal Logic Error at ReadInterface");
            }

            // Do not expand read values
            List <LogInfo> varLogs = Variables.SetVariable(s, info.DestVar, destStr, false, false, false);

            logs.AddRange(varLogs);

            return(logs);
        }
Example #2
0
        private void RecursiveFindCodeSection(IReadOnlyList <CodeCommand> codes, List <LogInfo> logs)
        {
            string targetCodeSection      = null;
            string targetInterfaceSection = null;

            foreach (CodeCommand cmd in codes)
            {
                switch (cmd.Type)
                {
                    #region Check CodeSections
                case CodeType.If:
                {
                    CodeInfo_If info = cmd.Info.Cast <CodeInfo_If>();

                    if (info.Condition.Type == BranchConditionType.ExistSection)
                    {
                        // For recursive section call
                        // Ex) If,ExistSection,%ScriptFile%,DoWork,Run,%ScriptFile%,DoWork
                        if (info.Condition.Arg1.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                            info.Embed.Type == CodeType.Run || info.Embed.Type == CodeType.RunEx || info.Embed.Type == CodeType.Exec)
                        {
                            CodeInfo_RunExec subInfo = info.Embed.Info.Cast <CodeInfo_RunExec>();
                            if (subInfo.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase))
                            {
                                if (info.Condition.Arg2.Equals(subInfo.SectionName, StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    RecursiveFindCodeSection(info.Link, logs);
                }
                break;

                case CodeType.Else:
                {
                    CodeInfo_Else info = cmd.Info.Cast <CodeInfo_Else>();

                    RecursiveFindCodeSection(info.Link, logs);
                }
                break;

                case CodeType.Run:
                case CodeType.Exec:
                case CodeType.RunEx:
                {
                    CodeInfo_RunExec info = cmd.Info.Cast <CodeInfo_RunExec>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                case CodeType.Loop:
                case CodeType.LoopLetter:
                case CodeType.LoopEx:
                case CodeType.LoopLetterEx:
                {
                    CodeInfo_Loop info = cmd.Info.Cast <CodeInfo_Loop>();

                    if (info.Break)
                    {
                        continue;
                    }

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                case CodeType.UserInput:
                {
                    CodeInfo_UserInput info = cmd.Info.Cast <CodeInfo_UserInput>();

                    UserInputType type = info.Type;
                    switch (type)
                    {
                    case UserInputType.DirPath:
                    case UserInputType.FilePath:
                    {
                        UserInputInfo_DirFile subInfo = info.SubInfo.Cast <UserInputInfo_DirFile>();

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

                    #endregion
                    #region Check InterfaceSections
                case CodeType.AddInterface:
                {
                    CodeInfo_AddInterface info = cmd.Info.Cast <CodeInfo_AddInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.ReadInterface:
                {
                    CodeInfo_ReadInterface info = cmd.Info.Cast <CodeInfo_ReadInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.WriteInterface:
                {
                    CodeInfo_WriteInterface info = cmd.Info.Cast <CodeInfo_WriteInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.IniWrite:
                {
                    // To detect multi-interface without `InterfaceList=`,
                    // Inspect pattern `IniWrite,%ScriptFile%,Main,Interface,<NewInterfaceSection>`
                    CodeInfo_IniWrite info = cmd.Info.Cast <CodeInfo_IniWrite>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.FileName.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        info.Section.Equals(ScriptSection.Names.Main, StringComparison.OrdinalIgnoreCase) &&
                        info.Key.Equals(ScriptSection.Names.Interface, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Value))
                    {
                        targetInterfaceSection = info.Value;
                    }
                }
                break;
                    #endregion
                }

                if (targetCodeSection != null)
                {
                    if (_sc.Sections.ContainsKey(targetCodeSection))
                    {
                        logs.AddRange(CheckCodeSection(_sc.Sections[targetCodeSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetCodeSection}] does not exist", cmd));
                    }
                }

                if (targetInterfaceSection != null)
                {
                    if (_sc.Sections.ContainsKey(targetInterfaceSection))
                    {
                        logs.AddRange(CheckInterfaceSection(_sc.Sections[targetInterfaceSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetInterfaceSection}] does not exist", cmd));
                    }
                }
            }
        }
Example #3
0
        private static List <CodeCommand> InternalOptimize(List <CodeCommand> cmds)
        {
            List <CodeCommand> optimized = new List <CodeCommand>(cmds.Count);

            Dictionary <CodeType, List <CodeCommand> > opDict = OptimizedCodeTypes.ToDictionary(x => x, x => new List <CodeCommand>(cmds.Count / 2));

            CodeType s = CodeType.None;

            foreach (CodeCommand cmd in cmds)
            {
                bool loopAgain;
                do
                {
                    loopAgain = false;
                    switch (s)
                    {
                        #region Default
                    case CodeType.None:
                        switch (cmd.Type)
                        {
                        case CodeType.TXTAddLine:
                        case CodeType.TXTReplace:
                        case CodeType.TXTDelLine:
                        case CodeType.IniRead:
                        case CodeType.IniWrite:
                        case CodeType.IniDelete:
                        case CodeType.IniReadSection:
                        case CodeType.IniAddSection:
                        case CodeType.IniDeleteSection:
                        case CodeType.IniWriteTextLine:
                        case CodeType.Visible:
                        case CodeType.ReadInterface:
                        case CodeType.WriteInterface:
                        case CodeType.WimExtract:
                            s = cmd.Type;
                            opDict[cmd.Type].Add(cmd);
                            break;

                        case CodeType.WimPathAdd:
                        case CodeType.WimPathDelete:
                        case CodeType.WimPathRename:
                            s = CodeType.WimPathAdd;         // Use WimPathAdd as representative
                            opDict[CodeType.WimPathAdd].Add(cmd);
                            break;

                        default:
                            optimized.Add(cmd);
                            break;
                        }
                        break;

                        #endregion
                        #region TXTAddLine
                    case CodeType.TXTAddLine:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_TXTAddLine), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.TXTAddLine:
                        {
                            CodeInfo_TXTAddLine firstInfo = opDict[s][0].Info.Cast <CodeInfo_TXTAddLine>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region TXTReplace
                    case CodeType.TXTReplace:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_TXTReplace));
                        switch (cmd.Type)
                        {
                        case CodeType.TXTReplace:
                        {
                            CodeInfo_TXTReplace firstInfo = opDict[s][0].Info.Cast <CodeInfo_TXTReplace>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region TXTDelLine
                    case CodeType.TXTDelLine:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_TXTDelLine), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.TXTDelLine:
                        {
                            CodeInfo_TXTDelLine firstInfo = opDict[s][0].Info.Cast <CodeInfo_TXTDelLine>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniRead
                    case CodeType.IniRead:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniRead), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniRead:
                        {
                            CodeInfo_IniRead firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniRead>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniWrite
                    case CodeType.IniWrite:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniWrite), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniWrite:
                        {
                            CodeInfo_IniWrite firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniWrite>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IinDelete
                    case CodeType.IniDelete:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniDelete), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniDelete:
                        {
                            CodeInfo_IniDelete firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniDelete>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniReadSection
                    case CodeType.IniReadSection:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniReadSection));
                        switch (cmd.Type)
                        {
                        case CodeType.IniReadSection:
                        {
                            CodeInfo_IniReadSection firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniReadSection>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniAddSection
                    case CodeType.IniAddSection:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniAddSection), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniAddSection:
                        {
                            CodeInfo_IniAddSection firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniAddSection>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniDeleteSection
                    case CodeType.IniDeleteSection:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniDeleteSection), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniDeleteSection:
                        {
                            CodeInfo_IniDeleteSection firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniDeleteSection>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region IniWriteTextLine
                    case CodeType.IniWriteTextLine:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_IniWriteTextLine), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.IniWriteTextLine:
                        {
                            CodeInfo_IniWriteTextLine firstInfo = opDict[s][0].Info.Cast <CodeInfo_IniWriteTextLine>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region Visible
                    case CodeType.Visible:
                        switch (cmd.Type)
                        {
                        case CodeType.Visible:
                            opDict[s].Add(cmd);
                            break;

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region ReadInterface
                    case CodeType.ReadInterface:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_ReadInterface), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.ReadInterface:
                        {
                            CodeInfo_ReadInterface firstInfo = opDict[s][0].Info.Cast <CodeInfo_ReadInterface>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region WriteInterface
                    case CodeType.WriteInterface:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_WriteInterface), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.WriteInterface:
                        {
                            CodeInfo_WriteInterface firstInfo = opDict[s][0].Info.Cast <CodeInfo_WriteInterface>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region WimExtract
                    case CodeType.WimExtract:
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_WimExtract), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.WimExtract:
                        {
                            CodeInfo_WimExtract firstInfo = opDict[s][0].Info.Cast <CodeInfo_WimExtract>();
                            if (firstInfo.OptimizeCompare(cmd.Info))
                            {
                                opDict[s].Add(cmd);
                            }
                            else
                            {
                                goto default;
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region WimPath Series
                    case CodeType.WimPathAdd:     // Use WimPathAdd as a representative of WimPath{Add, Delete, Rename}
                        Debug.Assert(opDict[s][0].Info.GetType() == typeof(CodeInfo_WimPathAdd) ||
                                     opDict[s][0].Info.GetType() == typeof(CodeInfo_WimPathDelete) ||
                                     opDict[s][0].Info.GetType() == typeof(CodeInfo_WimPathRename), "Invalid CodeInfo");
                        switch (cmd.Type)
                        {
                        case CodeType.WimPathAdd:
                        case CodeType.WimPathDelete:
                        case CodeType.WimPathRename:
                        {
                            CodeCommand firstCmd = opDict[s][0];
                            if (firstCmd.Type == CodeType.WimPathAdd)
                            {
                                CodeInfo_WimPathAdd firstInfo = opDict[s][0].Info.Cast <CodeInfo_WimPathAdd>();
                                if (firstInfo.OptimizeCompare(cmd.Info))
                                {
                                    opDict[s].Add(cmd);
                                }
                                else
                                {
                                    goto default;
                                }
                            }
                            else if (firstCmd.Type == CodeType.WimPathDelete)
                            {
                                CodeInfo_WimPathDelete firstInfo = opDict[s][0].Info.Cast <CodeInfo_WimPathDelete>();
                                if (firstInfo.OptimizeCompare(cmd.Info))
                                {
                                    opDict[s].Add(cmd);
                                }
                                else
                                {
                                    goto default;
                                }
                            }
                            else if (firstCmd.Type == CodeType.WimPathRename)
                            {
                                CodeInfo_WimPathRename firstInfo = opDict[s][0].Info.Cast <CodeInfo_WimPathRename>();
                                if (firstInfo.OptimizeCompare(cmd.Info))
                                {
                                    opDict[s].Add(cmd);
                                }
                                else
                                {
                                    goto default;
                                }
                            }
                            break;
                        }

                        case CodeType.Comment:         // Remove comments
                            break;

                        default:         // Optimize them
                            FinalizeSequence(s, opDict[s]);
                            s         = CodeType.None;
                            loopAgain = true;
                            break;
                        }
                        break;

                        #endregion
                        #region Error
                    default:
                        throw new InternalException("Internal Logic Error at CodeOptimizer.InternalOptimize()");
                        #endregion
                    }
                }while (loopAgain);
            }

            #region Finish
            foreach (var kv in opDict)
            {
                FinalizeSequence(kv.Key, kv.Value);
            }
            #endregion

            #region FinalizeSequence
            void FinalizeSequence(CodeType state, List <CodeCommand> cmdSeq)
            {
                CodeCommand opCmd;

                if (cmdSeq.Count == 1)
                {
                    opCmd = cmdSeq[0];
                }
                else if (1 < cmdSeq.Count)
                {
                    opCmd = PackCommand(state, new List <CodeCommand>(cmdSeq));
                }
                else // if (cmds.Count <= 0)
                {
                    return;
                }

                Debug.Assert(opCmd != null, "Internal Logic Error in CodeOptimizer.Optimize");
                optimized.Add(opCmd);

                cmdSeq.Clear();
            }

            #endregion

            return(optimized);
        }
Example #4
0
        private void InternalValidateCodes(CodeCommand[] codes, List <LogInfo> logs)
        {
            string targetCodeSection      = null;
            string targetInterfaceSection = null;

            foreach (CodeCommand cmd in codes)
            {
                switch (cmd.Type)
                {
                    #region Check CodeSections
                case CodeType.If:
                {
                    CodeInfo_If info = cmd.Info.Cast <CodeInfo_If>();

                    if (info.Condition.Type == BranchConditionType.ExistSection)
                    {
                        // For recursive section call
                        // Ex) If,ExistSection,%ScriptFile%,DoWork,Run,%ScriptFile%,DoWork
                        if (info.Condition.Arg1.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                            info.Embed.Type == CodeType.Run || info.Embed.Type == CodeType.Exec)
                        {
                            CodeInfo_RunExec subInfo = info.Embed.Info.Cast <CodeInfo_RunExec>();
                            if (subInfo.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase))
                            {
                                if (info.Condition.Arg2.Equals(subInfo.SectionName, StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    InternalValidateCodes(info.Link.ToArray(), logs);
                }
                break;

                case CodeType.Else:
                {
                    CodeInfo_Else info = cmd.Info.Cast <CodeInfo_Else>();

                    InternalValidateCodes(info.Link.ToArray(), logs);
                }
                break;

                case CodeType.Run:
                case CodeType.Exec:
                case CodeType.RunEx:
                {
                    CodeInfo_RunExec info = cmd.Info.Cast <CodeInfo_RunExec>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                case CodeType.Loop:
                case CodeType.LoopLetter:
                case CodeType.LoopEx:
                case CodeType.LoopLetterEx:
                {
                    CodeInfo_Loop info = cmd.Info.Cast <CodeInfo_Loop>();

                    if (info.Break)
                    {
                        continue;
                    }

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                    #endregion
                    #region Check InterfaceSections
                case CodeType.AddInterface:
                {
                    CodeInfo_AddInterface info = cmd.Info.Cast <CodeInfo_AddInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                        CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.ReadInterface:
                {
                    CodeInfo_ReadInterface info = cmd.Info.Cast <CodeInfo_ReadInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                        CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.WriteInterface:
                {
                    CodeInfo_WriteInterface info = cmd.Info.Cast <CodeInfo_WriteInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals("%ScriptFile%", StringComparison.OrdinalIgnoreCase) &&
                        CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;
                    #endregion
                }

                if (targetCodeSection != null && !_visitedSections.Contains(targetCodeSection))
                {
                    _visitedSections.Add(targetCodeSection);

                    if (_sc.Sections.ContainsKey(targetCodeSection))
                    {
                        logs.AddRange(ValidateCodeSection(_sc.Sections[targetCodeSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetCodeSection}] does not exist", cmd));
                    }
                }

                if (targetInterfaceSection != null && !_visitedSections.Contains(targetInterfaceSection))
                {
                    _visitedSections.Add(targetInterfaceSection);

                    if (_sc.Sections.ContainsKey(targetInterfaceSection))
                    {
                        logs.AddRange(ValidateInterfaceSection(_sc.Sections[targetInterfaceSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetInterfaceSection}] does not exist", cmd));
                    }
                }
            }
        }