/// <summary> /// Finds a prototype by name from a set of targets. /// </summary> /// <param name="name">The name of the prototype saught</param> /// <param name="targets">The list of possible prototypes</param> /// <returns>The prototype found or null</returns> static private InsPrototype findPrototype(string name, ArrayList targets) { InsPrototype prototype = null; foreach (InsPrototype proto in targets) { //Logger.getOnly().paragraph(proto.Name + "=?" + name); if (proto.Name == name) { prototype = proto; break; } } return prototype; }
/// <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; }