Пример #1
0
        /// <summary>
        /// Run,%ScriptFile%,<Section>[,PARAMS]
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public LogInfo[] RunExec(BakeryCommand cmd)
        {
            ArrayList logs = new ArrayList();

            // Necessary operand : 2, optional operand : variable length
            const int necessaryOperandNum = 2;

            if (cmd.Operands.Length < necessaryOperandNum)
            {
                throw new InvalidOperandException("Necessary operands does not exist", cmd);
            }

            // Get necesssary operand
            string pluginFile     = variables.Expand(cmd.Operands[0]);
            string rawPluginFile  = cmd.Operands[0];
            string sectionName    = variables.Expand(cmd.Operands[1]);
            string rawSectoinName = cmd.Operands[1];

            // Get optional operand
            string[] parameters = new string[cmd.Operands.Length - necessaryOperandNum];
            if (necessaryOperandNum < cmd.Operands.Length)
            {
                Array.Copy(cmd.Operands, 2, parameters, 0, cmd.Operands.Length - necessaryOperandNum);
            }

            bool currentPlugin = false;

            if (String.Equals(rawPluginFile, "%PluginFile%", StringComparison.OrdinalIgnoreCase))
            {
                currentPlugin = true;
            }
            else if (String.Equals(rawPluginFile, "%ScriptFile%", StringComparison.OrdinalIgnoreCase))
            {
                currentPlugin = true;
            }

            if (currentPlugin)
            {
                if (!plugins[curPluginIdx].Sections.ContainsKey(sectionName))
                {
                    throw new InvalidOperandException(string.Concat("'", Path.GetFileName(pluginFile), "' does not have section '", sectionName, "'"), cmd);
                }

                // Branch to new section
                returnAddress.Push(new CommandAddress(cmd.Address.section, cmd.Address.line + 1, cmd.Address.secLength));
                nextCommand          = new CommandAddress(plugins[curPluginIdx].Sections[sectionName], 0, plugins[curPluginIdx].Sections[sectionName].SecLines.Length);
                currentSectionParams = parameters;

                // Exec utilizes [Variables] section of the plugin
                if (cmd.Opcode == Opcode.Exec)
                {
                }
            }

            cmd.SectionDepth += 1; // For proper log indentation
            logs.Add(new LogInfo(cmd, string.Concat("Running section '", sectionName, "'"), LogState.Success));

            return(logs.ToArray(typeof(LogInfo)) as LogInfo[]);
        }
Пример #2
0
 /// <summary>
 /// Hold command information, with address and subcommand
 /// </summary>
 /// <param name="opcode"></param>
 /// <param name="operands"></param>
 /// <param name="optional"></param>
 public BakeryCommand(string rawCode, Opcode opcode, string[] operands, CommandAddress address, BakeryCommand subCommand)
 {
     this.rawCode    = rawCode;
     this.opcode     = opcode;
     this.operands   = operands;
     this.address    = address;
     this.subCommand = subCommand;
 }
Пример #3
0
        /// <summary>
        /// Run an plugin
        /// </summary>
        public void RunPlugin()
        {
            LoadDefaultPluginVariables();
            PluginSection section = plugins[curPluginIdx].Sections["Process"];

            nextCommand = new CommandAddress(section, 0, section.SecLines.Length);
            RunCommands();
            return;
        }
Пример #4
0
 /// <summary>
 /// Hold command information, with address and subcommand
 /// </summary>
 /// <param name="opcode"></param>
 /// <param name="operands"></param>
 /// <param name="optional"></param>
 public BakeryCommand(string rawCode, Opcode opcode, string[] operands, CommandAddress address, BakeryCommand subCommand, int sectionDepth)
 {
     this.rawCode      = rawCode;
     this.opcode       = opcode;
     this.operands     = operands;
     this.address      = address;
     this.subCommand   = subCommand;
     this.sectionDepth = sectionDepth;
 }
