Ejemplo n.º 1
0
        public override List <PlayHistoryVO> GetModels(PlayHistoryPara mp)
        {
            string where = GetConditionByPara(mp);

            CodeCommand command = new CodeCommand();

            string cmd = LOAD
                         .Replace("@WHERE", where)
                         .Replace("@ORDER", GetOrderByPara(mp));

            command.CommandText = cmd;

            var table = DbProxyFactory.Instance.Proxy.ExecuteTable(command);

            List <PlayHistoryVO> list = new List <PlayHistoryVO>();

            for (int i = 0; i < table.Rows.Count; i++)
            {
                list.Add(new PlayHistoryVO(table.Rows[i]));
            }

            return(list);
        }
Ejemplo n.º 2
0
        public static List <LogInfo> DirDelete(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

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

            string dirPath = StringEscaper.Preprocess(s, info.DirPath);

            // Path Security Check
            if (StringEscaper.PathSecurityCheck(dirPath, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            // Delete Directory
            FileHelper.DirectoryDeleteEx(dirPath);

            logs.Add(new LogInfo(LogState.Success, $"Deleted directory [{dirPath}]"));

            return(logs);
        }
Ejemplo n.º 3
0
        public static List <LogInfo> FileCreateBlank(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_FileCreateBlank info = cmd.Info.Cast <CodeInfo_FileCreateBlank>();

            string filePath = StringEscaper.Preprocess(s, info.FilePath);

            Encoding encoding = EncodingHelper.DefaultAnsi;

            if (info.Encoding != null)
            {
                encoding = info.Encoding;
            }

            if (File.Exists(filePath))
            {
                if (info.Preserve)
                {
                    logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{filePath}] will not be overwritten", cmd));
                    return(logs);
                }

                logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{filePath}] will be overwritten", cmd));
            }

            if (!StringEscaper.PathSecurityCheck(filePath, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            Directory.CreateDirectory(FileHelper.GetDirNameEx(filePath));
            EncodingHelper.WriteTextBom(filePath, encoding);
            logs.Add(new LogInfo(LogState.Success, $"Created blank text file [{filePath}]", cmd));

            return(logs);
        }
Ejemplo n.º 4
0
        public override bool Edit(SysAreaCityVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = EDIT;

            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Id", Value = ParameterHelper.ConvertValue(m.Id)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ParentId", Value = ParameterHelper.ConvertValue(m.ParentId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ZipCode", Value = ParameterHelper.ConvertValue(m.ZipCode)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateTime", Value = ParameterHelper.ConvertValue(m.CreateTime)
            });


            int result = DbProxyFactory.Instance.Proxy.ExecuteNonQuery(command);

            if (result >= 1)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 5
0
        public static List <LogInfo> DirSize(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_DirSize info = cmd.Info.Cast <CodeInfo_DirSize>();

            string dirPath = StringEscaper.Preprocess(s, info.DirPath);

            if (!Directory.Exists(dirPath))
            {
                return(LogInfo.LogErrorMessage(logs, $"Directory [{dirPath}] does not exist"));
            }

            string[] files   = FileHelper.GetFilesEx(dirPath, "*", SearchOption.AllDirectories);
            long     dirSize = files.Sum(f => new FileInfo(f).Length);

            logs.Add(new LogInfo(LogState.Success, $"Directory [{dirPath}] is [{dirSize}B]", cmd));

            List <LogInfo> varLogs = Variables.SetVariable(s, info.DestVar, dirSize.ToString());

            logs.AddRange(varLogs);

            return(logs);
        }
Ejemplo n.º 6
0
        public override bool Insert(UserCodeInfoVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = INSERT;
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@UserId", Value = ParameterHelper.ConvertValue(m.UserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@TypeId", Value = ParameterHelper.ConvertValue(m.TypeId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CodeContent", Value = ParameterHelper.ConvertValue(m.CodeContent)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateDate", Value = ParameterHelper.ConvertValue(m.CreateDate)
            });


            int result = DbProxyFactory.Instance.Proxy.ExecuteNonQuery(command);

            if (result >= 1)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
0
        public static List <LogInfo> Wait(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_Wait info = cmd.Info.Cast <CodeInfo_Wait>();

            if (!NumberHelper.ParseInt32(info.Second, out int second))
            {
                logs.Add(new LogInfo(LogState.Error, $"Argument [{info.Second}] is not a valid integer"));
                return(logs);
            }

            if (second < 0)
            {
                logs.Add(new LogInfo(LogState.Error, $"Argument [{info.Second}] should be larger than 0"));
                return(logs);
            }

            Task.Delay(TimeSpan.FromSeconds(second)).Wait();

            logs.Add(new LogInfo(LogState.Success, $"Slept [{info.Second}] seconds", cmd));

            return(logs);
        }
Ejemplo n.º 8
0
        public override int InsertIdentityId(SysAreaProvincesVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = INSERT + "; select @@Identity";

            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Id", Value = ParameterHelper.ConvertValue(m.Id)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateTime", Value = ParameterHelper.ConvertValue(m.CreateTime)
            });


            var result = DbProxyFactory.Instance.Proxy.ExecuteScalar(command);

            return(int.Parse(result.ToString()));
        }
Ejemplo n.º 9
0
        public override bool Insert(SysAreaDistrictsVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = INSERT;
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Id", Value = ParameterHelper.ConvertValue(m.Id)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CityId", Value = ParameterHelper.ConvertValue(m.CityId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ProvincesId", Value = ParameterHelper.ConvertValue(m.ProvincesId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateTime", Value = ParameterHelper.ConvertValue(m.CreateTime)
            });


            int result = DbProxyFactory.Instance.Proxy.ExecuteNonQuery(command);

            if (result >= 1)
            {
                return(true);
            }

            return(false);
        }
        public override int InsertIdentityId(UserFinanceHistoryVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = INSERT + "; select @@Identity";

            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@UserId", Value = ParameterHelper.ConvertValue(m.UserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@RechargeType", Value = ParameterHelper.ConvertValue(m.RechargeType)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Money", Value = ParameterHelper.ConvertValue(m.Money)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@MoneyType", Value = ParameterHelper.ConvertValue(m.MoneyType)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateDate", Value = ParameterHelper.ConvertValue(m.CreateDate)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateUserId", Value = ParameterHelper.ConvertValue(m.CreateUserId)
            });


            var result = DbProxyFactory.Instance.Proxy.ExecuteScalar(command);

            return(int.Parse(result.ToString()));
        }
Ejemplo n.º 11
0
        public static List <LogInfo> AddVariables(EngineState s, CodeCommand cmd)
        {
            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_AddVariables));
            CodeInfo_AddVariables info = cmd.Info as CodeInfo_AddVariables;

            string pluginFile  = StringEscaper.Preprocess(s, info.PluginFile);
            string sectionName = StringEscaper.Preprocess(s, info.SectionName);

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

            // Does section exists?
            if (!p.Sections.ContainsKey(sectionName))
            {
                throw new ExecuteException($"Plugin [{pluginFile}] does not have section [{sectionName}]");
            }

            // Directly read from file
            List <string> lines = Ini.ParseRawSection(p.FullPath, sectionName);

            // Add Variables
            Dictionary <string, string> varDict = Ini.ParseIniLinesVarStyle(lines);
            List <LogInfo> varLogs = s.Variables.AddVariables(info.Global ? VarsType.Global : VarsType.Local, varDict);

            // Add Macros
            SectionAddress addr      = new SectionAddress(p, p.Sections[sectionName]);
            List <LogInfo> macroLogs = s.Macro.LoadLocalMacroDict(addr, lines, true);

            varLogs.AddRange(macroLogs);

            if (varLogs.Count == 0) // No variables
            {
                varLogs.Add(new LogInfo(LogState.Info, $"Plugin [{pluginFile}]'s section [{sectionName}] does not have any variables"));
            }

            return(varLogs);
        }
Ejemplo n.º 12
0
        public override bool Edit(DomainSynchroHistoryVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = EDIT;

            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ServerId", Value = ParameterHelper.ConvertValue(m.ServerId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@MainDomain", Value = ParameterHelper.ConvertValue(m.MainDomain)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Domains", Value = ParameterHelper.ConvertValue(m.Domains)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@DomainPath", Value = ParameterHelper.ConvertValue(m.DomainPath)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@OperType", Value = ParameterHelper.ConvertValue(m.OperType)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@IsSynchro", Value = ParameterHelper.ConvertValue(m.IsSynchro)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@SynchroDate", Value = ParameterHelper.ConvertValue(m.SynchroDate)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ClientIp", Value = ParameterHelper.ConvertValue(m.ClientIp)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateDate", Value = ParameterHelper.ConvertValue(m.CreateDate)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateUserId", Value = ParameterHelper.ConvertValue(m.CreateUserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@UserId", Value = ParameterHelper.ConvertValue(m.UserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@IsDelete", Value = ParameterHelper.ConvertValue(m.IsDelete)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Id", Value = ParameterHelper.ConvertValue(m.Id)
            });


            int result = DbProxyFactory.Instance.Proxy.ExecuteNonQuery(command);

            if (result >= 1)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 13
