import sys try: from lxml import etree except ImportError: sys.stderr.write("You need the lxml python module installed. " "Preferably version 1.2.1 or later.\n" "See http://codespeak.net/lxml/\n\n") raise rules_ns_ = '{http://nouveau.freedesktop.org/}' # This really should not be here, but libxml2 does not load # attribute defaults from the Schema. rules_defaults_ = { 'reg8:type':'hex', 'reg8:access':'rw', 'reg32:type':'hex', 'reg32:access':'rw', 'array:type':'hex', 'bitfield:type':'hex', 'translation:variant':None } def load_xmlfile(fname): src = open(fname, "r") doc = etree.parse(src) src.close() return doc def load_schema(fname): return etree.XMLSchema(load_xmlfile(fname)) def getatt(elem, attrib): val = elem.get(attrib) if val is not None: return val name = "%s:%s" % ( elem.tag.replace(rules_ns_, ''), attrib ) try: val = rules_defaults_[name] except KeyError: sys.stderr.write("Default value not found for %s.\n" % name) val = None return val class RulesngHandler: def __init__(self): self._domain = "" self._idcnt = 0 def process_children(self, root): """For the given element 'root', call dispatch_elem() for its every child element and collect the return values into a list, filtering out Nones.""" outs = map(self.dispatch_elem, root.getchildren()) return filter(lambda x: x is not None, outs) def dispatch_elem(self, elem): """Determine the element type and call the proper function, returning the functions return value.""" if type(elem) == etree._Comment: return elname = elem.tag.replace(rules_ns_, "elem_").replace('-', '_') if hasattr(self, elname): return getattr(self, elname)(elem) def temp_array_name(self, oname): """Create a unique name for a temporary array. The returned name can be different on each call.""" self._idcnt += 1 name = oname.replace('/', 's') return "__%s_%03d" % (name, self._idcnt) def def_name(self, oname): """Mangle object name to create a known private name in C.""" name = oname.replace('/', 's') return "__%s_def" % name class RulesngElement: """Object to store the complete identity of a register, array or stripe from Rules-ng. Complete identity includes absolute address and full name, with applicable variants. Attributes: variants a set of variant id strings base the absolute base address, integer arrinfo list of (stride, len) tuples from arrays/stripes prefix name prefix string elem reference to the lxml element object parent reference to the parent RulesngElement object children list of references to child Rulesnglement objects containers list of container names; groups, bitsets, enums translation reference to the translation RulesngElement, or None idnum an arbitrary id number """ _id_base = 1000 def __init__(self, elem): self.variants = set() self.base = 0 self.arrinfo = [] self.prefix = "" self.elem = elem self.parent = None self.children = [] self.containers = [] self.translation = None self.idnum = RulesngElement._id_base RulesngElement._id_base += 1 def copy(self): """Create a proper semideep copy; do a deep copy, except for references to other RulesngElements.""" re = RulesngElement(self.elem) re.variants = set(self.variants) re.base = self.base re.arrinfo = list(self.arrinfo) re.prefix = self.prefix re.parent = self.parent re.children = list(self.children) re.containers = list(self.containers) re.translation = self.translation return re def getType(self): """Returns the name of the XML element as string.""" return self.elem.tag.replace(rules_ns_, '') def getAddress(self): """Returns the absolute address (related to offset attribute). """ return self.base + int(self.elem.get("offset"), 0) def getStride(self): return int(self.elem.get("stride"), 0) def getLength(self): return int(self.elem.get("length"), 0) def getName(self): """Returns the complete name with prefixes.""" myname = self.elem.get("name") if myname is not None: if myname[0] == '/': return myname[1:] return self.prefix + myname else: return self.prefix def getAtt(self, attribute): """Returns the value of the requested attribute, using Rules-ng specified defaults if the attribute is not defined in the lxml object.""" return getatt(self.elem, attribute)