/// <summary> /// Constructor that uses a parent instruction instead if the id is null. /// </summary> /// <param name="id">Instruction name or id, can be null</param> /// <param name="parent">Parent instruction of this DataRef</param> public DataRef(string id, Instruction parent) { m_ts = TestState.getOnly(); //Assert.IsNotNull(id,"Null id passed for constructing a DataRef"); //Assert.IsFalse(id == "","Empty id passed for constructing a DataRef"); Assert.IsNotNull(m_ts,"Null TestState passed for constructing a DataRef"); Assert.IsNotNull(parent,"Non-null parent instruction expected for constructing a DataRef"); // the id can be $id.data or $id or $.data or $ (parent default data) // these may occur with suffix ';' or space // replace all '$.' with '$genid.data' if (id == null || id.Equals("")) id = "$"; m_id = id; int dol = m_id.IndexOf('$'); if (dol >= 0) { // there are data references string genId = "Internal#Data#Ref"+sm_next_id.ToString(); string dgenId = "$"+genId; sm_next_id += 1; m_id = m_id.Replace("$.",dgenId+"."); m_id = m_id.Replace("$;",dgenId+";"); m_id = m_id.Replace("$ ",dgenId+" "); if (m_id == "$") m_id = dgenId; if (m_id[m_id.Length-1] == '$') // last char m_id = m_id.Substring(0,m_id.Length-1) + dgenId; // if dgenId was substituted, add the parent to the ts list if (-1 < m_id.IndexOf(dgenId)) m_ts.AddNamedInstruction(genId,parent); } else Assert.IsNotNull(id,"A DataRef has no ref prefixed with '$'. Read: "+id); }
/// <summary> /// Initialize an Instruction. /// </summary> public Instruction() { m_number = -1; m_parent = null; m_log = Logger.getOnly(); m_id = "NONE"; m_Rest = 0; // default is not to wait for execution m_tag = "NONE"; m_doneOnce = false; m_path = null; m_select = null; m_selectPath = null; }
public ApplicationContext() { m_tag = "on-application"; m_source = null; m_app = null; m_run = null; m_title = null; m_exeName = null; m_GuiModel = null; m_GuiModelPath = null; m_close = false; m_args = null; m_work = null; m_gui = null; m_model_root = null; // get the model root if there is one }
/// <summary> /// Adds an instruction to this context immediately after the one referenced. /// </summary> /// <param name="afterThis">The instruction to add ins after.</param> /// <param name="ins">The instruction to add.</param> public void Add(Instruction afterThis, Instruction ins) { m_log.isNotNull(afterThis, base.makeNameTag() + " Tried to reference a null instruction"); m_log.isNotNull(ins, base.makeNameTag() + " Tried to add a null instruction"); m_instructions.Insert(m_instructions.IndexOf(afterThis)+1, ins); }
/// <summary> /// Adds an instruction to this context. /// </summary> /// <param name="ins">The instruction to add.</param> public void Add(Instruction ins) { m_log.isNotNull(ins, base.makeNameTag() + " Tried to add a null instruction"); m_instructions.Add(ins); }
/// <summary> /// Determines if an instruction has an id. If it does, it adds to the named instruction list. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="ins">The instruction to be checked</param> static void CheckForId(XmlNode xn, Instruction ins) { XmlAttribute xa = xn.Attributes["id"]; if (xa != null) { TestState.getOnly().AddNamedInstruction(xa.Value, ins); ins.Id = xa.Value; } }
/// <summary> /// Adds an instruction to the growing tree, sets the log level /// and records it to the log. /// </summary> /// <param name="xn">An element node</param> /// <param name="ins">The instruction to be added</param> /// <param name="con">The current context object</param> static private void AddInstruction(XmlNode xn, Instruction ins, Context con) { // Vars put themselves on ts, making sure there is only one ins.Element = (XmlElement)xn; if (xn.Name != "var") CheckForId(xn, ins); // If not a new one, make sure the model node is propagated to each child context if (ins is Context && con.ModelNode != null) ((Context)ins).ModelNode = con.ModelNode; ins.Parent = con; con.Add(ins); string logLevel = XmlFiler.getAttribute(xn, "log"); if (logLevel != null && "all" == logLevel) ins.LogLevel = 1; if (logLevel != null && "time" == logLevel) ins.LogLevel = 2; // add one to the instruction count, then assign it to the instruction // A context might already have a number //if (ins.Number == -1) ins.Number = TestState.getOnly().IncInstructionCount; //Logger.getOnly().mark(ins); // log the progress of interpretation }
/// <summary> /// Simple results are logged via this empty report element. /// More complex ones use the other logging methods. /// This uses the resultImage() method from the instruction. /// This is typically called after mark(). /// </summary> /// <param name="ins">An instruction</param> public void result(Instruction ins) { if (!s_isClosed) { if (!m_init) initLog(); m_sw.WriteLine(@" <result {0}/>", ins.resultImage()); m_sw.Flush(); } }
/// <summary> /// Create an empty element in the log using the image() method /// on an instruction. This is invoked from Instruction.Execute /// to insure each instruction is marked at some point before or /// during its execution. The image() methods report the state of /// the instruction, including some internal class members for /// debugging. /// </summary> /// <param name="ins">An instruction</param> public void mark(Instruction ins) { if (!s_isClosed) { if (!m_init) initLog(); m_sw.WriteLine(@" <{0}/>", ins.image()); m_sw.Flush(); } }
/// <summary> /// Adds a sound or beep instruction to the message. /// It is played when the sound is read. /// </summary> /// <param name="ins">The sound or beep instruction.</param> public void AddSound(Instruction ins) { int index = m_Body.Add(ins); }
/// <summary> /// Adds a DataRef to the message using the parent if the id is null. /// </summary> /// <param name="id">Instruction name or id, can be null</param> /// <param name="name">Name of the data item, can be null</param> /// <param name="parent">Parent instruction of this DataRef</param> public void AddDataRef(string id, Instruction parent) { DataRef dref = new DataRef(id, parent); int index = m_Body.Add(dref); }
/// <summary> /// Add a named instruction to the pool to be retrieved by calling "Instruction". /// </summary> /// <param name="name">The id of the instruction.</param> /// <param name="ins">The instruction called by name.</param> public void AddNamedInstruction(string name, Instruction ins) { m_htNamedInstructions.Add(name, ins); }
public void SetSource(string name) { // It has to be the name of another on-application element already encountered. TestState ts = TestState.getOnly(); Instruction insSource = ts.Instruction(name); m_log.isTrue(insSource != null, "Source is null."); m_log.isTrue(insSource is OnApplication, "Source is not an on-application instruction."); // eventually or other types. m_source = insSource; }
/// <summary> /// Read instruction file. /// Interpret script nodes according to tne instruction file. /// Make the class but don't process its child instructions if any. /// Don't execute the instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> /// <returns>Returns an unexecuted instruction or null</returns> static public Instruction MakeShell(XmlNode xn, Context con) { Logger.getOnly().isNotNull(xn, "Instruction can't be created from nothing!"); if (m_actPrototypes == null) { Logger.getOnly().fail("Can not create: No instruction prototypes loaded."); return null; } Instruction FluffedInstruction = null; // number the context if it doesn't have one yet to avoid depth-first numbering. if (con != null && con.Number == -1) con.Number = TestState.getOnly().IncInstructionCount; // figure out what to do with this node switch (xn.Name) { case "#comment": // ignore comments, etc.. case "#significant-whitespace": case "#whitespace": case "#text": break; default: // Find the instruction prototype based on node name. InsPrototype prototype = findPrototype(xn.Name, m_actPrototypes); if (prototype != null) { var AtValues = new ArrayList(); ArrayList atts = prototype.Attributes; Logger.getOnly().startList("Instruction " + prototype.Name); XmlAttributeCollection atNodes = xn.Attributes; if (atNodes != null && atts != null) { foreach (XmlAttribute atx in atNodes) { // find each attribute in the prototype string atValue = null; foreach (Attribute at in atts) { if (at.Name == atx.Name) { // its this one atValue = XmlFiler.getAttribute(xn, at.Name); if (atValue != null && at.Name != "log") { // log is dealt with in AddInstruction() var atVar = new Attribute(at.Name, atValue, at.Value); AtValues.Add(atVar); Logger.getOnly().listItem(" " + atx.Name + "=" + atValue); break; } } } if (atValue == null) { // This attribute is not expected: make it a variable // Add it as a var instruction so it gets bound at the right time // Use <var id="atx.Name" set="atValue"/> var var = new Var(); var.Id = atx.Name; var.Set = XmlFiler.getAttribute(xn, atx.Name); // Add the var to the growing list of instructions AddInstruction(xn, var, con); Logger.getOnly().paragraph("Added <var id=\"" + var.Id + "\" set=\"" + var.Set + "\"/>"); } } } Logger.getOnly().endList(); // Create the instruction using prototype.Name, AtValues.Name and AtValues.Value string protoName = XmlNameToCName(prototype.Name); string protoNameQ = prefix + protoName; Assembly assem = Assembly.GetExecutingAssembly(); // All instruction classes must have empty constructors Object protoInstruction = null; try { protoInstruction = assem.CreateInstance(protoNameQ, true, BindingFlags.CreateInstance, null, null, null, null);} catch (Exception e) { Logger.getOnly().fail("Instruction " + protoName + " not created: " + e.Message); } Logger.getOnly().isNotNull(protoInstruction, "Instruction " + protoName + " is DOA"); FluffedInstruction = (Instruction)protoInstruction; foreach (Attribute at in AtValues) { // Call each setter to set the instruction properties. int number = 0; UInt32 unsigned = 0; string primative = "string"; if (at.Type == "msec" || at.Type == "int" || at.Type.Contains("[0-10]")) { try { number = Convert.ToInt32(at.Value); primative = "int"; } catch (FormatException) { } } if (at.Type == "m-sec" || at.Type == "hz") { try { unsigned = Convert.ToUInt32(at.Value, 10); primative = "UInt32"; } catch (FormatException) { } } if (primative == "string" && at.Type.Contains("|")) { string[] enumList = makeEnumList(at.Type); foreach (string value in enumList) { if (value == at.Value) { primative = value; break; } } if (primative == "string") Logger.getOnly().fail("Invalid enum {" + at.Value + "} for " + protoNameQ + "." + at.Name + "(" + at.Type + ")"); } string propName = XmlNameToCName(at.Name); string propNameQ = protoNameQ + "." + XmlNameToCName(at.Name); PropertyInfo pi = null; MethodInfo m = null; try { if (primative == "int") { pi = assem.GetType(protoNameQ).GetProperty(propName, typeof(int)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { number }); } else if (primative == "UInt32") { pi = assem.GetType(protoNameQ).GetProperty(propName, typeof(UInt32)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { unsigned }); } else { Type t = assem.GetType(protoNameQ); pi = t.GetProperty(propName, typeof(string)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { at.Value }); } } catch { Logger.getOnly().fail(" Can't find setter: " + protoNameQ + "." + propName + "(" + at.Type + ") using value {" + at.Value + "}"); } if (at.Name == "id" && protoName != "Var") TestState.getOnly().AddNamedInstruction(at.Value, FluffedInstruction); } // end of process attributes // Call the finishCreation method FluffedInstruction.finishCreation(xn, con); //if (prototype.Name != "if" && // prototype.Name != "then" && prototype.Name != "else") // Add the instruction to the growing list of instructions AddInstruction(xn, FluffedInstruction, con); } else { bool unknown = true; if (m_pasPrototypes != null) { InsPrototype IgnoredPrototype = findPrototype(xn.Name, m_pasPrototypes); if (IgnoredPrototype != null) unknown = false; } if (unknown) Logger.getOnly().fail("Can't make <" + xn.Name + "> instruction"); } break; } return FluffedInstruction; }
/// <summary> /// Adds an instruction to this context immediately after the one referenced. /// </summary> /// <param name="afterThis">The instruction to add ins after.</param> /// <param name="ins">The instruction to add.</param> public void Add(Instruction afterThis, Instruction ins) { isNotNull(afterThis, base.makeName() + " Tried to reference a null instruction"); isNotNull(ins, base.makeName() + " Tried to add a null instruction"); m_components.Insert(m_components.IndexOf(afterThis)+1, ins); }
/// <summary> /// Adds an instruction to this context. /// </summary> /// <param name="ins">The instruction to add.</param> public void Add(Instruction ins) { isNotNull(ins, base.makeName()+" Tried to add a null instruction"); m_components.Add(ins); }