0
        public static List <LogInfo> TXTAddLine(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

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

            string         fileName = StringEscaper.Preprocess(s, info.FileName);
            string         line     = StringEscaper.Preprocess(s, info.Line);
            string         modeStr  = StringEscaper.Preprocess(s, info.Mode);
            TXTAddLineMode mode;

            if (modeStr.Equals("Append", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Append;
            }
            else if (info.Mode.Equals("Prepend", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Prepend;
            }
            else
            {
                throw new ExecuteException($"Mode [{modeStr}] must be one of [Append, Prepend]");
            }

            if (StringEscaper.PathSecurityCheck(fileName, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            // Detect encoding of text
            // If text does not exists, create blank file
            Encoding encoding = Encoding.Default;

            if (File.Exists(fileName))
            {
                encoding = FileHelper.DetectTextEncoding(fileName);
            }

            if (mode == TXTAddLineMode.Prepend)
            {
                string tempPath = Path.GetTempFileName();
                using (StreamReader reader = new StreamReader(fileName, encoding))
                    using (StreamWriter writer = new StreamWriter(tempPath, false, encoding))
                    {
                        writer.WriteLine(line);
                        string lineFromSrc;
                        while ((lineFromSrc = reader.ReadLine()) != null)
                        {
                            writer.WriteLine(lineFromSrc);
                        }
                    }
                FileHelper.FileReplaceEx(tempPath, fileName);

                logs.Add(new LogInfo(LogState.Success, $"Prepened [{line}] to [{fileName}]", cmd));
            }
            else if (mode == TXTAddLineMode.Append)
            {
                bool newLineExist = true;
                if (File.Exists(fileName))
                {
                    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        long   bomLen   = FileHelper.TextBOMLength(fs);
                        byte[] lastChar = new byte[2];
                        if (2 + bomLen <= fs.Length)
                        {
                            fs.Position = fs.Length - 2;
                            fs.Read(lastChar, 0, 2);
                            if (lastChar[0] != '\r' || lastChar[1] != '\n')
                            {
                                newLineExist = false;
                            }
                        }
                    }
                }

                if (newLineExist)
                {
                    File.AppendAllText(fileName, line + "\r\n", encoding);
                }
                else
                {
                    File.AppendAllText(fileName, "\r\n" + line + "\r\n", encoding);
                }
                logs.Add(new LogInfo(LogState.Success, $"Appended [{line}] to [{fileName}]", cmd));
            }

            return(logs);
        }
Ejemplo n.º 14
0
        private static List <CodeCommand> InternalOptimize(List <CodeCommand> codes)
        {
            List <CodeCommand> optimized = new List <CodeCommand>();

            Dictionary <CodeType, List <CodeCommand> > opDict = new Dictionary <CodeType, List <CodeCommand> >();

            foreach (CodeType type in toOptimize)
            {
                opDict[type] = new List <CodeCommand>();
            }

            CodeType state = CodeType.None;

            for (int i = 0; i < codes.Count; i++)
            {
                CodeCommand cmd = codes[i];

                switch (state)
                {
                    #region Default
                case CodeType.None:
                    switch (cmd.Type)
                    {
                    case CodeType.TXTAddLine:
                        state = CodeType.TXTAddLine;
                        opDict[CodeType.TXTAddLine].Add(cmd);
                        break;

                    case CodeType.TXTReplace:
                        state = CodeType.TXTReplace;
                        opDict[CodeType.TXTReplace].Add(cmd);
                        break;

                    case CodeType.TXTDelLine:
                        state = CodeType.TXTDelLine;
                        opDict[CodeType.TXTDelLine].Add(cmd);
                        break;

                    case CodeType.INIWrite:
                        state = CodeType.INIWrite;
                        opDict[CodeType.INIWrite].Add(cmd);
                        break;

                    case CodeType.INIRead:
                        state = CodeType.INIRead;
                        opDict[CodeType.INIRead].Add(cmd);
                        break;

                    case CodeType.INIReadSection:
                        state = CodeType.INIReadSection;
                        opDict[CodeType.INIReadSection].Add(cmd);
                        break;

                    case CodeType.INIAddSection:
                        state = CodeType.INIAddSection;
                        opDict[CodeType.INIAddSection].Add(cmd);
                        break;

                    case CodeType.INIDeleteSection:
                        state = CodeType.INIDeleteSection;
                        opDict[CodeType.INIDeleteSection].Add(cmd);
                        break;

                    case CodeType.INIWriteTextLine:
                        state = CodeType.INIWriteTextLine;
                        opDict[CodeType.INIWriteTextLine].Add(cmd);
                        break;

                    case CodeType.Visible:
                        state = CodeType.Visible;
                        opDict[CodeType.Visible].Add(cmd);
                        break;

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

                    #endregion
                    #region TXTAddLine
                case CodeType.TXTAddLine:
                    Debug.Assert(opDict[state][0].Info.GetType() == typeof(CodeInfo_TXTAddLine));
                    switch (cmd.Type)
                    {
                    case CodeType.TXTAddLine:
                    {
                        Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_TXTAddLine));
                        CodeInfo_TXTAddLine firstInfo = (opDict[state][0].Info as CodeInfo_TXTAddLine);
                        if (cmd.Info is CodeInfo_TXTAddLine info &&
                            info.FileName.Equals(firstInfo.FileName, StringComparison.OrdinalIgnoreCase) &&
                            info.Mode.Equals(firstInfo.Mode, StringComparison.OrdinalIgnoreCase))
                        {
                            opDict[state].Add(cmd);
                        }
Ejemplo n.º 15
0
        public override int InsertIdentityId(DomainSynchroHistoryVO m)
        {
            CodeCommand command = new CodeCommand();

            command.CommandText = INSERT + "; select @@Identity";

            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ServerId", Value = ParameterHelper.ConvertValue(m.ServerId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Name", Value = ParameterHelper.ConvertValue(m.Name)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@MainDomain", Value = ParameterHelper.ConvertValue(m.MainDomain)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@Domains", Value = ParameterHelper.ConvertValue(m.Domains)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@DomainPath", Value = ParameterHelper.ConvertValue(m.DomainPath)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@OperType", Value = ParameterHelper.ConvertValue(m.OperType)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@IsSynchro", Value = ParameterHelper.ConvertValue(m.IsSynchro)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@SynchroDate", Value = ParameterHelper.ConvertValue(m.SynchroDate)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@ClientIp", Value = ParameterHelper.ConvertValue(m.ClientIp)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateDate", Value = ParameterHelper.ConvertValue(m.CreateDate)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@CreateUserId", Value = ParameterHelper.ConvertValue(m.CreateUserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@UserId", Value = ParameterHelper.ConvertValue(m.UserId)
            });
            command.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@IsDelete", Value = ParameterHelper.ConvertValue(m.IsDelete)
            });


            var result = DbProxyFactory.Instance.Proxy.ExecuteScalar(command);

            return(int.Parse(result.ToString()));
        }
Ejemplo n.º 16
0
        public static List <LogInfo> Eval(EngineState s, ScriptSection section, string rawCode, CodeType type, ErrorCheck check, out CodeCommand cmd)
        {
            CodeParser parser = new CodeParser(section, Global.Setting, Project.Compat);

            return(Eval(s, parser, rawCode, type, check, out cmd));
        }
Ejemplo n.º 17
0
        public static List <LogInfo> Eval(EngineState s, CodeParser parser, string rawCode, CodeType type, ErrorCheck check, CompatOption compat, out CodeCommand cmd)
        {
            // Create CodeCommand
            cmd = parser.ParseStatement(rawCode);
            if (cmd.Type == CodeType.Error)
            {
                CodeInfo_Error info = cmd.Info.Cast <CodeInfo_Error>();
                Console.WriteLine(info.ErrorMessage);

                Assert.AreEqual(ErrorCheck.ParserError, check);
                return(new List <LogInfo>());
            }
            Assert.AreEqual(type, cmd.Type);

            // Run CodeCommand
            s.SetCompat(compat);
            List <LogInfo> logs = Engine.ExecuteCommand(s, cmd);

            s.SetCompat(Project.Compat); // Reset to default

            // Assert
            CheckErrorLogs(logs, check);

            // Return logs
            return(logs);
        }
Ejemplo n.º 18
0
        public static List <LogInfo> CopyOrExpand(EngineState s, CodeCommand cmd)
        {
            List <LogInfo>        logs = new List <LogInfo>();
            CodeInfo_CopyOrExpand info = cmd.Info.Cast <CodeInfo_CopyOrExpand>();

            #region Event Handlers
            void ReportExpandProgress(object sender, ProgressEventArgs e)
            {
                s.MainViewModel.BuildCommandProgressValue = e.PercentDone;
                s.MainViewModel.BuildCommandProgressText  = $"Expanding... ({e.PercentDone}%)";
            }

            #endregion

            string srcFile  = StringEscaper.Preprocess(s, info.SrcFile);
            string destPath = StringEscaper.Preprocess(s, info.DestPath);
            Debug.Assert(srcFile != null, $"{nameof(srcFile)} != null");
            Debug.Assert(destPath != null, $"{nameof(destPath)} != null");

            // Path Security Check
            if (!StringEscaper.PathSecurityCheck(destPath, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            string srcFileName = Path.GetFileName(srcFile);
            string srcFileExt  = Path.GetExtension(srcFile);
            if (!Directory.Exists(destPath))
            {
                if (File.Exists(destPath))
                {
                    if (info.Preserve)
                    {
                        logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destPath}] already exists and will not be overwritten"));
                        return(logs);
                    }

                    logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destPath}] already exists and will be overwritten"));
                }
            }

            // Get destFullPath. It should be a file.
            string destDir;
            string destFullPath;
            if (Directory.Exists(destPath))
            {
                destDir      = destPath;
                destFullPath = Path.Combine(destPath, srcFileName);
            }
            else // Move to new name
            {
                destDir      = FileHelper.GetDirNameEx(destPath);
                destFullPath = destPath;
            }
            Directory.CreateDirectory(destDir);

            // Check wildcard
            // WinBuilder082 behavior
            // - Some files are matched with wildcard : Reports success, but no files are copied.
            // - No files are matched with wildcard   : Reports error.
            string wildcard = Path.GetFileName(srcFile);
            if (wildcard.IndexOfAny(new char[] { '*', '?' }) != -1)
            {
                logs.Add(new LogInfo(LogState.Warning, "CopyOrExpand does not support filename with wildcard"));
                return(logs);
            }

            // Copy or Expand srcFile.
            if (File.Exists(srcFile))
            { // SrcFile is uncompressed, just copy!
                File.Copy(srcFile, destFullPath, !info.Preserve);
                logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] copied to [{destPath}]"));
            }
            else
            { // Extract Cabinet from _ (Ex) EXPLORER.EX_ -> EXPLORER.EXE
              // Terminate if a file does not have equivalent cabinet file
                if (srcFileExt.Length == ".".Length)
                {
                    return(logs);
                }
                string srcCabExt = srcFileExt.Substring(0, srcFileExt.Length - 1) + "_";
                string srcCab    = srcFile.Substring(0, srcFile.Length - srcCabExt.Length) + srcCabExt;

                if (File.Exists(srcCab))
                {
                    // Turn on report progress only if file is larger than 1MB
                    FileInfo fi             = new FileInfo(srcCab);
                    bool     reportProgress = 1024 * 1024 <= fi.Length;

                    using (SevenZipExtractor extractor = new SevenZipExtractor(srcCab))
                    {
                        if (extractor.Format != InArchiveFormat.Cab)
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcCab}] is not a cabinet archive"));
                        }

                        string[] archiveFileNames = extractor.ArchiveFileNames.ToArray();
                        if (archiveFileNames.Length != 1)
                        {
                            return(LogInfo.LogErrorMessage(logs, $"Cabinet [{srcCab}] should contain only a single file"));
                        }

                        if (!archiveFileNames.Contains(srcFileName, StringComparer.OrdinalIgnoreCase))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"Failed to extract [{srcFileName}] from [{srcCab}]"));
                        }

                        if (reportProgress)
                        {
                            extractor.Extracting += ReportExpandProgress; // Use "Expanding" instead of "CopyOrExpanding"
                            s.MainViewModel.SetBuildCommandProgress("CopyOrExpand Progress");
                        }
                        try
                        {
                            using (FileStream fs = new FileStream(destFullPath, FileMode.Create))
                            {
                                extractor.ExtractFile(srcFileName, fs);
                            }
                            logs.Add(new LogInfo(LogState.Success, $"[{srcCab}] extracted to [{destFullPath}]"));
                        }
                        finally
                        {
                            extractor.Extracting -= ReportExpandProgress; // Use "Expanding" instead of "CopyOrExpanding"
                            s.MainViewModel.ResetBuildCommandProgress();
                        }
                    }
                }
                else
                { // Error
                    logs.Add(new LogInfo(LogState.Error, $"The file [{srcFile}] or [{Path.GetFileName(srcCab)}] could not be found"));
                }
            }

            return(logs);
        }
