Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    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')))
Ejemplo n.º 4
0
    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')))
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)