def set(self, project, sourceTag): activeInstance=self.closestVal.owner with activeInstance.lock: dstVal=self.project.getCreateSubValue(self.itemList) #dstVal=activeInstance.findCreateNamedInput(self.direction, # self.ioItemList, # sourceTag) # now we can extract the type. tp=dstVal.getType() if not isinstance(self.literal, value.Value): newVal=value.interpretLiteral(self.literal, tp, self.sourceType, project.fileList) else: newVal=self.literal if not (tp.isSubtype(newVal.getType()) or newVal.getType().isSubtype(tp) ): raise SetError( "Incompatible types in assignment: '%s' to '%s'"% (newVal.getType().getName(), tp.getName())) activeInstance.stageNamedInput(dstVal, newVal, sourceTag)
def set(self, project, sourceTag): activeInstance = self.closestVal.owner with activeInstance.lock: dstVal = self.project.getCreateSubValue(self.itemList) #dstVal=activeInstance.findCreateNamedInput(self.direction, # self.ioItemList, # sourceTag) # now we can extract the type. tp = dstVal.getType() if not isinstance(self.literal, value.Value): newVal = value.interpretLiteral(self.literal, tp, self.sourceType, project.fileList) else: newVal = self.literal if not (tp.isSubtype(newVal.getType()) or newVal.getType().isSubtype(tp)): raise SetError( "Incompatible types in assignment: '%s' to '%s'" % (newVal.getType().getName(), tp.getName())) activeInstance.stageNamedInput(dstVal, newVal, sourceTag)
def startElement(self, name, attrs): if self.valueReader is not None: self.valueReader.startElement(name, attrs) return elif self.cmdReader is not None: self.cmdReader.startElement(name, attrs) return # otherwise elif name == "function-input": # the top-level input tag if not self.isInput: raise IOReaderError("Misplaced controller-input tag", self) if attrs.has_key("version"): self.fileVersion = int(attrs.getValue("version")) else: self.fileVersion = 0 if self.fileVersion > curVersion: raise IOReaderError( "function-input is from the future (%d)" % self.fileVersion, self) elif name == "function-output": # the return top-level tag if self.isInput: raise IOReaderError("Misplaced controller-output tag", self) if attrs.has_key("version"): self.fileVersion = int(attrs.getValue("version")) else: self.fileVersion = 0 if self.fileVersion > curVersion: raise IOReaderError( "function-output is from the future (%d)" % self.fileVersion, self) elif name == "env": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced env tag", self) self.section = IOReader.env if attrs.has_key('output_dir'): self.inp.outputDir = attrs.getValue('output_dir') if attrs.has_key('persistent_dir'): self.inp.persistentDir = attrs.getValue('persistent_dir') if attrs.has_key('base_dir'): self.inp.baseDir = attrs.getValue('base_dir') elif name == "inputs": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced inputs tag", self) self.section = IOReader.inputs val = value.Value(None, vtype.recordType) self.setValueReader( value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "subnet-inputs": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced subnet-inputs tag", self) self.section = IOReader.subnetInputs val = value.Value(None, vtype.recordType) self.setValueReader( value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "outputs": if (self.section != IOReader.none): raise IOReaderError("Misplaced outputs tag", self) self.section = IOReader.outputs if self.isInput: # read it in as a value val = value.Value(None, vtype.recordType) self.setValueReader( value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "subnet-outputs": if (self.section != IOReader.none): raise IOReaderError("Misplaced subnet-outputs tag", self) self.section = IOReader.subnetOutputs if self.isInput: # read it in as a value val = value.Value(None, vtype.recordType) self.setValueReader( value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "new-instances": if (self.section != IOReader.none) or self.isInput: raise IOReaderError("Misplaced new-instances tag", self) self.section = IOReader.newInstances elif name == "new-connections": if (self.section != IOReader.none) or self.isInput: raise IOReaderError("Misplaced new-connections tag", self) self.section = IOReader.newConnections elif name == "commands": if (self.section != IOReader.none): raise IOReaderError("Misplaced commands tag", self) self.section = IOReader.cmd cancel = cpc.util.getBooleanAttribute(attrs, "cancel_prev") if cancel: if self.out is not None: self.out.cancelPrevCommands() else: raise IOReaderError("Can't cancel commands in input", self) if self.cmdReader is None: self.cmdReader = cpc.command.CommandReader() elif name == "value": if not attrs.has_key('id'): raise IOReaderError("no id for value", self) self.valueName = id = attrs.getValue("id") # TODO: handle compound types #val=value.Value(None, vtype.valueType) self.setValueReader( value.ValueReader(self.filename, None, implicitTopItem=False, allowUnknownTypes=True), name) elif name == "instance": if not attrs.has_key('id'): raise IOReaderError("instance has no id", self) if not attrs.has_key('function'): raise IOReaderError("instance has no function", self) name = attrs.getValue('id') fn = attrs.getValue('function') if self.section == IOReader.newInstances: self.out.addInstance(name, fn) else: raise IOReaderError("Misplaced instance tag", self) elif name == "connection": if not attrs.has_key('src') and not attrs.has_key('value'): raise IOReaderError("connection has no src or value", self) if not attrs.has_key('dst'): raise IOReaderError("connection has no dst", self) if self.section != IOReader.newConnections: raise IOReaderError("Misplaced connection tag", self) if attrs.has_key('src'): self.out.addConnection(attrs.getValue('src'), attrs.getValue('dst')) else: if not attrs.has_key('type'): raise IOReaderError("connection has no type", self) tpname = attrs.getValue('type') if ((tpname not in vtype.basicTypes) or vtype.basicTypes[tpname].isCompound()): raise IOReaderError( "Value connection with non-basic type %s" % tpname, self) tp = vtype.basicTypes[tpname] val = value.interpretLiteral(attrs.getValue('value'), tp) self.out.addConnection(None, attrs.getValue('dst'), val) elif name == "error": if not attrs.has_key('msg'): raise IOReaderError("Error has no message", self) self.out.setError(xml.sax.saxutils.unescape(attrs.getValue('msg'))) elif name == "warning": if not attrs.has_key('msg'): raise IOReaderError("Warning has no message", self) self.out.setWarning( xml.sax.saxutils.unescape(attrs.getValue('msg')))
def startElement(self, name, attrs): if self.valueReader is not None: self.valueReader.startElement(name, attrs) return elif self.cmdReader is not None: self.cmdReader.startElement(name, attrs) return # otherwise elif name=="function-input": # the top-level input tag if not self.isInput: raise IOReaderError("Misplaced controller-input tag", self) if attrs.has_key("version"): self.fileVersion=int(attrs.getValue("version")) else: self.fileVersion=0 if self.fileVersion > curVersion: raise IOReaderError("function-input is from the future (%d)"% self.fileVersion, self) elif name=="function-output": # the return top-level tag if self.isInput: raise IOReaderError("Misplaced controller-output tag", self) if attrs.has_key("version"): self.fileVersion=int(attrs.getValue("version")) else: self.fileVersion=0 if self.fileVersion > curVersion: raise IOReaderError("function-output is from the future (%d)"% self.fileVersion, self) elif name == "env": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced env tag", self) self.section=IOReader.env if attrs.has_key('output_dir'): self.inp.outputDir=attrs.getValue('output_dir') if attrs.has_key('persistent_dir'): self.inp.persistentDir=attrs.getValue('persistent_dir') if attrs.has_key('base_dir'): self.inp.baseDir=attrs.getValue('base_dir') elif name == "inputs": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced inputs tag", self) self.section=IOReader.inputs val=value.Value(None, vtype.recordType) self.setValueReader(value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "subnet-inputs": if (self.section != IOReader.none) or not self.isInput: raise IOReaderError("Misplaced subnet-inputs tag", self) self.section=IOReader.subnetInputs val=value.Value(None, vtype.recordType) self.setValueReader(value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "outputs": if (self.section != IOReader.none) : raise IOReaderError("Misplaced outputs tag", self) self.section=IOReader.outputs if self.isInput: # read it in as a value val=value.Value(None, vtype.recordType) self.setValueReader(value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "subnet-outputs": if (self.section != IOReader.none) : raise IOReaderError("Misplaced subnet-outputs tag", self) self.section=IOReader.subnetOutputs if self.isInput: # read it in as a value val=value.Value(None, vtype.recordType) self.setValueReader(value.ValueReader(self.filename, val, allowUnknownTypes=True), name) elif name == "new-instances": if (self.section != IOReader.none) or self.isInput: raise IOReaderError("Misplaced new-instances tag", self) self.section=IOReader.newInstances elif name == "new-connections": if (self.section != IOReader.none) or self.isInput: raise IOReaderError("Misplaced new-connections tag", self) self.section=IOReader.newConnections elif name == "commands": if (self.section != IOReader.none): raise IOReaderError("Misplaced commands tag", self) self.section=IOReader.cmd cancel=cpc.util.getBooleanAttribute(attrs,"cancel_prev") if cancel: if self.out is not None: self.out.cancelPrevCommands() else: raise IOReaderError("Can't cancel commands in input", self) if self.cmdReader is None: self.cmdReader=cpc.command.CommandReader() elif name == "value": if not attrs.has_key('id'): raise IOReaderError("no id for value", self) self.valueName=id=attrs.getValue("id") # TODO: handle compound types #val=value.Value(None, vtype.valueType) self.setValueReader(value.ValueReader(self.filename, None, implicitTopItem=False, allowUnknownTypes=True), name) elif name == "instance": if not attrs.has_key('id'): raise IOReaderError("instance has no id", self) if not attrs.has_key('function'): raise IOReaderError("instance has no function", self) name=attrs.getValue('id') fn=attrs.getValue('function') if self.section == IOReader.newInstances: self.out.addInstance(name, fn) else: raise IOReaderError("Misplaced instance tag", self) elif name == "connection": if not attrs.has_key('src') and not attrs.has_key('value'): raise IOReaderError("connection has no src or value", self) if not attrs.has_key('dst'): raise IOReaderError("connection has no dst", self) if self.section != IOReader.newConnections: raise IOReaderError("Misplaced connection tag", self) if attrs.has_key('src'): self.out.addConnection(attrs.getValue('src'), attrs.getValue('dst')) else: if not attrs.has_key('type'): raise IOReaderError("connection has no type", self) tpname=attrs.getValue('type') if ( (tpname not in vtype.basicTypes) or vtype.basicTypes[tpname].isCompound() ): raise IOReaderError( "Value connection with non-basic type %s"% tpname,self) tp=vtype.basicTypes[tpname] val=value.interpretLiteral(attrs.getValue('value'), tp) self.out.addConnection(None, attrs.getValue('dst'), val) elif name == "error": if not attrs.has_key('msg'): raise IOReaderError("Error has no message", self) self.out.setError(xml.sax.saxutils.unescape(attrs.getValue('msg'))) elif name == "warning": if not attrs.has_key('msg'): raise IOReaderError("Warning has no message", self) self.out.setWarning(xml.sax.saxutils.unescape(attrs. getValue('msg')))
def startElement(self, name, attrs): # first handle all the sub-readers if self.cmdReader is not None: self.cmdReader.startElement(name, attrs) elif self.fnInputReader is not None: self.fnInputReader.startElement(name, attrs) elif self.valueReader is not None: self.valueReader.startElement(name, attrs) elif self.descReader is not None: self.descReader.startElement(name, attrs) # and then actual elements elif name == "cpc": # top-level element if attrs.has_key('version'): self.fileVersion=int(attrs.getValue("version")) else: self.fileVersion=0 if self.fileVersion > curVersion: raise ProjectXMLError("Can't read file from the future.") elif name == "import": if not attrs.has_key('name'): raise ProjectXMLError("import has no name", self) name=keywords.fixID(attrs.getValue('name')) nimport=self.importList.get(name) if nimport is None: # we don't have it yet. Read it. nimport=self.project.importName(name) # and try again nimport=self.importList.get(name) if nimport is None: raise ProjectXMLError("Failed to import %s"%name, self) self.localImports[name] = nimport elif name == "function": if self.function is not None: raise ProjectXMLError( "function-in-function definitions not supported", self) if not attrs.has_key("type"): raise ProjectXMLError("function has no type", self) if not attrs.has_key("id"): raise ProjectXMLError("function has no id", self) fntype=attrs.getValue("type") id=keywords.fixID(attrs.getValue("id")) if fntype == "python": tsk=atomic.SimpleFunctionFunction(id, lib=self.thisImport) elif fntype == "python-extended": tsk=atomic.ExtendedFunctionFunction(id, lib=self.thisImport) elif fntype == "network": tsk=network_function.NetworkFunction(id, lib=self.thisImport) elif fntype == "external": if self.dirName is None: raise ProjectXMLError( "external function without directory", self) tsk=external.ExternalFunction(id, basedir=self.dirName, lib=self.thisImport) else: raise ProjectXMLError("function type '%s' not recognized"% (fntype), self) self.function=tsk self.functionType=fntype elif name == "type": if self.function is not None: raise ProjectXMLError( "type-in-function definitions not supported", self) if self.type is not None: raise ProjectXMLError( "type-in-type definitions not supported", self) if not attrs.has_key("id"): raise ProjectXMLError("type has no id", self) if not attrs.has_key("base"): raise ProjectXMLError("type has no base", self) name=keywords.fixID(attrs.getValue("id")) basetype=self.importList.getTypeByFullName(attrs.getValue("base"), self.thisImport) self.type=basetype.inherit(name, self.thisImport) self.typeStack.append( (self.type, None) ) if basetype.isSubtype(vtype.arrayType): if attrs.has_key("member-type"): tnm=keywords.fixID(attrs.getValue("member-type")) members=self.importList.getTypeByFullName(tnm, self.thisImport) self.type.setMembers(members) log.debug("new array(%s) type %s"%(members.name, name)) #else: # raise ProjectXMLError("Array type %s has no member type"% # name, self) elif basetype.isSubtype(vtype.dictType): if attrs.has_key("member-type"): tnm=keywords.fixID(attrs.getValue("member-type")) members=self.importList.getTypeByFullName(tnm, self.thisImport) self.type.setMembers(members) log.debug("new dict(%s) type %s"%(members.name, name)) elif basetype.isSubtype(vtype.fileType): if attrs.has_key("extension"): self.type.setExtension(attrs.getValue("extension")) if attrs.has_key("mime-type"): self.type.setExtension(attrs.getValue("mime-type")) elif name == "inputs": if self.type is not None: raise ProjectXMLError("nested inputs", self) self.ioitem="inputs" if self.instance is not None: self.type=self.instance.getInputs() self.typeStack.append( (self.type, None) ) elif self.function is not None: self.type=self.function.getInputs() self.typeStack.append( (self.type, None) ) elif self.activeInst is not None: curValue=self.activeInst.getStagedInputs() self.affectedInputAIs.add(self.activeInst) self.setValueReader(value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError("inputs without function/instance", self) elif name == "outputs": if self.type is not None: raise ProjectXMLError("nested outputs", self) self.ioitem="outputs" if self.instance is not None: self.type=self.instance.getOutputs() self.typeStack.append( (self.type, None) ) elif self.function is not None: self.type=self.function.getOutputs() self.typeStack.append( (self.type, None) ) elif self.activeInst is not None: curValue=self.activeInst.getOutputs() self.affectedOutputAIs.add(self.activeInst) self.setValueReader(value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError("outputs without function/instance", self) elif name == "subnet-inputs": if self.type is not None: raise ProjectXMLError("nested subnet-inputs", self) self.ioitem="subnet-inputs" if self.instance is not None: self.type=self.instance.getSubnetInputs() self.typeStack.append( (self.type, None) ) elif self.function is not None: self.type=self.function.getSubnetInputs() self.typeStack.append( (self.type, None) ) elif self.activeInst is not None: curValue=self.activeInst.getStagedSubnetInputs() self.affectedInputAIs.add(self.activeInst) self.setValueReader(value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError( "subnet-inputs without function/instance", self) elif name == "subnet-outputs": if self.type is not None: raise ProjectXMLError("nested subnet-outputs", self) self.ioitem="subnet-outputs" if self.instance is not None: self.type=self.instance.getSubnetOutputs() self.typeStack.append((self.type, None)) elif self.function is not None: self.type=self.function.getSubnetOutputs() self.typeStack.append((self.type, None)) elif self.activeInst is not None: curValue=self.activeInst.getSubnetOutputs() self.affectedOutputAIs.add(self.activeInst) self.setValueReader(value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError( "subnet-outputs without function/instance", self) elif name == "field": if self.type is None and self.ioitem is None: raise ProjectXMLError("Field without type context", self) if not attrs.has_key("type"): raise ProjectXMLError("No type in field", self) tpnm=keywords.fixID(attrs.getValue("type")) if self.type is not None and self.type.isCompound(): tp=self.importList.getTypeByFullName(tpnm, self.thisImport) nm=None if self.type.isSubtype(vtype.arrayType): self.type.setMembers(tp) elif self.type.isSubtype(vtype.dictType): self.type.setMembers(tp) elif self.type.isSubtype(vtype.recordType): if not attrs.has_key("id"): raise ProjectXMLError("No id in list field", self) const=cpc.util.getBooleanAttribute(attrs,"const") opt=cpc.util.getBooleanAttribute(attrs,"opt") complete=cpc.util.getBooleanAttribute(attrs, "complete") nm=keywords.fixID(attrs.getValue("id")) self.type.addMember(nm, tp, opt, const, complete) # add it to the stack self.type=tp self.typeStack.append((tp, nm)) else: raise ProjectXMLError("Non-compound type %s can't have fields"% self.type.getName(), self) elif name == "network": #if len(self.networkStack) < 1: # raise ProjectXMLError("network in network definition", self) if self.function is None: # there is no function, check whether we're in an active # network: if len(self.activeInstStack) < 1: # we're not. Get the top level if len(self.networkStack)>0: raise ProjectXMLError("network in network definition", self) self.networkStack.append(self.thisImport.getNetwork()) else: self.networkStack.append(self.activeInst.getNet()) else: # this is a function network if len(self.networkStack)>0: raise ProjectXMLError("network in network definition", self) self.networkStack.append(self.function.getSubnet()) self.network=self.networkStack[-1] elif name == "instance": if self.network is None: raise ProjectXMLError("instance without network", self) if not attrs.has_key("id"): raise ProjectXMLError("instance has no id", self) if not attrs.has_key("function"): raise ProjectXMLError("instance has no function", self) id=keywords.fixID(attrs.getValue("id")) fn=keywords.fixID(attrs.getValue('function')) func=self.importList.getFunctionByFullName(fn, self.thisImport) self.instance=instance.Instance(id, func, fn, self.thisImport) elif name == "assign": if not 'value' in attrs: raise ProjectXMLError("assign has no value", self) if not attrs.has_key('type'): raise ProjectXMLError("assign has no type", self) if not attrs.has_key('dest'): raise ProjectXMLError("assign has no destination", self) valueString=attrs.getValue('value') typestr=keywords.fixID(attrs.getValue('type')) dst=keywords.fixID(attrs.getValue('dest')) # get the type object tp=self.importList.getTypeByFullName(typestr, self.thisImport) # get the value from the type object val=active_value.ActiveValue(value.interpretLiteral(valueString,tp), tp) val.setUpdated(True) #log.debug("value is %s, %s"%(str(val), valueString)) # get the destination dstInstName,dstDir,dstItemName=(connection.splitIOName(dst, keywords.In)) cn=connection.makeInitialValue(self.network, dstInstName, dstDir, dstItemName, val) self.network.findConnectionSrcDest(cn, self.affectedInputAIs, self.affectedOutputAIs) self.network.addConnection(cn, self) elif name == "connection": if self.network is None: raise ProjectXMLError("connection without network", self) if not attrs.has_key('src') and not attrs.has_key('value'): raise ProjectXMLError("connection has no source", self) if not attrs.has_key('dest'): raise ProjectXMLError("connection has no destination", self) dst=keywords.fixID(attrs.getValue('dest')) dstInstName,dstDir,dstItemName=(connection.splitIOName(dst, None)) if attrs.has_key('src'): src=keywords.fixID(attrs.getValue('src')) # now check the source srcInstName,srcDir,srcItemName=(connection.splitIOName(src, None)) cn=connection.makeConnection(self.network, srcInstName, srcDir, srcItemName, dstInstName, dstDir, dstItemName) else: if not attrs.has_key("type"): raise ProjectXMLError("connection has no type", self) typestr=keywords.fixID(attrs.getValue('type')) valueString=attrs.getValue('value') tp=self.importList.getTypeByFullName(typestr, self.thisImport) # get the value from the type object val=value.interpretLiteral(valueString, tp) cn=connection.makeInitialValue(self.network, dstInstName, dstDir, dstItemName, val) self.network.findConnectionSrcDest(cn, self.affectedInputAIs, self.affectedOutputAIs) self.network.addConnection(cn, self) elif name=="controller": # generic items if cpc.util.getBooleanAttribute(attrs,"persistent_dir"): # a persistent scratch dir is needed log.debug("Setting persistent dir for %s"% self.function.getName()) self.function.setPersistentDir(True) if cpc.util.getBooleanAttribute(attrs,"output_dir"): log.debug("Setting output dir always on for %s"% self.function.getName()) # a run dir is needed even if there's no file output self.function.setOutputDirWithoutFiles(True) if cpc.util.getBooleanAttribute(attrs, "log"): log.debug("Turning on logging for %s"%(self.function.getName())) self.function.setLog(True) if cpc.util.getBooleanAttribute(attrs, "access_outputs"): log.debug("Controller uses current outputs for %s"% (self.function.getName())) self.function.setAccessOutputs(True) if cpc.util.getBooleanAttribute(attrs, "access_subnet_outputs"): log.debug("Controller uses current subnet outputs for %s"% (self.function.getName())) self.function.setAccessSubnetOutputs(True) # type-specific items if (self.functionType == "python" or self.functionType == "python-extended"): importName=None if attrs.has_key("import"): importName=keywords.fixID(attrs.getValue('import')) if not attrs.has_key('function'): raise ProjectXMLError("python controller has no function", self) fnName=keywords.fixID(attrs.getValue("function")) self.function.setFunction(fnName, importName) elif self.functionType == "command": pass elif self.functionType == "external": if not attrs.has_key('executable'): raise ProjectXMLError( "command controller has no executable", self) executable=attrs.getValue("executable") self.function.setExecutable(executable) self.inController=True elif name=="stdin": if self.inController and self.functionType == "command": if not attrs.has_key('value'): raise ProjectXMLError("stdin has no value", self) self.function.setStdin(attrs.getValue('value')) else: raise ProjectXMLError("stdin tag, without command controller", self) elif name=="arg": if self.inController and self.functionType == "command": pass else: raise ProjectXMLError("arg tag, without command controller", self) elif name == "active": # read in a description of an active network + active instances if not isinstance(self.network, active_network.ActiveNetwork): raise ProjectXMLError("active instance without active network", self) if not attrs.has_key("id"): raise ProjectXMLError("active instance has no id", self) if not attrs.has_key("state"): raise ProjectXMLError("active instance has no state", self) if not attrs.has_key("seqnr"): raise ProjectXMLError("active instance has no seqnr", self) name=keywords.fixID(attrs.getValue("id")) stStr=attrs.getValue("state") # now get the actual state state=None for st in active_inst.ActiveInstance.states: if st.str == stStr: state=st if state is None: raise ProjectXMLError("active instance state %s invalid"%stStr, self) seqnr=int(attrs.getValue("seqnr")) ai=self.network.getActiveInstance(name) ai.setState(state) ai.setSeqNr(seqnr) if attrs.has_key('errmsg'): ai.markError(xml.sax.saxutils.unescape(attrs. getValue('errmsg')), False) if attrs.has_key('warnmsg'): ai.setWarning(xml.sax.saxutils.unescape(attrs. getValue('warnmsg'))) if attrs.has_key('cputime'): try: ai.setCputime(float(attrs.getValue('cputime'))) except ValueError: pass self.activeInstStack.append(ai) self.activeInst=ai self.affectedInputAIs.add(ai) self.affectedOutputAIs.add(ai) elif name == "active-connection": # any value associated with active connection points if self.activeInst is None: raise ProjectXMLError( "active connection without active instance", self) if not attrs.has_key("id"): raise ProjectXMLError("active conn field has no id", self) if not attrs.has_key("type"): raise ProjectXMLError("active conn field has no type", self) tpnm=keywords.fixID(attrs.getValue("type")) tp=self.importList.getTypeByFullName(tpnm, self.thisImport) if attrs.has_key("seqnr"): seqnr=int(attrs.getValue("seqnr")) else: seqnr=0 name=keywords.fixID(attrs.getValue("id")) # TODO fix this for new type struct. val=None if attrs.has_key("value"): if not attrs.has_key("value_type"): raise ProjectXMLError( "active connection value without value_type", self) vtpnm=keywords.fixID(attrs.getValue("value_type")) vtp=self.importList.getTypeByFullName(vtpnm, self.thisImport) valnm=attrs.getValue("value") valueString=attrs.getValue('value') val=value.interpretLiteral(valueString, tp) if self.ioitem == "inputs": self.activeInst.setInput(name, tp, val, seqnr) elif self.ioitem == "outputs": self.activeInst.setOutput(name, tp, val, seqnr) elif self.ioitem == "subnet-inputs": self.activeInst.setSubnetInput(name, tp, val, seqnr) elif self.ioitem == "subnet-outputs": self.activeInst.setSubnetOutput(name, tp, val, seqnr) else: raise ProjectXMLError( "unknown active connection ioitem '%s'"% (self.ioitem), self) elif name == "tasks": pass # just ignore it; we deal with tasks when they come elif name == "task": if self.curTask is not None: raise ProjectXMLError("task within task", self) if self.activeInst is None: raise ProjectXMLError("task without active instance", self) if not attrs.has_key("seqnr"): raise ProjectXMLError("task has no seqnr", self) if not attrs.has_key("priority"): raise ProjectXMLError("task has no priority", self) priority=int(attrs.getValue("priority")) seqnr=int(attrs.getValue("seqnr")) self.curTask=task.Task(self.project, self.activeInst, self.activeInst.getFunction(), None, priority, seqnr) elif name == "function-input": if self.curTask is None: raise ProjectXMLError("function-input without task", self) inp=run.FunctionRunInput() self.setFnInputReader(run.IOReader(inp, None), name) self.fnInputReader.setReportFilename(self.filename) self.fnInputReader.startElement(name, attrs) elif name == "command-list": if self.curTask is None: raise ProjectXMLError("commands without task", self) self.cmdReader=cpc.command.CommandReader() elif name == "desc": # A description. First find out what it describes. if self.type is not None: if ( len(self.typeStack) > 1 and self.typeStack[-2][0].isSubtype(vtype.recordType)): # if it is a field, describe it as a field tp=self.typeStack[-2][0] field=self.typeStack[-1][1] lstm=tp.getRecordMember(field) self.setDescReader(description.DescriptionReader(lstm, self.filename), name) elif not self.type.isBuiltin() and len(self.typeStack)==1: # it is a custom, describable type self.setDescReader(description.DescriptionReader(self.type, self.filename), name) else: raise ProjectXMLError("description of a builtin type.", self) elif self.function is not None: self.setDescReader(description.DescriptionReader(self.function, self.filename), name) elif self.curTask is None and self.network is None: self.setDescReader(description.DescriptionReader( self.thisImport, self.filename), name) # raise ProjectXMLError("Unknown item to describe.") else: raise ProjectXMLError("Unknown tag %s"%name, self)
def startElement(self, name, attrs): # first handle all the sub-readers if self.cmdReader is not None: self.cmdReader.startElement(name, attrs) elif self.fnInputReader is not None: self.fnInputReader.startElement(name, attrs) elif self.valueReader is not None: self.valueReader.startElement(name, attrs) elif self.descReader is not None: self.descReader.startElement(name, attrs) # and then actual elements elif name == "cpc": # top-level element if attrs.has_key('version'): self.fileVersion = int(attrs.getValue("version")) else: self.fileVersion = 0 if self.fileVersion > curVersion: raise ProjectXMLError("Can't read file from the future.") elif name == "import": if not attrs.has_key('name'): raise ProjectXMLError("import has no name", self) name = keywords.fixID(attrs.getValue('name')) nimport = self.importList.get(name) if nimport is None: # we don't have it yet. Read it. nimport = self.project.importName(name) # and try again nimport = self.importList.get(name) if nimport is None: raise ProjectXMLError("Failed to import %s" % name, self) self.localImports[name] = nimport elif name == "function": if self.function is not None: raise ProjectXMLError( "function-in-function definitions not supported", self) if not attrs.has_key("type"): raise ProjectXMLError("function has no type", self) if not attrs.has_key("id"): raise ProjectXMLError("function has no id", self) fntype = attrs.getValue("type") id = keywords.fixID(attrs.getValue("id")) if fntype == "python": tsk = atomic.SimpleFunctionFunction(id, lib=self.thisImport) elif fntype == "python-extended": tsk = atomic.ExtendedFunctionFunction(id, lib=self.thisImport) elif fntype == "network": tsk = network_function.NetworkFunction(id, lib=self.thisImport) elif fntype == "external": if self.dirName is None: raise ProjectXMLError( "external function without directory", self) tsk = external.ExternalFunction(id, basedir=self.dirName, lib=self.thisImport) else: raise ProjectXMLError( "function type '%s' not recognized" % (fntype), self) self.function = tsk self.functionType = fntype elif name == "type": if self.function is not None: raise ProjectXMLError( "type-in-function definitions not supported", self) if self.type is not None: raise ProjectXMLError("type-in-type definitions not supported", self) if not attrs.has_key("id"): raise ProjectXMLError("type has no id", self) if not attrs.has_key("base"): raise ProjectXMLError("type has no base", self) name = keywords.fixID(attrs.getValue("id")) basetype = self.importList.getTypeByFullName( attrs.getValue("base"), self.thisImport) self.type = basetype.inherit(name, self.thisImport) self.typeStack.append((self.type, None)) if basetype.isSubtype(vtype.arrayType): if attrs.has_key("member-type"): tnm = keywords.fixID(attrs.getValue("member-type")) members = self.importList.getTypeByFullName( tnm, self.thisImport) self.type.setMembers(members) log.debug("new array(%s) type %s" % (members.name, name)) #else: # raise ProjectXMLError("Array type %s has no member type"% # name, self) elif basetype.isSubtype(vtype.dictType): if attrs.has_key("member-type"): tnm = keywords.fixID(attrs.getValue("member-type")) members = self.importList.getTypeByFullName( tnm, self.thisImport) self.type.setMembers(members) log.debug("new dict(%s) type %s" % (members.name, name)) elif basetype.isSubtype(vtype.fileType): if attrs.has_key("extension"): self.type.setExtension(attrs.getValue("extension")) if attrs.has_key("mime-type"): self.type.setExtension(attrs.getValue("mime-type")) elif name == "inputs": if self.type is not None: raise ProjectXMLError("nested inputs", self) self.ioitem = "inputs" if self.instance is not None: self.type = self.instance.getInputs() self.typeStack.append((self.type, None)) elif self.function is not None: self.type = self.function.getInputs() self.typeStack.append((self.type, None)) elif self.activeInst is not None: curValue = self.activeInst.getStagedInputs() self.affectedInputAIs.add(self.activeInst) self.setValueReader( value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError("inputs without function/instance", self) elif name == "outputs": if self.type is not None: raise ProjectXMLError("nested outputs", self) self.ioitem = "outputs" if self.instance is not None: self.type = self.instance.getOutputs() self.typeStack.append((self.type, None)) elif self.function is not None: self.type = self.function.getOutputs() self.typeStack.append((self.type, None)) elif self.activeInst is not None: curValue = self.activeInst.getOutputs() self.affectedOutputAIs.add(self.activeInst) self.setValueReader( value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError("outputs without function/instance", self) elif name == "subnet-inputs": if self.type is not None: raise ProjectXMLError("nested subnet-inputs", self) self.ioitem = "subnet-inputs" if self.instance is not None: self.type = self.instance.getSubnetInputs() self.typeStack.append((self.type, None)) elif self.function is not None: self.type = self.function.getSubnetInputs() self.typeStack.append((self.type, None)) elif self.activeInst is not None: curValue = self.activeInst.getStagedSubnetInputs() self.affectedInputAIs.add(self.activeInst) self.setValueReader( value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError( "subnet-inputs without function/instance", self) elif name == "subnet-outputs": if self.type is not None: raise ProjectXMLError("nested subnet-outputs", self) self.ioitem = "subnet-outputs" if self.instance is not None: self.type = self.instance.getSubnetOutputs() self.typeStack.append((self.type, None)) elif self.function is not None: self.type = self.function.getSubnetOutputs() self.typeStack.append((self.type, None)) elif self.activeInst is not None: curValue = self.activeInst.getSubnetOutputs() self.affectedOutputAIs.add(self.activeInst) self.setValueReader( value.ValueReader(self.filename, curValue, importList=self.importList, currentImport=self.thisImport, sourceTag=self), name) else: raise ProjectXMLError( "subnet-outputs without function/instance", self) elif name == "field": if self.type is None and self.ioitem is None: raise ProjectXMLError("Field without type context", self) if not attrs.has_key("type"): raise ProjectXMLError("No type in field", self) tpnm = keywords.fixID(attrs.getValue("type")) if self.type is not None and self.type.isCompound(): tp = self.importList.getTypeByFullName(tpnm, self.thisImport) nm = None if self.type.isSubtype(vtype.arrayType): self.type.setMembers(tp) elif self.type.isSubtype(vtype.dictType): self.type.setMembers(tp) elif self.type.isSubtype(vtype.recordType): if not attrs.has_key("id"): raise ProjectXMLError("No id in list field", self) const = cpc.util.getBooleanAttribute(attrs, "const") opt = cpc.util.getBooleanAttribute(attrs, "opt") complete = cpc.util.getBooleanAttribute(attrs, "complete") nm = keywords.fixID(attrs.getValue("id")) self.type.addMember(nm, tp, opt, const, complete) # add it to the stack self.type = tp self.typeStack.append((tp, nm)) else: raise ProjectXMLError( "Non-compound type %s can't have fields" % self.type.getName(), self) elif name == "network": #if len(self.networkStack) < 1: # raise ProjectXMLError("network in network definition", self) if self.function is None: # there is no function, check whether we're in an active # network: if len(self.activeInstStack) < 1: # we're not. Get the top level if len(self.networkStack) > 0: raise ProjectXMLError("network in network definition", self) self.networkStack.append(self.thisImport.getNetwork()) else: self.networkStack.append(self.activeInst.getNet()) else: # this is a function network if len(self.networkStack) > 0: raise ProjectXMLError("network in network definition", self) self.networkStack.append(self.function.getSubnet()) self.network = self.networkStack[-1] elif name == "instance": if self.network is None: raise ProjectXMLError("instance without network", self) if not attrs.has_key("id"): raise ProjectXMLError("instance has no id", self) if not attrs.has_key("function"): raise ProjectXMLError("instance has no function", self) id = keywords.fixID(attrs.getValue("id")) fn = keywords.fixID(attrs.getValue('function')) func = self.importList.getFunctionByFullName(fn, self.thisImport) self.instance = instance.Instance(id, func, fn, self.thisImport) elif name == "assign": if not 'value' in attrs: raise ProjectXMLError("assign has no value", self) if not attrs.has_key('type'): raise ProjectXMLError("assign has no type", self) if not attrs.has_key('dest'): raise ProjectXMLError("assign has no destination", self) valueString = attrs.getValue('value') typestr = keywords.fixID(attrs.getValue('type')) dst = keywords.fixID(attrs.getValue('dest')) # get the type object tp = self.importList.getTypeByFullName(typestr, self.thisImport) # get the value from the type object val = active_value.ActiveValue( value.interpretLiteral(valueString, tp), tp) val.setUpdated(True) #log.debug("value is %s, %s"%(str(val), valueString)) # get the destination dstInstName, dstDir, dstItemName = (connection.splitIOName( dst, keywords.In)) cn = connection.makeInitialValue(self.network, dstInstName, dstDir, dstItemName, val) self.network.findConnectionSrcDest(cn, self.affectedInputAIs, self.affectedOutputAIs) self.network.addConnection(cn, self) elif name == "connection": if self.network is None: raise ProjectXMLError("connection without network", self) if not attrs.has_key('src') and not attrs.has_key('value'): raise ProjectXMLError("connection has no source", self) if not attrs.has_key('dest'): raise ProjectXMLError("connection has no destination", self) dst = keywords.fixID(attrs.getValue('dest')) dstInstName, dstDir, dstItemName = (connection.splitIOName( dst, None)) if attrs.has_key('src'): src = keywords.fixID(attrs.getValue('src')) # now check the source srcInstName, srcDir, srcItemName = (connection.splitIOName( src, None)) cn = connection.makeConnection(self.network, srcInstName, srcDir, srcItemName, dstInstName, dstDir, dstItemName) else: if not attrs.has_key("type"): raise ProjectXMLError("connection has no type", self) typestr = keywords.fixID(attrs.getValue('type')) valueString = attrs.getValue('value') tp = self.importList.getTypeByFullName(typestr, self.thisImport) # get the value from the type object val = value.interpretLiteral(valueString, tp) cn = connection.makeInitialValue(self.network, dstInstName, dstDir, dstItemName, val) self.network.findConnectionSrcDest(cn, self.affectedInputAIs, self.affectedOutputAIs) self.network.addConnection(cn, self) elif name == "controller": # generic items if cpc.util.getBooleanAttribute(attrs, "persistent_dir"): # a persistent scratch dir is needed log.debug("Setting persistent dir for %s" % self.function.getName()) self.function.setPersistentDir(True) if cpc.util.getBooleanAttribute(attrs, "output_dir"): log.debug("Setting output dir always on for %s" % self.function.getName()) # a run dir is needed even if there's no file output self.function.setOutputDirWithoutFiles(True) if cpc.util.getBooleanAttribute(attrs, "log"): log.debug("Turning on logging for %s" % (self.function.getName())) self.function.setLog(True) if cpc.util.getBooleanAttribute(attrs, "access_outputs"): log.debug("Controller uses current outputs for %s" % (self.function.getName())) self.function.setAccessOutputs(True) if cpc.util.getBooleanAttribute(attrs, "access_subnet_outputs"): log.debug("Controller uses current subnet outputs for %s" % (self.function.getName())) self.function.setAccessSubnetOutputs(True) # type-specific items if (self.functionType == "python" or self.functionType == "python-extended"): importName = None if attrs.has_key("import"): importName = keywords.fixID(attrs.getValue('import')) if not attrs.has_key('function'): raise ProjectXMLError("python controller has no function", self) fnName = keywords.fixID(attrs.getValue("function")) self.function.setFunction(fnName, importName) elif self.functionType == "command": pass elif self.functionType == "external": if not attrs.has_key('executable'): raise ProjectXMLError( "command controller has no executable", self) executable = attrs.getValue("executable") self.function.setExecutable(executable) self.inController = True elif name == "stdin": if self.inController and self.functionType == "command": if not attrs.has_key('value'): raise ProjectXMLError("stdin has no value", self) self.function.setStdin(attrs.getValue('value')) else: raise ProjectXMLError("stdin tag, without command controller", self) elif name == "arg": if self.inController and self.functionType == "command": pass else: raise ProjectXMLError("arg tag, without command controller", self) elif name == "active": # read in a description of an active network + active instances if not isinstance(self.network, active_network.ActiveNetwork): raise ProjectXMLError("active instance without active network", self) if not attrs.has_key("id"): raise ProjectXMLError("active instance has no id", self) if not attrs.has_key("state"): raise ProjectXMLError("active instance has no state", self) if not attrs.has_key("seqnr"): raise ProjectXMLError("active instance has no seqnr", self) name = keywords.fixID(attrs.getValue("id")) stStr = attrs.getValue("state") # now get the actual state state = None for st in active_inst.ActiveInstance.states: if st.str == stStr: state = st if state is None: raise ProjectXMLError( "active instance state %s invalid" % stStr, self) seqnr = int(attrs.getValue("seqnr")) ai = self.network.getActiveInstance(name) ai.setState(state) ai.setSeqNr(seqnr) if attrs.has_key('errmsg'): ai.markError( xml.sax.saxutils.unescape(attrs.getValue('errmsg')), False) if attrs.has_key('warnmsg'): ai.setWarning( xml.sax.saxutils.unescape(attrs.getValue('warnmsg'))) if attrs.has_key('cputime'): try: ai.setCputime(float(attrs.getValue('cputime'))) except ValueError: pass self.activeInstStack.append(ai) self.activeInst = ai self.affectedInputAIs.add(ai) self.affectedOutputAIs.add(ai) elif name == "active-connection": # any value associated with active connection points if self.activeInst is None: raise ProjectXMLError( "active connection without active instance", self) if not attrs.has_key("id"): raise ProjectXMLError("active conn field has no id", self) if not attrs.has_key("type"): raise ProjectXMLError("active conn field has no type", self) tpnm = keywords.fixID(attrs.getValue("type")) tp = self.importList.getTypeByFullName(tpnm, self.thisImport) if attrs.has_key("seqnr"): seqnr = int(attrs.getValue("seqnr")) else: seqnr = 0 name = keywords.fixID(attrs.getValue("id")) # TODO fix this for new type struct. val = None if attrs.has_key("value"): if not attrs.has_key("value_type"): raise ProjectXMLError( "active connection value without value_type", self) vtpnm = keywords.fixID(attrs.getValue("value_type")) vtp = self.importList.getTypeByFullName(vtpnm, self.thisImport) valnm = attrs.getValue("value") valueString = attrs.getValue('value') val = value.interpretLiteral(valueString, tp) if self.ioitem == "inputs": self.activeInst.setInput(name, tp, val, seqnr) elif self.ioitem == "outputs": self.activeInst.setOutput(name, tp, val, seqnr) elif self.ioitem == "subnet-inputs": self.activeInst.setSubnetInput(name, tp, val, seqnr) elif self.ioitem == "subnet-outputs": self.activeInst.setSubnetOutput(name, tp, val, seqnr) else: raise ProjectXMLError( "unknown active connection ioitem '%s'" % (self.ioitem), self) elif name == "tasks": pass # just ignore it; we deal with tasks when they come elif name == "task": if self.curTask is not None: raise ProjectXMLError("task within task", self) if self.activeInst is None: raise ProjectXMLError("task without active instance", self) if not attrs.has_key("seqnr"): raise ProjectXMLError("task has no seqnr", self) if not attrs.has_key("priority"): raise ProjectXMLError("task has no priority", self) priority = int(attrs.getValue("priority")) seqnr = int(attrs.getValue("seqnr")) self.curTask = task.Task(self.project, self.activeInst, self.activeInst.getFunction(), None, priority, seqnr) elif name == "function-input": if self.curTask is None: raise ProjectXMLError("function-input without task", self) inp = run.FunctionRunInput() self.setFnInputReader(run.IOReader(inp, None), name) self.fnInputReader.setReportFilename(self.filename) self.fnInputReader.startElement(name, attrs) elif name == "command-list": if self.curTask is None: raise ProjectXMLError("commands without task", self) self.cmdReader = cpc.command.CommandReader() elif name == "desc": # A description. First find out what it describes. if self.type is not None: if (len(self.typeStack) > 1 and self.typeStack[-2][0].isSubtype(vtype.recordType)): # if it is a field, describe it as a field tp = self.typeStack[-2][0] field = self.typeStack[-1][1] lstm = tp.getRecordMember(field) self.setDescReader( description.DescriptionReader(lstm, self.filename), name) elif not self.type.isBuiltin() and len(self.typeStack) == 1: # it is a custom, describable type self.setDescReader( description.DescriptionReader(self.type, self.filename), name) else: raise ProjectXMLError("description of a builtin type.", self) elif self.function is not None: self.setDescReader( description.DescriptionReader(self.function, self.filename), name) elif self.curTask is None and self.network is None: self.setDescReader( description.DescriptionReader(self.thisImport, self.filename), name) # raise ProjectXMLError("Unknown item to describe.") else: raise ProjectXMLError("Unknown tag %s" % name, self)