Ejemplo n.º 19
0
        public static List <LogInfo> Eval(EngineState s, string rawCode, CodeType type, ErrorCheck check, CompatOption compat, out CodeCommand cmd)
        {
            CodeParser parser = new CodeParser(DummySection(), Global.Setting, compat);

            return(Eval(s, parser, rawCode, type, check, compat, out cmd));
        }
Ejemplo n.º 20
0
        public static List <LogInfo> TXTAddLineOp(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_TXTAddLineOp));
            CodeInfo_TXTAddLineOp infoOp = cmd.Info as CodeInfo_TXTAddLineOp;

            string         fileName = StringEscaper.Preprocess(s, infoOp.InfoList[0].FileName);
            string         modeStr  = StringEscaper.Preprocess(s, infoOp.InfoList[0].Mode);
            TXTAddLineMode mode;

            if (modeStr.Equals("Append", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Append;
            }
            else if (modeStr.Equals("Prepend", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Prepend;
            }
            else
            {
                throw new ExecuteException($"Mode [{modeStr}] must be one of [Append, Prepend]");
            }

            if (StringEscaper.PathSecurityCheck(fileName, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            // Detect encoding of text
            // If text does not exists, create blank file
            Encoding encoding = Encoding.Default;

            if (File.Exists(fileName))
            {
                encoding = FileHelper.DetectTextEncoding(fileName);
            }

            string linesToWrite;

            if (mode == TXTAddLineMode.Prepend)
            {
                string tempPath = Path.GetTempFileName();
                using (StreamReader reader = new StreamReader(fileName, encoding))
                    using (StreamWriter writer = new StreamWriter(tempPath, false, encoding))
                    {
                        StringBuilder b = new StringBuilder();
                        for (int i = infoOp.InfoList.Count - 1; 0 <= i; i--)
                        {
                            b.AppendLine(StringEscaper.Preprocess(s, infoOp.InfoList[i].Line));
                        }
                        linesToWrite = b.ToString();

                        writer.Write(linesToWrite);
                        writer.Write(reader.ReadToEnd());
                    }
                FileHelper.FileReplaceEx(tempPath, fileName);

                logs.Add(new LogInfo(LogState.Success, $"Lines prepened to [{fileName}] : \r\n{linesToWrite}", cmd));
            }
            else if (mode == TXTAddLineMode.Append)
            {
                StringBuilder b = new StringBuilder();
                for (int i = 0; i < infoOp.InfoList.Count; i++)
                {
                    b.AppendLine(StringEscaper.Preprocess(s, infoOp.InfoList[i].Line));
                }
                linesToWrite = b.ToString();

                bool newLineExist = true;
                if (File.Exists(fileName))
                {
                    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        long   bomLen   = FileHelper.TextBOMLength(fs);
                        byte[] lastChar = new byte[2];
                        if (2 + bomLen <= fs.Length)
                        {
                            fs.Position = fs.Length - 2;
                            fs.Read(lastChar, 0, 2);
                            if (lastChar[0] != '\r' || lastChar[1] != '\n')
                            {
                                newLineExist = false;
                            }
                        }
                    }
                }

                if (newLineExist)
                {
                    File.AppendAllText(fileName, linesToWrite, encoding);
                }
                else
                {
                    File.AppendAllText(fileName, "\r\n" + linesToWrite, encoding);
                }

                logs.Add(new LogInfo(LogState.Success, $"Lines appended to [{fileName}] : \r\n{linesToWrite}", cmd));
            }

            return(logs);
        }
Ejemplo n.º 21
0
 static IMemberRef GetMemberRef(IMenuItemContext context) => CodeCommand.GetMemberRef(context, MenuConstants.GUIDOBJ_SEARCH_GUID);
Ejemplo n.º 22
0
 public static void RunExec(EngineState s, CodeCommand cmd, bool preserveCurParams = false, bool forceLog = false)
 {
     RunExec(s, cmd, preserveCurParams, forceLog, false);
 }
Ejemplo n.º 23
0
        public static List <LogInfo> Set(EngineState s, CodeCommand cmd)
        {
            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Set));
            CodeInfo_Set info = cmd.Info as CodeInfo_Set;

            Variables.VarKeyType varType = Variables.DetermineType(info.VarKey);
            if (varType == Variables.VarKeyType.None)
            {
                // Check Macro
                if (Regex.Match(info.VarKey, Macro.MacroNameRegex, RegexOptions.Compiled).Success) // Macro Name Validation
                {
                    string macroCommand = StringEscaper.Preprocess(s, info.VarValue);

                    if (macroCommand.Equals("NIL", StringComparison.OrdinalIgnoreCase))
                    {
                        macroCommand = null;
                    }

                    LogInfo log = s.Macro.SetMacro(info.VarKey, macroCommand, cmd.Addr, info.Permanent);
                    return(new List <LogInfo>(1)
                    {
                        log
                    });
                }
            }

            // [WB082 Behavior]
            // If PERMANENT was used but the key exists in interface command, the value will not be written to script.project but in interface.
            // Need to investigate where the logs are saved in this case.
            switch (info.Permanent)
            {
            case true:
            {         // Check if interface contains VarKey
                List <LogInfo> logs = new List <LogInfo>();

                if (Variables.DetermineType(info.VarKey) != Variables.VarKeyType.Variable)
                {
                    goto case false;
                }

                string varKey     = Variables.TrimPercentMark(info.VarKey);
                string finalValue = StringEscaper.Preprocess(s, info.VarValue);

                #region Set UI
                Plugin        p     = cmd.Addr.Plugin;
                PluginSection iface = p.GetInterface(out string sectionName);
                if (iface == null)
                {
                    goto case false;
                }

                List <UICommand> uiCmds = iface.GetUICodes(true);
                UICommand        uiCmd  = uiCmds.Find(x => x.Key.Equals(varKey));
                if (uiCmd == null)
                {
                    goto case false;
                }

                bool match = false;
                switch (uiCmd.Type)
                {
                case UIType.TextBox:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_TextBox));
                    UIInfo_TextBox uiInfo = uiCmd.Info as UIInfo_TextBox;

                    uiInfo.Value = finalValue;

                    logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [{finalValue}]"));
                    match = true;
                }
                break;

                case UIType.NumberBox:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_NumberBox));
                    UIInfo_NumberBox uiInfo = uiCmd.Info as UIInfo_NumberBox;

                    // WB082 just write string value in case of error, but PEBakery will throw warning
                    if (!NumberHelper.ParseInt32(finalValue, out int intVal))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"[{finalValue}] is not valid integer"));
                        return(logs);
                    }

                    uiInfo.Value = intVal;

                    logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [{finalValue}]"));
                    match = true;
                }
                break;

                case UIType.CheckBox:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_CheckBox));
                    UIInfo_CheckBox uiInfo = uiCmd.Info as UIInfo_CheckBox;

                    if (finalValue.Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        uiInfo.Value = true;

                        logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [True]"));
                        match = true;
                    }
                    else if (finalValue.Equals("False", StringComparison.OrdinalIgnoreCase))
                    {
                        uiInfo.Value = false;

                        logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [False]"));
                        match = true;
                    }
                    else
                    {                 // WB082 just write string value in case of error, but PEBakery will throw warning
                        logs.Add(new LogInfo(LogState.Warning, $"[{finalValue}] is not valid boolean"));
                        return(logs);
                    }
                }
                break;

                case UIType.ComboBox:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_ComboBox));
                    UIInfo_ComboBox uiInfo = uiCmd.Info as UIInfo_ComboBox;

                    int idx = uiInfo.Items.FindIndex(x => x.Equals(finalValue, StringComparison.OrdinalIgnoreCase));
                    if (idx == -1)
                    {                 // Invalid Index
                        logs.Add(new LogInfo(LogState.Warning, $"[{finalValue}] not found in item list"));
                        return(logs);
                    }

                    uiInfo.Index = idx;
                    uiCmd.Text   = uiInfo.Items[idx];

                    logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [{uiCmd.Text}]"));
                    match = true;
                }
                break;

                case UIType.RadioButton:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_RadioButton));
                    UIInfo_RadioButton uiInfo = uiCmd.Info as UIInfo_RadioButton;

                    if (finalValue.Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        uiInfo.Selected = true;

                        logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to true]"));
                        match = true;
                    }
                    else if (finalValue.Equals("False", StringComparison.OrdinalIgnoreCase))
                    {
                        uiInfo.Selected = false;

                        logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [False]"));
                        match = true;
                    }
                    else
                    {                 // WB082 just write string value, but PEBakery will ignore and throw and warning
                        logs.Add(new LogInfo(LogState.Warning, $"[{finalValue}] is not valid boolean"));
                        return(logs);
                    }
                }
                break;

                case UIType.FileBox:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_FileBox));
                    UIInfo_FileBox uiInfo = uiCmd.Info as UIInfo_FileBox;

                    uiCmd.Text = finalValue;

                    logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [{finalValue}]"));
                    match = true;
                }
                break;

                case UIType.RadioGroup:
                {
                    Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_RadioGroup));
                    UIInfo_RadioGroup uiInfo = uiCmd.Info as UIInfo_RadioGroup;

                    int idx = uiInfo.Items.FindIndex(x => x.Equals(finalValue, StringComparison.OrdinalIgnoreCase));
                    if (idx == -1)
                    {                 // Invalid Index
                        logs.Add(new LogInfo(LogState.Warning, $"[{finalValue}] not found in item list"));
                        return(logs);
                    }

                    uiInfo.Selected = idx;

                    logs.Add(new LogInfo(LogState.Success, $"Interface [{varKey}] set to [{finalValue}]"));
                    match = true;
                }
                break;
                }

                if (match)
                {
                    uiCmd.Update();

                    logs.AddRange(Variables.SetVariable(s, info.VarKey, info.VarValue, false, false));
                    return(logs);
                }
                else
                {
                    goto case false;
                }
                #endregion
            }

            case false:
            default:
                return(Variables.SetVariable(s, info.VarKey, info.VarValue, info.Global, info.Permanent));
            }
        }