Пример #5
0
 /// <summary>
 /// Hold command information, with address
 /// </summary>
 /// <param name="opcode"></param>
 /// <param name="operands"></param>
 /// <param name="optional"></param>
 public BakeryCommand(string rawCode, Opcode opcode, string[] operands, CommandAddress address)
 {
     this.rawCode      = rawCode;
     this.opcode       = opcode;
     this.operands     = operands;
     this.address      = address;
     this.subCommand   = null;
     this.sectionDepth = 0;
 }
Пример #6
0
        /// <summary>
        /// Run array of commands.
        /// </summary>
        /// <param name="nextCommand"></param>
        private void RunCommands()
        {
            while (true)
            {
                if (!(nextCommand.line < nextCommand.secLength)) // End of section
                {
                    currentSectionParams = new string[0];
                    BakeryCommand logCmd = new BakeryCommand("End of section", Opcode.None, new string[0], returnAddress.Count);
                    string        logMsg = string.Concat("Section '", nextCommand.section.SecName, "' End");
                    logger.Write(new LogInfo(logCmd, logMsg, LogState.Infomation));
                    try
                    {
                        nextCommand = returnAddress.Pop();
                        if (!(nextCommand.line < nextCommand.secLength)) // Is return address end of section?
                        {
                            continue;
                        }
                    }
                    catch (InvalidOperationException)
                    { // The Stack<T> is empty, terminate function
                        break;
                    }
                }

                // Fetch instructions
                int    i       = nextCommand.line;
                string rawCode = nextCommand.section.SecLines[i].Trim();

                try
                {
                    currentCommand = ParseCommand(rawCode, new CommandAddress(nextCommand.section, i, nextCommand.secLength));

                    try
                    {
                        ExecuteCommand(currentCommand, logger);
                    }
                    catch (InvalidOpcodeException e)
                    {
                        logger.Write(new LogInfo(e.Command, e.Message, LogState.Error));
                    }
                }
                catch (InvalidOpcodeException e)
                {
                    currentCommand = new BakeryCommand(rawCode, Opcode.Unknown, new string[0]);
                    logger.Write(new LogInfo(e.Command, e.Message, LogState.Error));
                }
                catch (InvalidOperandException e)
                {
                    currentCommand = new BakeryCommand(rawCode, Opcode.Unknown, new string[0]);
                    logger.Write(new LogInfo(e.Command, e.Message, LogState.Error));
                }
                nextCommand.line += 1;
            }

            logger.WriteVariables(variables);
        }
