예제 #1
0
        private int StepFlow(ActionBase action)
        {
// function
            if (action is Actionfunction)
            {
                return(++m_IP);
            }

// return
            if (action is Actionreturn)
            {
                m_IP = m_InstrStack.Pop();
                m_CallStack.Pop();
                m_variables.RemoveLocals(m_FnNameStack.Pop());

                return(++m_IP);
            }

// call
            if (action is Actioncall)
            {
                Actioncall call = (Actioncall)action;
                Debug.Assert(null != call);

                m_InstrStack.Push(m_IP);
                m_IP = m_script.GetFuncEntryIndex(call.FunctionName);
                m_CallStack.Push(m_IP);

                if (-1 == m_IP)
                {
                    string errMsg = "Function: '" + call.FunctionName + "' NOT found.";

                    m_Status = VMStatus.ERROR;

                    m_ErrStack.Push(errMsg);
                    host.MarkCurrentLine(m_IP, action.LineNumber, Color.Red, action.Path2Script);
                    action.Result = EnumActionResult.ERROR;

                    throw new Exception(errMsg);
                }

                Actionfunction fn = (Actionfunction)m_script.GetAction(m_IP);
                Debug.Assert(null != fn);

                Dictionary <string, string> vars = new Dictionary <string, string>();

                if (call.Parameters.Count > 0)
                {
                    for (int i = 0; i < call.Parameters.Count; ++i)
                    {
                        string key   = fn.Parameters[i];
                        string value = m_variables.Get(call.Parameters[i]);

                        vars.Add(key, value);
                    }
                }

                m_variables.AddLocals(fn.Name, vars); // create a new scope as well

                m_FnNameStack.Push(fn.Name);

                return(m_IP);
            }

// Label
            if (action is ActionLabel)
            {
                return(++m_IP);
            }

// goto
            if (action is ActionGoto)
            {
                ActionGoto actGoto = (ActionGoto)action;

                int jump2Index = -1;
                int i          = 0;

                foreach (ActionBase item in m_script.Actions) // locate position where to goto
                {
                    if (item is ActionLabel)
                    {
                        ActionLabel actLabel = (ActionLabel)item;

                        if (actLabel.GetLabel == actGoto.label)
                        {
                            jump2Index = i;
                            break;
                        }
                    }
                    ++i;
                }

                if (-1 == jump2Index)
                {
                    throw new Exception("Error locating label '" + actGoto.label + "' for GOTO command.");
                }

                if ("0" != actGoto.jumpCount) // not a FOR-EVER kind of goto
                {
                    if (!m_dicGotoCounts.ContainsKey(actGoto.label))
                    {
                        m_dicGotoCounts.Add(actGoto.label, Convert.ToInt32(actGoto.jumpCount)); // init
                    }
                    if (m_dicGotoCounts[actGoto.label] > 0)
                    {
                        --m_dicGotoCounts[actGoto.label];
                    }
                    else
                    {
                        m_dicGotoCounts.Remove(actGoto.label);
                        m_script.Actions.IndexOf(actGoto);
                        return(m_IP);
                    }
                }
                m_IP = jump2Index;

                return(m_IP);
            }

// foreach
// for
// while
            if (action is ActionFlowIterator)
            {
                ActionFlowIterator act = (ActionFlowIterator)action;

                Debug.Assert(null != act);

                if (0 == m_LoopStack.Count)
                {
                    m_LoopStack.Push(m_IP);
                }
                else if (m_LoopStack.Peek() != m_IP)
                {
                    m_LoopStack.Push(m_IP);
                }

                if (act.IsDone)
                {
                    m_LoopStack.Pop();
                    m_IP = GetMatchingLoopStatement(m_IP);
                }

                return(++m_IP);
            }

// break
            if (action is Actionbreak)
            {
                int ip = m_LoopStack.Pop();

                ActionFlowIterator act = (ActionFlowIterator)m_script.Actions[ip];

                act.Done(); // probably it will cleanup itself from the vm

                m_IP = GetClosestLoopStatement(m_IP);

                return(++m_IP);
            }

// loop
// continue
            if (action is Actionloop || action is Actioncontinue)
            {
                m_IP = m_LoopStack.Peek();
                return(m_IP);
            }

// if
            if (action is Actionif)
            {
                Actionif actIF = (Actionif)action;
                m_IfStack.Push(m_IP);

                if (actIF.result == true)
                {
                    return(++m_IP);  // go inside if block
                }
                else // bypass if block (find else or endif statement (matching! nested if satetement are skipped as well)
                {
                    m_IP = GetMatchingIfStatement(m_IP);
                    return(m_IP);
                }
            }

// endif
            if (action is Actionendif)
            {
                m_IfStack.Pop();
                return(++m_IP);
            }

// else
            if (action is Actionelse)
            {
                int      index = m_IfStack.Peek();
                Actionif actIF = (Actionif)script.Actions[index];

                if (actIF.result == true) // then skip the else part
                {
                    m_IP = GetMatchingIfStatement(m_IP);
                    return(m_IP);
                }
                else
                {
                    return(++m_IP);
                }
            }

            // unknown command
            throw new Exception("Player::StepFlow Unknown FlowCommand [" + action.RawCmdLine.Trim() + "]");
        }