Ejemplo n.º 24
0
        public static List <LogInfo> TXTDelLineOp(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_TXTDelLineOp));
            CodeInfo_TXTDelLineOp infoOp = cmd.Info as CodeInfo_TXTDelLineOp;

            string fileName = StringEscaper.Preprocess(s, infoOp.InfoList[0].FileName);

            if (StringEscaper.PathSecurityCheck(fileName, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            if (File.Exists(fileName) == false)
            {
                logs.Add(new LogInfo(LogState.Error, $"File [{fileName}] not exists"));
                return(logs);
            }

            List <string> prepDeleteLine = new List <string>();

            foreach (CodeInfo_TXTDelLine info in infoOp.InfoList)
            {
                string deleteLine = StringEscaper.Preprocess(s, info.DeleteLine);
                prepDeleteLine.Add(deleteLine);
            }

            Encoding encoding = FileHelper.DetectTextEncoding(fileName);

            int    count    = 0;
            string tempPath = Path.GetTempFileName();

            using (StreamReader reader = new StreamReader(fileName, encoding))
                using (StreamWriter writer = new StreamWriter(tempPath, false, encoding))
                {
                    string srcLine;
                    while ((srcLine = reader.ReadLine()) != null)
                    {
                        bool writeLine = true;
                        foreach (string deleteLine in prepDeleteLine)
                        {
                            // Strange enough, WB082 treat [deleteLine] as case sensitive string.
                            if (srcLine.StartsWith(deleteLine, StringComparison.Ordinal))
                            {
                                writeLine = false;
                                count++;
                                break;
                            }
                        }

                        if (writeLine)
                        {
                            writer.WriteLine(srcLine);
                        }
                    }
                }
            FileHelper.FileReplaceEx(tempPath, fileName);

            logs.Add(new LogInfo(LogState.Success, $"Deleted [{count}] lines from [{fileName}]"));

            return(logs);
        }
Ejemplo n.º 25
0
        public static void Loop(EngineState s, CodeCommand cmd)
        {
            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Loop));
            CodeInfo_Loop info = cmd.Info as CodeInfo_Loop;

            if (info.Break)
            {
                if (s.LoopState == LoopState.Off)
                {
                    s.Logger.Build_Write(s, new LogInfo(LogState.Error, "Loop is not running", cmd, s.CurDepth));
                }
                else
                {
                    s.LoopState = LoopState.Off;
                    s.Logger.Build_Write(s, new LogInfo(LogState.Info, "Breaking loop", cmd, s.CurDepth));

                    // Reset LoopCounter, to be sure
                    s.LoopLetter  = ' ';
                    s.LoopCounter = 0;
                }
            }
            else if (s.LoopState != LoopState.Off)
            { // If loop is already turned on, throw error
                s.Logger.Build_Write(s, new LogInfo(LogState.Error, "Nested loop is not supported", cmd, s.CurDepth));
            }
            else
            {
                string startStr = StringEscaper.Preprocess(s, info.StartIdx);
                string endStr   = StringEscaper.Preprocess(s, info.EndIdx);

                // Prepare Loop
                string        scriptFile  = StringEscaper.Preprocess(s, info.ScriptFile);
                string        sectionName = StringEscaper.Preprocess(s, info.SectionName);
                List <string> paramList   = StringEscaper.Preprocess(s, info.Parameters);

                Script p = Engine.GetScriptInstance(s, cmd, s.CurrentScript.FullPath, scriptFile, out bool inCurrentScript);

                // Does section exists?
                if (!p.Sections.ContainsKey(sectionName))
                {
                    throw new ExecuteException($"[{scriptFile}] does not have section [{sectionName}]");
                }

                // Section Parameter
                Dictionary <int, string> paramDict = new Dictionary <int, string>();
                for (int i = 0; i < paramList.Count; i++)
                {
                    paramDict[i + 1] = paramList[i];
                }

                long loopCount = 0;
                long startIdx = 0, endIdx = 0;
                char startLetter = ' ', endLetter = ' ';
                switch (cmd.Type)
                {
                case CodeType.Loop:
                {         // Integer Index
                    if (!NumberHelper.ParseInt64(startStr, out startIdx))
                    {
                        throw new ExecuteException($"Argument [{startStr}] is not a valid integer");
                    }
                    if (!NumberHelper.ParseInt64(endStr, out endIdx))
                    {
                        throw new ExecuteException($"Argument [{endStr}] is not a valid integer");
                    }
                    loopCount = endIdx - startIdx + 1;
                }
                break;

                case CodeType.LoopLetter:
                {         // Drive Letter
                    if (!(startStr.Length == 1 && StringHelper.IsAlphabet(startStr[0])))
                    {
                        throw new ExecuteException($"Argument [{startStr}] is not a valid drive letter");
                    }
                    if (!(endStr.Length == 1 && StringHelper.IsAlphabet(endStr[0])))
                    {
                        throw new ExecuteException($"Argument [{endStr}] is not a valid drive letter");
                    }

                    startLetter = char.ToUpper(startStr[0]);
                    endLetter   = char.ToUpper(endStr[0]);

                    if (endLetter < startLetter)
                    {
                        throw new ExecuteException($"StartLetter must be smaller than EndLetter in lexicographic order");
                    }

                    loopCount = endLetter - startLetter + 1;
                }
                break;

                default:
                    throw new InternalException("Internal Logic Error at CommandBranch.Loop");
                }

                // Log Messages
                string logMessage;
                if (inCurrentScript)
                {
                    logMessage = $"Loop Section [{sectionName}] [{loopCount}] times";
                }
                else
                {
                    logMessage = $"Loop [{p.Title}]'s Section [{sectionName}] [{loopCount}] times";
                }
                s.Logger.Build_Write(s, new LogInfo(LogState.Info, logMessage, cmd, s.CurDepth));

                // Loop it
                SectionAddress nextAddr = new SectionAddress(p, p.Sections[sectionName]);
                int            loopIdx  = 1;
                switch (cmd.Type)
                {
                case CodeType.Loop:
                    for (s.LoopCounter = startIdx; s.LoopCounter <= endIdx; s.LoopCounter++)
                    {     // Counter Variable is [#c]
                        s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"Entering Loop with [{s.LoopCounter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth));
                        s.Logger.LogSectionParameter(s, s.CurDepth, paramDict, cmd);

                        int depthBackup = s.CurDepth;
                        s.LoopState = LoopState.OnIndex;
                        Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, true);
                        if (s.LoopState == LoopState.Off)     // Loop,Break
                        {
                            break;
                        }
                        s.LoopState = LoopState.Off;
                        s.CurDepth  = depthBackup;

                        s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"End of Loop with [{s.LoopCounter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth));
                        loopIdx += 1;
                    }
                    break;

                case CodeType.LoopLetter:
                    for (s.LoopLetter = startLetter; s.LoopLetter <= endLetter; s.LoopLetter++)
                    {     // Counter Variable is [#c]
                        s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"Entering Loop with [{s.LoopLetter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth));
                        s.Logger.LogSectionParameter(s, s.CurDepth, paramDict, cmd);

                        int depthBackup = s.CurDepth;
                        s.LoopState = LoopState.OnDriveLetter;
                        Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, true);
                        if (s.LoopState == LoopState.Off)     // Loop,Break
                        {
                            break;
                        }
                        s.LoopState = LoopState.Off;
                        s.CurDepth  = depthBackup;

                        s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"End of Loop with [{s.LoopLetter}] ({loopIdx}/{loopCount})", cmd, s.CurDepth));
                        loopIdx += 1;
                    }
                    break;

                default:
                    throw new InternalException("Internal Logic Error at CommandBranch.Loop");
                }

                // Reset LoopCounter, to be sure
                s.LoopLetter  = ' ';
                s.LoopCounter = 0;
            }
        }
