def bool(text,context={}): try: # If the object decodes, the conditional is false conditional = exp.parse_conditional_inverse(text) # If the expression needs context to decode, it'll need to be able to # reference other entries, so create them here... children = [] for name, value in context.items(): children.append(sequence.Sequence(name, [], value=exp.Constant(value))) children.append(conditional) list(sequence.Sequence('', children).decode(Data())) return False except DecodeError,ex: return True
def endElement(self, name): assert self._stack[-1][0] == name (name, attrs, breaks, lineno, colno) = self._stack.pop() # We don't pop the children item until after we have called the # handler, as it may be used when creating a value reference. children = self._children[-1] length = None if attrs.has_key('length'): length = self._parse_expression(attrs['length']) entry_name = "" if attrs.has_key('name'): entry_name = attrs['name'] entry = self._handlers[name](attrs, children, entry_name, length, breaks) # Check for value constraints constraints = [] if attrs.has_key('min'): minimum = self._parse_expression(attrs['min']) constraints.append(Minimum(minimum)) if attrs.has_key('max'): maximum = self._parse_expression(attrs['max']) constraints.append(Maximum(maximum)) if attrs.has_key('expected'): expected = self._parse_expression(attrs['expected']) constraints.append(Equals(expected)) if name == 'field' and not isinstance(entry, fld.Field) and attrs.has_key('value'): # Fields that are long integers can be internally converted to # references to Sequences; we need to handle the expected values. expected = self._parse_expression(attrs['value']) constraints.append(Equals(expected)) if constraints: if isinstance(entry, ReferencedEntry): # We found a reference with constraints; create an intermediate # sequence that will have the constraints. reference = entry if not ent.is_hidden(reference.name): reference.name = '%s:' % reference.name value = self._parse_expression("${%s}" % reference.name) entry = seq.Sequence(entry_name, [reference], value=value) entry.constraints += constraints self._children.pop() if attrs.has_key('if'): # This is a 'conditional' entry; only present if the expression in # 'if' is true. To decode this, we create a choice with a 'not # present' option; this option attempts to decode first, with the # condition inverted. try: not_present = exp.parse_conditional_inverse(attrs['if']) not_present.name = 'not present:' except exp.ExpressionError, ex: raise XmlExpressionError(ex, self._filename, self.locator) assert isinstance(not_present, ent.Entry) self.lookup[not_present] = (self._filename, lineno, colno) self.lookup[entry] = (self._filename, lineno, colno) name = 'optional %s' % entry_name if entry_name else 'optional:' optional = chc.Choice(name, [not_present, entry]) entry = optional