예제 #2
0
        private bool HandleError(ActionBase action)
        {
            if (null == m_actionError)
            {
                m_actionError = action;
            }

            m_variables.UpdateSystem("$ERROR", "True");

            int tmpInstPtr = m_IP;

            ++tmpInstPtr;

            if (tmpInstPtr < script.Actions.Count) // peek ahead one instruction is it a if statement?
            {
                ActionBase actTmp = m_script.GetAction(tmpInstPtr);;

                if (actTmp is Actionif)
                {
                    Actionif actIF = (Actionif)actTmp;
                    Debug.Assert(null != actIF);

                    if (actIF.Params[1] == "$ERROR" || actIF.Params[3] == "$ERROR")
                    {
                        return(true); // error is handled (do not let the playback to be stopped)
                    }
                }
            }

            // unhandled error...
            if (!m_bErrorIsHandled && m_listOnError.Count > 0)
            {
                m_bErrorIsHandled = true;

                int pos = m_script.Actions.IndexOf(action) + 1;

                foreach (string funcName in m_listOnError)
                {
                    if (m_FnNameStack.Count > 0)
                    {
                        string fn = m_FnNameStack.Peek();

                        if (fn == funcName) // do not insert calls inside our function
                        {
                            continue;
                        }
                    }

                    Actioncall call = new Actioncall();
                    call.FunctionName = funcName;

                    m_script.Actions.Insert(pos, call);
                    ++pos;
                }

                ActionError err = new ActionError();

                m_script.Actions.Insert(pos, err);

                return(true); // show must go on
            }
            else
            {
                m_Status = VMStatus.ERROR;
                return(false); // we stop the playback
            }
        }
예제 #3
0
        public void Run()
        {
            m_ScreenshotCounter = 0;

            SaveScreenshotOnPlaybackBegin();

            ActionBase action = null;
            int        ip     = 0;

            m_host.WriteLog("<steps>");

            while (VMStatus.IN_PLAYBACK == m_Status)
            {
                ip = m_IP;

                action = m_script.GetAction(m_IP);

                Step(action);

                if (action is ActionFlow)   // if, for, next, loop, foreach, return, function, call, expression, else, label, goto, endif etc.
                {
                    StepFlow(action);
                }

                switch (action.Result)
                {
                case EnumActionResult.OK:
                    m_variables.UpdateSystem("$ERROR", "False");
                    break;

                case EnumActionResult.ERROR:
                case EnumActionResult.TIMEOUT:
                case EnumActionResult.TEST_FAILED:
                {
                    if (!HandleError(action))     // unhandled error will result is playback stop
                    {
                        SaveScreenshotOnPlaybackEnd();
                        return;
                    }
                }
                break;

                case EnumActionResult.STOPPED:
                    m_Status = VMStatus.STOPPED;
                    SaveScreenshotOnPlaybackEnd();
                    return;
                }

                if (VMStatus.QUIT == m_Status)
                {
                    HandleQuit(action);
                }

                if (ip == m_IP) // the IP is not set artifically (by a flow command)
                {
                    ++m_IP;     // go to the next command
                }
                if (IsFinished())
                {
                    SaveScreenshotOnPlaybackEnd();
                    return;
                }
                else
                {
                    UtilSys.Wait(m_iSpeed);
                }
            }
            SaveScreenshotOnPlaybackEnd();
        }