Ejemplo n.º 26
0
        public static List <LogInfo> Math(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_Math info = cmd.Info.Cast <CodeInfo_Math>();

            MathType type = info.Type;

            switch (type)
            {
            case MathType.Add:
            case MathType.Sub:
            case MathType.Mul:
            case MathType.Div:
            {
                MathInfo_Arithmetic subInfo = info.SubInfo.Cast <MathInfo_Arithmetic>();

                string srcStr1 = StringEscaper.Preprocess(s, subInfo.Src1);
                string srcStr2 = StringEscaper.Preprocess(s, subInfo.Src2);

                if (!NumberHelper.ParseDecimal(srcStr1, out decimal src1))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr1}] is not a valid integer"));
                }
                if (!NumberHelper.ParseDecimal(srcStr2, out decimal src2))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr2}] is not a valid integer"));
                }

                decimal destInt;
                switch (type)
                {
                case MathType.Add:
                    destInt = src1 + src2;
                    break;

                case MathType.Sub:
                    destInt = src1 - src2;
                    break;

                case MathType.Mul:
                    destInt = src1 * src2;
                    break;

                case MathType.Div:
                    destInt = src1 / src2;
                    break;

                default:
                    throw new InternalException("Internal Logic Error at Math,Arithmetic");
                }

                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destInt.ToString(CultureInfo.InvariantCulture)));
            }
            break;

            case MathType.IntDiv:
            {
                MathInfo_IntDiv subInfo = info.SubInfo.Cast <MathInfo_IntDiv>();

                string srcStr1 = StringEscaper.Preprocess(s, subInfo.Src1);
                string srcStr2 = StringEscaper.Preprocess(s, subInfo.Src2);

                if (srcStr1.StartsWith("-", StringComparison.Ordinal) ||
                    srcStr2.StartsWith("-", StringComparison.Ordinal))
                {         // Signed
                    if (!NumberHelper.ParseInt64(srcStr1, out long src1))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr1}] is not a valid integer"));
                    }
                    if (!NumberHelper.ParseInt64(srcStr2, out long src2))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr2}] is not a valid integer"));
                    }

                    long q = src1 / src2;
                    long r = src1 % src2;

                    logs.AddRange(Variables.SetVariable(s, subInfo.QuotientVar, q.ToString()));
                    logs.AddRange(Variables.SetVariable(s, subInfo.RemainderVar, r.ToString()));
                }
                else
                {         // Unsigned
                    if (!NumberHelper.ParseUInt64(srcStr1, out ulong src1))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr1}] is not a valid integer"));
                    }
                    if (!NumberHelper.ParseUInt64(srcStr2, out ulong src2))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr2}] is not a valid integer"));
                    }

                    ulong q = src1 / src2;
                    ulong r = src1 % src2;

                    logs.AddRange(Variables.SetVariable(s, subInfo.QuotientVar, q.ToString()));
                    logs.AddRange(Variables.SetVariable(s, subInfo.RemainderVar, r.ToString()));
                }
            }
            break;

            case MathType.Neg:
            {
                MathInfo_Neg subInfo = info.SubInfo.Cast <MathInfo_Neg>();

                string srcStr = StringEscaper.Preprocess(s, subInfo.Src);
                if (!NumberHelper.ParseDecimal(srcStr, out decimal src))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                }

                decimal destInt = src * -1;
                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destInt.ToString(CultureInfo.InvariantCulture)));
            }
            break;

            case MathType.ToSign:
            case MathType.ToUnsign:
            {
                // Math,IntSign,<DestVar>,<Src>,<BitSize>
                // Math,IntUnsign,<DestVar>,<Src>,<BitSize>
                MathInfo_IntegerSignedness subInfo = info.SubInfo.Cast <MathInfo_IntegerSignedness>();

                string srcStr     = StringEscaper.Preprocess(s, subInfo.Src);
                string bitSizeStr = StringEscaper.Preprocess(s, subInfo.BitSize);
                string errorMsg   = ParseAndCheckBitSize(bitSizeStr, out int bitSize);
                if (errorMsg != null)
                {
                    return(LogInfo.LogErrorMessage(logs, errorMsg));
                }

                string destStr;
                if (info.Type == MathType.ToSign)
                {         // Unsigned int to signed int
                    switch (bitSize)
                    {
                    case 8:
                    {
                        if (!NumberHelper.ParseUInt8(srcStr, out byte src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((sbyte)src).ToString();
                    }
                    break;

                    case 16:
                    {
                        if (!NumberHelper.ParseUInt16(srcStr, out ushort src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((short)src).ToString();
                    }
                    break;

                    case 32:
                    {
                        if (!NumberHelper.ParseUInt32(srcStr, out uint src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((int)src).ToString();
                    }
                    break;

                    case 64:
                    {
                        if (!NumberHelper.ParseUInt64(srcStr, out ulong src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((long)src).ToString();
                    }
                    break;

                    default:
                        throw new InternalException("Internal Logic Error at Math,ToSign");
                    }
                }
                else
                {         // Signed int to unsigned int
                    switch (bitSize)
                    {
                    case 8:
                    {
                        if (!NumberHelper.ParseInt8(srcStr, out sbyte src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((byte)src).ToString();
                    }
                    break;

                    case 16:
                    {
                        if (!NumberHelper.ParseInt16(srcStr, out short src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((ushort)src).ToString();
                    }
                    break;

                    case 32:
                    {
                        if (!NumberHelper.ParseInt32(srcStr, out int src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((uint)src).ToString();
                    }
                    break;

                    case 64:
                    {
                        if (!NumberHelper.ParseInt64(srcStr, out long src))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                        }

                        destStr = ((ulong)src).ToString();
                    }
                    break;

                    default:
                        throw new InternalException("Internal Logic Error at Math,ToUnsign");
                    }
                }

                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destStr));
            }
            break;

            case MathType.BoolAnd:
            case MathType.BoolOr:
            case MathType.BoolXor:
            {
                MathInfo_BoolLogicOperation subInfo = info.SubInfo.Cast <MathInfo_BoolLogicOperation>();

                string srcStr1 = StringEscaper.Preprocess(s, subInfo.Src1);
                string srcStr2 = StringEscaper.Preprocess(s, subInfo.Src2);

                bool src1;
                if (NumberHelper.ParseInt64(srcStr1, out long srcInt1))         // C-Style Boolean
                {
                    src1 = srcInt1 != 0;
                }
                else if (srcStr1.Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    src1 = true;
                }
                else if (srcStr1.Equals("False", StringComparison.OrdinalIgnoreCase))
                {
                    src1 = false;
                }
                else
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr1}] is not valid boolean value"));
                }

                bool src2;
                if (NumberHelper.ParseInt64(srcStr2, out long srcInt2))         // C-Style Boolean
                {
                    src2 = srcInt2 != 0;
                }
                else if (srcStr2.Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    src2 = true;
                }
                else if (srcStr2.Equals("False", StringComparison.OrdinalIgnoreCase))
                {
                    src2 = false;
                }
                else
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr2}] is not valid boolean value"));
                }

                bool dest;
                switch (type)
                {
                case MathType.BoolAnd:
                    dest = src1 && src2;
                    break;

                case MathType.BoolOr:
                    dest = src1 || src2;
                    break;

                case MathType.BoolXor:
                    dest = src1 ^ src2;
                    break;

                default:
                    throw new InternalException("Internal Logic Error at Math,BoolLogicOper");
                }

                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, dest.ToString()));
            }
            break;

            case MathType.BoolNot:
            {
                MathInfo_BoolNot subInfo = info.SubInfo.Cast <MathInfo_BoolNot>();

                bool   src;
                string srcStr = StringEscaper.Preprocess(s, subInfo.Src);
                if (NumberHelper.ParseInt64(srcStr, out long srcInt))         // C-Style Boolean
                {
                    src = srcInt != 0;
                }
                else if (srcStr.Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    src = true;
                }
                else if (srcStr.Equals("False", StringComparison.OrdinalIgnoreCase))
                {
                    src = false;
                }
                else
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not valid boolean value"));
                }

                bool dest = !src;
                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, dest.ToString()));
            }
            break;

            case MathType.BitAnd:
            case MathType.BitOr:
            case MathType.BitXor:
            {
                MathInfo_BitLogicOperation subInfo = info.SubInfo.Cast <MathInfo_BitLogicOperation>();

                string srcStr1 = StringEscaper.Preprocess(s, subInfo.Src1);
                string srcStr2 = StringEscaper.Preprocess(s, subInfo.Src2);

                if (!NumberHelper.ParseUInt64(srcStr1, out ulong src1))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr1}] is not a valid integer"));
                }
                if (!NumberHelper.ParseUInt64(srcStr2, out ulong src2))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr2}] is not a valid integer"));
                }

                ulong dest;
                switch (type)
                {
                case MathType.BitAnd:
                    dest = src1 & src2;
                    break;

                case MathType.BitOr:
                    dest = src1 | src2;
                    break;

                case MathType.BitXor:
                    dest = src1 ^ src2;
                    break;

                default:
                    throw new InternalException("Internal Logic Error at Math,BitLogicOper");
                }

                string destStr = dest.ToString();
                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destStr));
            }
            break;

            case MathType.BitNot:
            {
                MathInfo_BitNot subInfo = info.SubInfo.Cast <MathInfo_BitNot>();

                string srcStr     = StringEscaper.Preprocess(s, subInfo.Src);
                string bitSizeStr = StringEscaper.Preprocess(s, subInfo.BitSize);
                string errorMsg   = ParseAndCheckBitSize(bitSizeStr, out int bitSize);
                if (errorMsg != null)
                {
                    return(LogInfo.LogErrorMessage(logs, errorMsg));
                }

                string destStr;
                switch (bitSize)
                {
                case 8:
                {
                    if (!NumberHelper.ParseUInt8(srcStr, out byte src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    destStr = ((byte)~src).ToString();
                }
                break;

                case 16:
                {
                    if (!NumberHelper.ParseUInt16(srcStr, out ushort src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    destStr = ((ushort)~src).ToString();
                }
                break;

                case 32:
                {
                    if (!NumberHelper.ParseUInt32(srcStr, out uint src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    destStr = (~src).ToString();
                }
                break;

                case 64:
                {
                    if (!NumberHelper.ParseUInt64(srcStr, out ulong src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    destStr = (~src).ToString();
                }
                break;

                default:
                    throw new InternalException("Internal Logic Error at Math,BitNot");
                }

                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destStr));
            }
            break;

            case MathType.BitShift:
            {
                MathInfo_BitShift subInfo = info.SubInfo.Cast <MathInfo_BitShift>();

                string srcStr = StringEscaper.Preprocess(s, subInfo.Src);

                string shiftStr = StringEscaper.Preprocess(s, subInfo.Shift);
                if (!NumberHelper.ParseInt32(shiftStr, out int shift))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{shiftStr}] is not a valid integer"));
                }

                string directionStr = StringEscaper.Preprocess(s, subInfo.Direction);
                bool   isLeft       = false;
                if (directionStr.Equals("Left", StringComparison.OrdinalIgnoreCase))
                {
                    isLeft = true;
                }
                else if (!directionStr.Equals("Right", StringComparison.OrdinalIgnoreCase))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{directionStr}] must be one of [Left, Right]"));
                }

                string bitSizeStr = StringEscaper.Preprocess(s, subInfo.BitSize);
                string errorMsg   = ParseAndCheckBitSize(bitSizeStr, out int bitSize);
                if (errorMsg != null)
                {
                    return(LogInfo.LogErrorMessage(logs, errorMsg));
                }

                string destStr;
                switch (bitSize)
                {
                case 8:
                {
                    if (!NumberHelper.ParseUInt8(srcStr, out byte src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    byte dest;
                    if (isLeft)
                    {
                        dest = (byte)(src << shift);
                    }
                    else
                    {
                        dest = (byte)(src >> shift);
                    }
                    destStr = dest.ToString();
                }
                break;

                case 16:
                {
                    if (!NumberHelper.ParseUInt16(srcStr, out ushort src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    ushort dest;
                    if (isLeft)
                    {
                        dest = (ushort)(src << shift);
                    }
                    else
                    {
                        dest = (ushort)(src >> shift);
                    }
                    destStr = dest.ToString();
                }
                break;

                case 32:
                {
                    if (!NumberHelper.ParseUInt32(srcStr, out uint src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    uint dest;
                    if (isLeft)
                    {
                        dest = src << shift;
                    }
                    else
                    {
                        dest = src >> shift;
                    }
                    destStr = dest.ToString();
                }
                break;

                case 64:
                {
                    if (!NumberHelper.ParseUInt64(srcStr, out ulong src))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                    }

                    ulong dest;
                    if (isLeft)
                    {
                        dest = src << shift;
                    }
                    else
                    {
                        dest = src >> shift;
                    }
                    destStr = dest.ToString();
                }
                break;

                default:
                    throw new InternalException("Internal Logic Error at Math,BitShift");
                }

                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, destStr));
            }
            break;

            case MathType.Ceil:
            case MathType.Floor:
            case MathType.Round:
            {
                MathInfo_CeilFloorRound subInfo = info.SubInfo.Cast <MathInfo_CeilFloorRound>();

                string srcStr = StringEscaper.Preprocess(s, subInfo.Src);
                if (!NumberHelper.ParseInt64(srcStr, out long srcInt))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                }

                string unitStr = StringEscaper.Preprocess(s, subInfo.Unit);
                // Is roundToStr number?
                if (!NumberHelper.ParseInt64(unitStr, out long unit))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{unitStr}] is not a valid integer"));
                }
                if (unit < 0)
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{unit}] must be positive integer"));
                }

                long destInt;
                long remainder = srcInt % unit;
                switch (type)
                {
                case MathType.Ceil:
                    destInt = srcInt - remainder + unit;
                    break;

                case MathType.Floor:
                    destInt = srcInt - remainder;
                    break;

                case MathType.Round:
                    if ((unit - 1) / 2 < remainder)
                    {
                        destInt = srcInt - remainder + unit;
                    }
                    else
                    {
                        destInt = srcInt - remainder;
                    }
                    break;

                default:
                    throw new InternalException($"Internal Logic Error at Math,{info.Type}");
                }

                List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, destInt.ToString());
                logs.AddRange(varLogs);
            }
            break;

            case MathType.Abs:
            {
                MathInfo_Abs subInfo = info.SubInfo.Cast <MathInfo_Abs>();

                string srcStr = StringEscaper.Preprocess(s, subInfo.Src);
                if (!NumberHelper.ParseDecimal(srcStr, out decimal src))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{srcStr}] is not a valid integer"));
                }

                decimal dest = System.Math.Abs(src);
                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, dest.ToString(CultureInfo.InvariantCulture)));
            }
            break;

            case MathType.Pow:
            {
                MathInfo_Pow subInfo = info.SubInfo.Cast <MathInfo_Pow>();

                string baseStr = StringEscaper.Preprocess(s, subInfo.Base);
                if (!NumberHelper.ParseDecimal(baseStr, out decimal _base))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{baseStr}] is not a valid integer"));
                }

                string powerStr = StringEscaper.Preprocess(s, subInfo.Power);
                if (!NumberHelper.ParseUInt32(powerStr, out uint power))
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{baseStr}] is not a postivie integer"));
                }

                decimal dest = NumberHelper.DecimalPower(_base, power);
                logs.AddRange(Variables.SetVariable(s, subInfo.DestVar, dest.ToString(CultureInfo.InvariantCulture)));
            }
            break;

            case MathType.Hex:
            case MathType.Dec:
            {
                MathInfo_HexDec subInfo = info.SubInfo.Cast <MathInfo_HexDec>();

                string intStr     = StringEscaper.Preprocess(s, subInfo.Src);
                string bitSizeStr = StringEscaper.Preprocess(s, subInfo.BitSize);
                string errorMsg   = ParseAndCheckBitSize(bitSizeStr, out int bitSize);
                if (errorMsg != null)
                {
                    return(LogInfo.LogErrorMessage(logs, errorMsg));
                }

                string dest;
                switch (bitSize)
                {
                case 8:
                    if (!NumberHelper.ParseSignedAsUInt8(intStr, out byte u8))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{intStr}] is not a valid 8bit integer"));
                    }
                    dest = info.Type == MathType.Hex ? $"0x{u8:X2}" : u8.ToString();
                    break;

                case 16:
                    if (!NumberHelper.ParseSignedAsUInt16(intStr, out ushort u16))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{intStr}] is not a valid 16bit integer"));
                    }
                    dest = info.Type == MathType.Hex ? $"0x{u16:X4}" : u16.ToString();
                    break;

                case 32:
                    if (!NumberHelper.ParseSignedAsUInt32(intStr, out uint u32))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{intStr}] is not a valid 32bit integer"));
                    }
                    dest = info.Type == MathType.Hex ? $"0x{u32:X8}" : u32.ToString();
                    break;

                case 64:
                    if (!NumberHelper.ParseSignedAsUInt64(intStr, out ulong u64))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{intStr}] is not a valid 64bit integer"));
                    }
                    dest = info.Type == MathType.Hex ? $"0x{u64:X16}" : u64.ToString();
                    break;

                default:
                    throw new InternalException($"Internal Logic Error at Math,{info.Type}");
                }

                List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, dest);
                logs.AddRange(varLogs);
            }
            break;

            case MathType.Rand:
            {
                MathInfo_Rand subInfo = info.SubInfo.Cast <MathInfo_Rand>();

                int min = 0;
                if (subInfo.Min != null)
                {
                    string minStr = StringEscaper.Preprocess(s, subInfo.Min);
                    if (!NumberHelper.ParseInt32(minStr, out min))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{minStr}] is not a valid integer"));
                    }
                    if (min < 0)
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{min}] must be positive integer"));
                    }
                }

                int max = 65536;
                if (subInfo.Max != null)
                {
                    string maxStr = StringEscaper.Preprocess(s, subInfo.Max);
                    if (!NumberHelper.ParseInt32(maxStr, out max))
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{maxStr}] is not a valid integer"));
                    }
                    if (max < 0)
                    {
                        return(LogInfo.LogErrorMessage(logs, $"[{max}] must be positive integer"));
                    }
                    if (max <= min)
                    {
                        return(LogInfo.LogErrorMessage(logs, "Maximum bounds must be larger than minimum value"));
                    }
                }

                int destInt = s.Random.Next() % (max - min) + min;

                List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, destInt.ToString());
                logs.AddRange(varLogs);
            }
            break;

            default:     // Error
                throw new InternalException("Internal Logic Error at CommandMath.Math");
            }

            return(logs);
        }