Пример #7
0
        /// <summary>
        /// Parse raw command in string into BakeryCommand instance.
        /// </summary>
        /// <param name="rawCode"></param>
        /// <returns></returns>
        private BakeryCommand ParseCommand(string rawCode, CommandAddress address)
        {
            Opcode    opcode      = Opcode.None;
            ArrayList operandList = new ArrayList();

            // Remove whitespace of rawCode's start and end
            rawCode = rawCode.Trim();

            // Check if rawCode is Empty
            if (string.Equals(rawCode, string.Empty))
            {
                return(new BakeryCommand(string.Empty, Opcode.None, new string[0], address, returnAddress.Count));
            }

            // Comment Format : starts with '//' or '#', ';'
            if (rawCode.Substring(0, 2) == "//" || rawCode.Substring(0, 1) == "#" || rawCode.Substring(0, 1) == ";")
            {
                return(new BakeryCommand(rawCode, Opcode.Comment, new string[0], address, returnAddress.Count));
            }

            // Splice with spaces
            string[] slices = rawCode.Split(',');

            // Parse opcode
            try
            {
                // https://msdn.microsoft.com/ko-kr/library/essfb559(v=vs.110).aspx
                Opcode opcodeValue = (Opcode)Enum.Parse(typeof(Opcode), slices[0].Trim(), true);
                if (Enum.IsDefined(typeof(Opcode), opcodeValue))
                {
                    if (opcodeValue != Opcode.None && opcodeValue != Opcode.Comment)
                    {
                        opcode = opcodeValue;
                    }
                    else
                    {
                        throw new InvalidOpcodeException("Unknown command \'" + slices[0].Trim() + "\'", new BakeryCommand(rawCode, Opcode.Unknown, new string[0], address));
                    }
                }
                else
                {
                    throw new InvalidOpcodeException("Unknown command \'" + slices[0].Trim() + "\'", new BakeryCommand(rawCode, Opcode.Unknown, new string[0], address));
                }
            }
            catch (ArgumentException)
            {
                throw new InvalidOpcodeException("Unknown command \'" + slices[0].Trim() + "\'", new BakeryCommand(rawCode, Opcode.Unknown, new string[0], address));
            } // Do nothing

            // Check doublequote's occurence - must be 2n
            if (Helper.CountStringOccurrences(rawCode, "\"") % 2 == 1)
            {
                throw new InvalidCommandException("number of doublequotes must be times of 2");
            }

            /// Parse operand
            ParseState state  = ParseState.Normal;
            string     tmpStr = string.Empty;

            for (int i = 1; i < slices.Length; i++)
            {
                // Remove whitespace
                slices[i] = slices[i].Trim();

                // Check if operand is doublequoted
                int idx = slices[i].IndexOf("\"");
                if (idx == -1) // Do not have doublequote
                {
                    switch (state)
                    {
                    case ParseState.Normal:     // Add to operand
                        operandList.Add(slices[i]);
                        break;

                    case ParseState.Merge:
                        tmpStr = string.Concat(tmpStr, ",", slices[i]);
                        break;

                    default:
                        throw new InternalParseException();
                    }
                }
                else if (idx == 0) // Startes with doublequote
                {                  // Merge this operand with next operand
                    switch (state)
                    {
                    case ParseState.Normal:                                                // Add to operand
                        if (slices[i].IndexOf("\"", idx + 1) != -1)                        // This operand starts and end with doublequote
                        {                                                                  // Ex) FileCopy,"1 2.dll",34.dll
                            operandList.Add(slices[i].Substring(1, slices[i].Length - 2)); // Remove doublequote
                        }
                        else
                        {
                            state  = ParseState.Merge;
                            tmpStr = string.Concat(slices[i].Substring(1));     // Remove doublequote
                        }
                        break;

                    case ParseState.Merge:
                        throw new InvalidOperandException();

                    default:
                        throw new InternalParseException();
                    }
                }
                else if (idx == slices[i].Length - 1) // Endes with doublequote
                {
                    switch (state)
                    {
                    case ParseState.Normal:     // Add to operand
                        throw new InvalidOperandException();

                    case ParseState.Merge:
                        state  = ParseState.Normal;
                        tmpStr = string.Concat(tmpStr, ",", slices[i].Substring(0, slices[i].Length - 1));     // Remove doublequote
                        operandList.Add(tmpStr);
                        tmpStr = string.Empty;
                        break;

                    default:
                        throw new InternalParseException();
                    }
                }
                else // doublequote is in the middle
                {
                    throw new InvalidOperandException();
                }
            }

            // doublequote is not matched by two!
            if (state == ParseState.Merge)
            {
                throw new InvalidOperandException("ParseState == Merge");
            }

            string[] operands = operandList.ToArray(typeof(string)) as string[];
            for (int i = 0; i < operands.Length; i++)
            {
                // Process Escape Characters
                operands[i] = operands[i].Replace(@"$#c", ",");
                operands[i] = operands[i].Replace(@"$#p", "%");
                operands[i] = operands[i].Replace(@"$#q", "\"");
                operands[i] = operands[i].Replace(@"$#s", " ");
                operands[i] = operands[i].Replace(@"$#t", "\t");
                operands[i] = operands[i].Replace(@"$#x", "\n");
                operands[i] = operands[i].Replace(@"$#z", "\x00\x00");
            }

            // forge BakeryCommand
            return(new BakeryCommand(rawCode, opcode, operands, address, returnAddress.Count));
        }