예제 #4
0
        public bool Init()
        {
            m_Status = VMStatus.INITIALIZATION;

            string path = Path.Combine(host.StartupPath, @"data\log\" + Path.GetFileNameWithoutExtension(m_script.Path) + ".log");

            host.SetLogFile(path, host.BigBrother);

            m_variables = new VariableManager(this, m_script);

            StringBuilder sb = new StringBuilder();

            sb.Append("<Playback ");

            string[,] attributes =
            {
                { "script=",  m_script.Path             },
                { "On=",      UtilSys.GetDateTime()     },
                { "Autorun=", host.IsAutorun.ToString() },
            };

            for (int i = 0; i < attributes.GetLength(0); ++i)
            {
                sb.Append(" " + attributes[i, 0] + "\"" + attributes[i, 1] + "\"");
            }

            sb.Append(">");

            string msg = sb.ToString();

            host.WriteLog(msg);

            m_dtStartTime = DateTime.Now;

            m_actionError = null;

            // register events are using this
            m_bErrorIsHandled = false;
            m_bQuitIsHandled  = false;

            m_utree = null;
            m_grid  = null;
            m_dicControls.Clear();
            m_dicCache.Clear();
            m_dicGotoCounts.Clear();
            m_InstrStack.Clear();
            m_CallStack.Clear();
            m_IfStack.Clear();
            m_LoopStack.Clear(); // this stack is used by instructions like for, while, foreach
            m_FnNameStack.Clear();
            m_ErrStack.Clear();

            m_listAfterEachCommand.Clear();
            m_listAfterCommands.Clear();
            m_listOnError.Clear();
            m_listOnQuit.Clear();

            host.ReleaseSQLStuff();

            m_FnNameStack.Push(VariableManager._GlobalScopeName);

            m_variables.Reset();
            m_variables.AddSystem("$ERROR", "False");
            m_variables.AddSystem("sys.speed", Speed.ToString());
            m_variables.AddSystem("sys.SaveScreenshotOnError", m_bSaveScreenshotOnError.ToString());
            m_variables.AddSystem("env.ScreenWidht", Screen.PrimaryScreen.Bounds.Width.ToString());
            m_variables.AddSystem("env.ScreenHeight", Screen.PrimaryScreen.Bounds.Height.ToString());


            foreach (KeyValuePair <string, string> kv in m_script.Scopes[0].Variables)
            {
                m_variables.Add(kv.Key, kv.Value);
            }

            foreach (KeyValuePair <string, string> kv in m_script.Scopes[0].Consts)
            {
                m_variables.AddConst(kv.Key, kv.Value);
            }

            foreach (KeyValuePair <string, string> kv in Data.Vars)
            {
                m_variables.AddExternal(kv.Key, kv.Value);
            }

            m_IP = m_script.EntryPoint;

            if (-1 == m_IP)
            {
                m_ErrStack.Push("No entry point in script.\r\nEdit script file and enter the [sys.start] command from which point you want playback to begin.");
                return(false);
            }

            m_Status = VMStatus.IN_PLAYBACK;
            return(true);
        }