Ejemplo n.º 27
0
        public static void RunExec(EngineState s, CodeCommand cmd, bool preserveCurParams, bool forceLog, bool callback)
        {
            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_RunExec));
            CodeInfo_RunExec info = cmd.Info as CodeInfo_RunExec;

            string        scriptFile  = StringEscaper.Preprocess(s, info.ScriptFile);
            string        sectionName = StringEscaper.Preprocess(s, info.SectionName);
            List <string> paramList   = StringEscaper.Preprocess(s, info.Parameters);

            Script p = Engine.GetScriptInstance(s, cmd, s.CurrentScript.FullPath, scriptFile, out bool inCurrentScript);

            // Does section exists?
            if (!p.Sections.ContainsKey(sectionName))
            {
                throw new ExecuteException($"[{scriptFile}] does not have section [{sectionName}]");
            }

            // Section Parameter
            Dictionary <int, string> paramDict = new Dictionary <int, string>();

            if (preserveCurParams)
            {
                paramDict = s.CurSectionParams;
            }
            else
            {
                for (int i = 0; i < paramList.Count; i++)
                {
                    paramDict[i + 1] = paramList[i];
                }
            }

            // Branch to new section
            SectionAddress nextAddr = new SectionAddress(p, p.Sections[sectionName]);

            s.Logger.LogStartOfSection(s, nextAddr, s.CurDepth, inCurrentScript, paramDict, cmd, forceLog);

            Dictionary <string, string>      localVars   = null;
            Dictionary <string, string>      fixedVars   = null;
            Dictionary <string, CodeCommand> localMacros = null;

            if (cmd.Type == CodeType.Exec)
            {
                // Backup Varaibles and Macros
                localVars   = s.Variables.GetVarDict(VarsType.Local);
                fixedVars   = s.Variables.GetVarDict(VarsType.Fixed);
                localMacros = s.Macro.LocalDict;

                // Load Per-Script Variables
                s.Variables.ResetVariables(VarsType.Local);
                List <LogInfo> varLogs = s.Variables.LoadDefaultScriptVariables(p);
                s.Logger.Build_Write(s, LogInfo.AddDepth(varLogs, s.CurDepth + 1));

                // Load Per-Script Macro
                s.Macro.ResetLocalMacros();
                List <LogInfo> macroLogs = s.Macro.LoadLocalMacroDict(p, false);
                s.Logger.Build_Write(s, LogInfo.AddDepth(macroLogs, s.CurDepth + 1));
            }

            // Run Section
            int depthBackup = s.CurDepth;
            int errorOffStartLineIdxBackup = s.ErrorOffStartLineIdx;
            int erroroffCountBackup        = s.ErrorOffLineCount;

            Engine.RunSection(s, nextAddr, paramDict, s.CurDepth + 1, callback);

            if (cmd.Type == CodeType.Exec)
            {
                // Restore Variables
                s.Variables.SetVarDict(VarsType.Local, localVars);
                s.Variables.SetVarDict(VarsType.Fixed, fixedVars);

                // Restore Local Macros
                s.Macro.SetLocalMacros(localMacros);
            }

            s.CurDepth             = depthBackup;
            s.ErrorOffStartLineIdx = errorOffStartLineIdxBackup;
            s.ErrorOffLineCount    = erroroffCountBackup;
            s.Logger.LogEndOfSection(s, nextAddr, s.CurDepth, inCurrentScript, cmd, forceLog);
        }
Ejemplo n.º 28
0
        public static List <LogInfo> Expand(EngineState s, CodeCommand cmd)
        {
            List <LogInfo>  logs           = new List <LogInfo>();
            CodeInfo_Expand info           = cmd.Info.Cast <CodeInfo_Expand>();
            List <string>   extractedFiles = new List <string>();

            #region Event Handlers
            void ReportExpandProgress(object sender, ProgressEventArgs e)
            {
                s.MainViewModel.BuildCommandProgressValue = e.PercentDone;
                s.MainViewModel.BuildCommandProgressText  = $"Expanding... ({e.PercentDone}%)";
            }

            object trackLock = new object();
            void TrackExtractedFile(object sender, FileInfoEventArgs e)
            {
                lock (trackLock)
                    extractedFiles.Add(e.FileInfo.FileName);
            }

            #endregion

            string srcCab     = StringEscaper.Preprocess(s, info.SrcCab);
            string destDir    = StringEscaper.Preprocess(s, info.DestDir);
            string singleFile = null;
            if (info.SingleFile != null)
            {
                singleFile = StringEscaper.Preprocess(s, info.SingleFile);
            }

            // Path Security Check
            if (!StringEscaper.PathSecurityCheck(destDir, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            if (!Directory.Exists(destDir))
            {
                if (File.Exists(destDir))
                {
                    return(LogInfo.LogErrorMessage(logs, $"Path [{destDir}] is a file, not a directory"));
                }
                Directory.CreateDirectory(destDir);
            }

            // Does srcCab exist?
            if (!File.Exists(srcCab))
            {
                return(LogInfo.LogErrorMessage(logs, $"Cannot find [{srcCab}]"));
            }

            // Turn on report progress only if file is larger than 1MB
            FileInfo fi             = new FileInfo(srcCab);
            bool     reportProgress = 1024 * 1024 <= fi.Length;

            if (singleFile == null)
            { // No singleFile operand, extract all
                using (SevenZipExtractor extractor = new SevenZipExtractor(srcCab))
                {
                    if (extractor.Format != InArchiveFormat.Cab)
                    {
                        return(LogInfo.LogErrorMessage(logs, "Expand command must be used with cabinet archive"));
                    }

                    if (reportProgress)
                    {
                        extractor.FileExtractionFinished += TrackExtractedFile;
                        extractor.Extracting             += ReportExpandProgress;
                        s.MainViewModel.SetBuildCommandProgress("Expand Progress");
                    }
                    try
                    {
                        extractor.ExtractArchive(destDir);
                        foreach (string file in extractedFiles)
                        {
                            logs.Add(new LogInfo(LogState.Success, $"[{file}] extracted"));
                        }
                        logs.Add(new LogInfo(LogState.Success, $"[{extractedFiles.Count}] files from [{srcCab}] extracted to [{destDir}]"));
                    }
                    finally
                    {
                        if (reportProgress)
                        {
                            extractor.FileExtractionFinished -= TrackExtractedFile;
                            extractor.Extracting             -= ReportExpandProgress;
                            s.MainViewModel.ResetBuildCommandProgress();
                        }
                    }
                }
            }
            else
            { // singleFile specified, extract only that file
                string destPath = Path.Combine(destDir, singleFile);
                if (File.Exists(destPath))
                {     // Check PRESERVE, NOWARN
                    if (info.Preserve)
                    { // Do nothing
                        logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destPath}] already exists, skipping extract from [{srcCab}]"));
                        return(logs);
                    }

                    logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destPath}] will be overwritten"));
                }

                using (SevenZipExtractor extractor = new SevenZipExtractor(srcCab))
                {
                    if (extractor.Format != InArchiveFormat.Cab)
                    {
                        return(LogInfo.LogErrorMessage(logs, "Expand command must be used with cabinet archive"));
                    }

                    if (reportProgress)
                    {
                        extractor.Extracting += ReportExpandProgress;
                        s.MainViewModel.SetBuildCommandProgress("Expand Progress");
                    }

                    string[] archiveFileNames = extractor.ArchiveFileNames.ToArray();
                    if (archiveFileNames.Contains(singleFile, StringComparer.OrdinalIgnoreCase))
                    {
                        try
                        {
                            string destFile = Path.Combine(destDir, singleFile);
                            using (FileStream fs = new FileStream(destFile, FileMode.Create))
                            {
                                extractor.ExtractFile(singleFile, fs);
                            }
                            logs.Add(new LogInfo(LogState.Success, $"[{singleFile}] from [{srcCab}] extracted to [{destPath}]"));
                        }
                        finally
                        {
                            if (reportProgress)
                            {
                                extractor.Extracting -= ReportExpandProgress;
                                s.MainViewModel.ResetBuildCommandProgress();
                            }
                        }
                    }
                    else
                    { // Unable to find specified file
                        logs.Add(new LogInfo(LogState.Error, $"Failed to extract [{singleFile}] from [{srcCab}]"));
                    }
                }
            }

            return(logs);
        }
Ejemplo n.º 29
0
 static IEnumerable <IMemberRef> GetMemberRefs(IMenuItemContext context) =>
 CodeCommand.GetMemberRefs(context, MenuConstants.GUIDOBJ_SEARCH_GUID);
Ejemplo n.º 30
0
        public static List <LogInfo> Compress(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_Compress info = cmd.Info.Cast <CodeInfo_Compress>();

            #region Event Handlers
            void ReportCompressProgress(object sender, ProgressEventArgs e)
            {
                s.MainViewModel.BuildCommandProgressValue = e.PercentDone;
                s.MainViewModel.BuildCommandProgressText  = $"Compressing... ({e.PercentDone}%)";
            }

            #endregion

            // Parse arguments / parameters
            string srcPath     = StringEscaper.Preprocess(s, info.SrcPath);
            string destArchive = StringEscaper.Preprocess(s, info.DestArchive);
            SevenZip.OutArchiveFormat outFormat = ArchiveFile.ToSevenZipOutFormat(info.Format);
            SevenZip.CompressionLevel compLevel = SevenZip.CompressionLevel.Normal;
            if (info.CompressLevel is ArchiveFile.CompressLevel level)
            {
                try
                {
                    compLevel = ArchiveFile.ToSevenZipLevel(level);
                }
                catch (ArgumentException)
                { // Should have been filtered by CodeParser
                    logs.Add(new LogInfo(LogState.CriticalError, $"Invalid ArchiveHelper.CompressLevel [{info.CompressLevel}]"));
                    return(logs);
                }
            }

            // Path Security Check
            if (!StringEscaper.PathSecurityCheck(destArchive, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            // Check if a file or directory exist under name of destArchive
            bool appendMode = false;
            if (Directory.Exists(destArchive))
            {
                return(LogInfo.LogErrorMessage(logs, $"[{destArchive}] should be a file, not a directory"));
            }
            if (File.Exists(destArchive))
            {
                logs.Add(new LogInfo(LogState.Overwrite, $"Archive [{destArchive}] will be appended"));
                appendMode = true;
            }

            // If parent directory of destArchive does not exist, create it
            Directory.CreateDirectory(FileHelper.GetDirNameEx(destArchive));

            // Prepare SevenZipSharp compressor
            SevenZipCompressor compressor = new SevenZipCompressor
            {
                ArchiveFormat    = outFormat,
                CompressionMode  = appendMode ? CompressionMode.Append : CompressionMode.Create,
                CompressionLevel = compLevel,
            };

            // Set filename encoding to UTF-8
            // 7z files always use Unicode filename, so no action is required.
            switch (outFormat)
            {
            case OutArchiveFormat.Zip:
                compressor.CustomParameters["cu"] = "on";     // Force UTF-8 for filename
                break;
            }

            string wildcard = Path.GetFileName(srcPath);
            if (!StringHelper.IsWildcard(wildcard))
            { // No wildcard
                if (File.Exists(srcPath))
                {
                    // Compressor Options
                    compressor.DirectoryStructure = false;

                    // Compressor Callbacks
                    compressor.Compressing += ReportCompressProgress;

                    s.MainViewModel.SetBuildCommandProgress("Compress Progress");
                    try
                    {
                        compressor.CompressFiles(destArchive, srcPath);
                    }
                    finally
                    {
                        compressor.Compressing -= ReportCompressProgress;
                        s.MainViewModel.ResetBuildCommandProgress();
                    }
                }
                else if (Directory.Exists(srcPath))
                {
                    // Compressor Options
                    compressor.DirectoryStructure      = true;
                    compressor.PreserveDirectoryRoot   = true;
                    compressor.IncludeEmptyDirectories = true;

                    // Compressor Callbacks
                    compressor.Compressing += ReportCompressProgress;

                    s.MainViewModel.SetBuildCommandProgress("Compress Progress");
                    try
                    {
                        compressor.CompressDirectory(srcPath, destArchive);
                    }
                    finally
                    {
                        compressor.Compressing -= ReportCompressProgress;
                        s.MainViewModel.ResetBuildCommandProgress();
                    }
                }
                else
                {
                    return(LogInfo.LogErrorMessage(logs, $"Cannot find [{srcPath}]"));
                }

                if (File.Exists(destArchive))
                {
                    logs.Add(new LogInfo(LogState.Success, $"[{srcPath}] compressed to [{destArchive}]"));
                }
                else
                {
                    logs.Add(new LogInfo(LogState.Error, $"Compressing to [{srcPath}] failed"));
                }
            }
            else
            { // With wildcard
                string   srcDirToFind = Path.GetDirectoryName(srcPath);
                string[] files        = FileHelper.GetFilesEx(srcDirToFind, wildcard, SearchOption.AllDirectories);

                // Compressor Options
                compressor.DirectoryStructure      = true;
                compressor.PreserveDirectoryRoot   = true;
                compressor.IncludeEmptyDirectories = true;

                // Compressor Callbacks
                compressor.Compressing += ReportCompressProgress;

                s.MainViewModel.SetBuildCommandProgress("Compress Progress");
                try
                {
                    compressor.CompressFiles(destArchive, files);
                    foreach (string f in files)
                    {
                        logs.Add(new LogInfo(LogState.Success, $"Compressed [{f}]"));
                    }
                }
                finally
                {
                    compressor.Compressing -= ReportCompressProgress;
                    s.MainViewModel.ResetBuildCommandProgress();
                }

                if (File.Exists(destArchive))
                {
                    logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files compressed to [{destArchive}]"));
                }
                else
                {
                    logs.Add(new LogInfo(LogState.Error, $"Compressing to [{srcPath}] failed"));
                }
            }

            return(logs);
        }