From: <nou...@li...> - 2007-04-09 11:32:03
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: staticdbgen.py Log Message: Use the same command line interface as headergen.py does. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/staticdbgen.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -3 -r1.1.1.1 -r1.2 --- staticdbgen.py 9 Apr 2007 10:52:26 -0000 1.1.1.1 +++ staticdbgen.py 9 Apr 2007 11:32:03 -0000 1.2 @@ -1,7 +1,8 @@ -from lxml import etree +#!/usr/bin/python + from rulesng import * import sys - +import getopt class Cwriter(RulesngHandler): @@ -47,6 +48,14 @@ # ----------------------------------------------- + def __init__(self): + RulesngHandler.__init__(self) + # the default output is stdout + self.outsock = sys.stdout + + def out(self, msg): + self.outsock.write(msg + "\n") + # These are the XML element handlers. # First print an array in C containing all children of the node. # Then return a tuple with the element anem and the structure @@ -68,12 +77,12 @@ name = elem.get("name") arrname = self.temp_array_name(name) vals = self.process_children(elem) - print "static struct elem_value %s[] =\n{" % arrname - for t, v in vals: print "\t%s," % v - print "};" - print "static struct elem_enum %s = " \ + self.out("static struct elem_value %s[] =\n{" % arrname) + for t, v in vals: self.out("\t%s," % v) + self.out("};") + self.out( "static struct elem_enum %s = " \ "{ .name = \"%s\",\t.values = %s,\t.len = %d };\n" % \ - (self.def_name(name), name, arrname, len(vals)) + (self.def_name(name), name, arrname, len(vals)) ) return None def elem_bitfield(self, elem): @@ -81,11 +90,11 @@ vals = self.process_children(elem) if len(vals) > 0: arrname = self.temp_array_name(name) - print "static struct uni_value %s[] =\n{" % arrname + self.out("static struct uni_value %s[] =\n{" % arrname) for t, v in vals: - print "\t{ .itype = %s,\t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};\n" + self.out( "\t{ .itype = %s,\t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};\n") else: arrname = "NULL" shr = int(elem.get("low")) @@ -102,12 +111,12 @@ name = elem.get("name") arrname = self.temp_array_name(name) vals = self.process_children(elem) - print "static struct elem_bitfield %s[] =\n{" % arrname - for t, v in vals: print "\t%s," % v - print "};" - print "static struct elem_bitset %s = " \ + self.out("static struct elem_bitfield %s[] =\n{" % arrname) + for t, v in vals: self.out("\t%s," % v) + self.out("};") + self.out( "static struct elem_bitset %s = " \ "{ .name = \"%s\",\t.fields = %s,\t.len = %d };\n" % \ - (self.def_name(name), name, arrname, len(vals)) + (self.def_name(name), name, arrname, len(vals)) ) return None def elem_reg8(self, elem): @@ -127,11 +136,12 @@ stype = 'uni_bitfield' ctype = 'REGISTER_BITFIELDS' field = '.u.bitfields' - print "static struct %s %s[] =\n{" % (stype, arrname) + self.out( "static struct %s %s[] =\n{" % ( + stype, arrname) ) for t, v in vals: - print "\t{ .itype = %s,\t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};\n" + self.out( "\t{ .itype = %s,\t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};\n") else: arrname = "NULL" ctype = 'REGISTER_VALUES' @@ -155,11 +165,12 @@ vals = self.process_children(elem) if len(vals) > 0: arrname = self.temp_array_name(name) - print "static struct uni_register %s[] =\n{" % arrname + self.out( "static struct uni_register %s[] =\n{" % + arrname ) for t, v in vals: - print "\t{ .itype = %s, \t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};" + self.out( "\t{ .itype = %s, \t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};") else: arrname = "NULL" code = "{ .name = %s, .offset = %s, .stride = %s, "\ @@ -181,11 +192,12 @@ vals = self.process_children(elem) if len(vals) > 0: arrname = self.temp_array_name(name) - print "static struct uni_register %s[] =\n{" % arrname + self.out( "static struct uni_register %s[] =\n{" % + arrname ) for t, v in vals: - print "\t{ .itype = %s, \t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};" + self.out( "\t{ .itype = %s, \t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};") else: arrname = "NULL" code = "{ .name = %s, .offset = %s, .stride = %s, "\ @@ -200,11 +212,11 @@ doma = elem.get("domain") arrname = self.temp_array_name(doma) vals = self.process_children(elem) - print "static struct uni_register %s[] =\n{" % arrname + self.out("static struct uni_register %s[] =\n{" % arrname) for t, v in vals: - print "\t{ .itype = %s, \t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};" + self.out( "\t{ .itype = %s, \t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};") variant = elem.get("variant") if variant is None: variant = "NULL" @@ -219,14 +231,14 @@ name = elem.get("name") arrname = self.temp_array_name(name) vals = self.process_children(elem) - print "static struct uni_register %s[] =\n{" % arrname + self.out("static struct uni_register %s[] =\n{" % arrname) for t, v in vals: - print "\t{ .itype = %s, \t%s = %s }," % ( - self.itypes[t], self.fields[t], v) - print "};" - print "static struct elem_group %s = " \ + self.out( "\t{ .itype = %s, \t%s = %s }," % ( + self.itypes[t], self.fields[t], v) ) + self.out("};") + self.out( "static struct elem_group %s = " \ "{ .name = \"%s\",\t.regs = %s,\t.len = %d };\n" % \ - (self.def_name(name), name, arrname, len(vals)) + (self.def_name(name), name, arrname, len(vals)) ) return None def elem_use_enum(self, elem): @@ -245,7 +257,7 @@ vals = self.process_children(elem) if len(vals) > 0: arrname = self.temp_array_name("variant") - print "static struct uni_decl %s[] = \n{" % arrname + self.out("static struct uni_decl %s[] = \n{" % arrname) for t, v in vals: if t == "variant": itype = "UNI_DECL_VARIANT" @@ -255,25 +267,26 @@ itype = "UNI_DECL_REG" field = ".u.reg" decl = "{ .itype = %s, %s = %s }" % ( - self.itypes[t], self.fields[t], v ) - print "\t{ .itype = %s, %s = %s }," % ( - itype, field, decl) - print "};" + self.itypes[t], + self.fields[t], v ) + self.out( "\t{ .itype = %s, %s = %s }," % ( + itype, field, decl) ) + self.out("};") else: arrname = "NULL" - print ("static const char * const %s[] = { " % idname) + \ - ", ".join(idlist) + ", NULL };\n" + self.out( ("static const char * const %s[] = { " % idname) + \ + ", ".join(idlist) + ", NULL };\n" ) code = "{ .id = %s, .decls = %s, "\ ".len = %d }" % (idname, arrname, len(vals) ) return ("variant", code) def elem_database(self, elem): - print "/* This file has been generated from a rules-ng "\ - "database.\n * DO NOT EDIT! */\n\n"\ - "#include \"rulesng.h\"\n" + self.out( "/* This file has been generated from a rules-ng " + "database.\n * DO NOT EDIT! */\n\n" + "#include \"rulesng.h\"\n" ) vals = self.process_children(elem) arrname = self.temp_array_name("database") - print "static struct uni_decl %s[] =\n{" % arrname + self.out("static struct uni_decl %s[] =\n{" % arrname) for t, v in vals: if t == "variant": itype = "UNI_DECL_VARIANT" @@ -284,21 +297,72 @@ field = ".u.reg" decl = "{ .itype = %s, %s = %s }" % ( self.itypes[t], self.fields[t], v ) - print "\t{ .itype = %s, %s = %s }," % ( - itype, field, decl) - print "};" - print "struct elem_database database_%s = { .domain = \"%s\""\ - ", .decls = %s, .len = %d };\n" % ( - self._domain, self._domain, arrname, len(vals) ) + self.out( "\t{ .itype = %s, %s = %s }," % ( + itype, field, decl) ) + self.out("};") + self.out( "struct elem_database database_%s = { " + ".domain = \"%s\", .decls = %s, .len = %d };\n" % ( + self._domain, self._domain, arrname, len(vals)) ) return None -schema = load_schema("rules-ng.xsd") -db = load_xmlfile("test.xml") -schema.assertValid(db) +def eprint(msg): + sys.stderr.write(msg + "\n") + +def usage(): + return "Usage: %s [options] inputfile\n" \ + "inputfile must be a valid rules-ng XML file.\n" \ + "Options:\n" \ + " -h, --help\n" \ + " \tDescription and this help.\n\n" \ + " -s, --schema sfile\n" \ + " \tUse rules-ng schema sfile.\n\n" \ + " -o, --output file\n" \ + " \tOutput to file.\n" % sys.argv[0] + + +def main(argv): + try: + opts, args = getopt.getopt(argv, 'hs:o:', + ['help', 'schema=', 'output=']) + except getopt.GetoptError: + eprint(usage()) + sys.exit(2) + + schemafile = "rules-ng.xsd" + outfile = None + + for opt, arg in opts: + if opt in ('-h', '--help'): + print usage() + print "This program is for converting a rules-ng " \ + "style database (XML) into\n" \ + "static constructs in C language for quick " \ + "built-in access\n" \ + "in various tools." + sys.exit() + elif opt in ('-s', '--schema'): + schemafile = arg + elif opt in ('-o', '--output'): + outfile = arg + + if len(args) != 1: + eprint("Error: exactly one file argument required.\n") + sys.exit(2) + + schema = load_schema(schemafile) + db = load_xmlfile(args[0]) + schema.assertValid(db) + + root = db.getroot() + + writer = Cwriter() + if outfile is not None: + writer.outsock = open(outfile, "w") + writer.dispatch_elem(root) + -root = db.getroot() -cw = Cwriter() +if __name__ == "__main__": + main(sys.argv[1:]) -cw.dispatch_elem(root) |
From: <nou...@li...> - 2007-04-09 11:32:40
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: Forgot to call parent class init. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -3 -r1.1.1.1 -r1.2 --- headergen.py 9 Apr 2007 10:52:26 -0000 1.1.1.1 +++ headergen.py 9 Apr 2007 11:32:37 -0000 1.2 @@ -35,6 +35,8 @@ def __init__(self, table): """As parameter, provide the dictionary collected by class Collector, so that <use-foo> elements can work.""" + + RulesngHandler.__init__(self) self.table = table # This is the 'search context' stack. The current context |
From: <nou...@li...> - 2007-04-15 08:41:38
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: staticdbgen.py Log Message: Framework for implementing translation processing: Added field key_offset into struct elem_translation. Added structures for collecting several databases into a list, containing persistent database state, i.e., the translation state. Translation states are stored in a hash table for each database. Couple related helper routines. Search entry call API changed. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/staticdbgen.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- staticdbgen.py 9 Apr 2007 11:32:03 -0000 1.2 +++ staticdbgen.py 15 Apr 2007 08:41:36 -0000 1.3 @@ -222,9 +222,11 @@ variant = "NULL" else: variant = '"%s"' % variant - code = "{ .domain = \"%s\", .variant = %s, .regs = %s, "\ - ".len = %d }" % ( - doma, variant, arrname, len(vals) ) + key_offset = filter(lambda x: x.get("type") == 'offset', + elem.getchildren() )[0].get("offset") + code = "{ .domain = \"%s\", .variant = %s, .key_offset = %s,"\ + " .regs = %s, .len = %d }" % ( + doma, variant, key_offset, arrname, len(vals) ) return ('translation', code) def elem_group(self, elem): |
From: <nou...@li...> - 2007-04-15 11:54:16
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: staticdbgen.py Log Message: Add autoincrementing and unknown reg8/reg32 value types. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/staticdbgen.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- staticdbgen.py 15 Apr 2007 08:41:36 -0000 1.3 +++ staticdbgen.py 15 Apr 2007 11:53:47 -0000 1.4 @@ -37,7 +37,8 @@ 'int':'VALUE_INT', 'uint':'VALUE_UINT', 'real':'VALUE_REAL', - 'offset':'VALUE_OFFSET' + 'offset':'VALUE_OFFSET', + 'autoinc':'VALUE_AUTOINC' } accesses = { @@ -146,11 +147,17 @@ arrname = "NULL" ctype = 'REGISTER_VALUES' field = '.u.values' + + try: + vtype = self.valtypes[getatt(elem, "type")] + except KeyError: + vtype = "VALUE_UNKNOWN" + code = "{ .name = \"%s\", .offset = %s, .vtype = %s, "\ ".access = %s, "\ ".content_type = %s, %s = %s, .len = %d }" % ( name, elem.get("offset"), - self.valtypes[getatt(elem, "type")], + vtype, self.accesses[getatt(elem, "access")], ctype, field, arrname, len(vals) ) return ('reg32', code) |
From: <nou...@li...> - 2007-04-15 15:59:53
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: Forgot to call parent class init. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- headergen.py 9 Apr 2007 11:32:37 -0000 1.2 +++ headergen.py 15 Apr 2007 15:59:54 -0000 1.3 @@ -12,6 +12,7 @@ elements into a dictionary""" def __init__(self): + RulesngHandler.__init__(self) self.table = {} def elem_enum(self, elem): |
From: <nou...@li...> - 2007-04-15 16:02:44
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: staticdbgen.py Log Message: Preliminary work for implementing bitfield processing in staticdb: Changed static database structures; elem_bitset and uni_bitfield structures are gone. Replaced by ordered arrays of pointers to elem_bitfield structures. Changed the elem_bitfield structure. Added bitfield test cases to test.xml. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/staticdbgen.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- staticdbgen.py 15 Apr 2007 11:53:47 -0000 1.4 +++ staticdbgen.py 15 Apr 2007 16:02:14 -0000 1.5 @@ -51,6 +51,9 @@ def __init__(self): RulesngHandler.__init__(self) + # dictionary of bitfield address dictionaries, indexed by + # bitset name + self.bitsets = {}; # the default output is stdout self.outsock = sys.stdout @@ -98,26 +101,35 @@ self.out("};\n") else: arrname = "NULL" - shr = int(elem.get("low")) + lbit = int(elem.get("low")) hbit = int(elem.get("high")) - mask = 2**(hbit+1) - 2**shr - code = "{ .name = \"%s\", .mask = 0x%08x, .shr = %d, "\ + code = "{ .name = \"%s\", .high = %d, .low = %d, "\ ".vtype = %s, .values = %s, .len = %d }" % ( - name, mask, shr, + name, hbit, lbit, self.valtypes[getatt(elem, "type")], arrname, len(vals) ) - return ('bitfield', code) + return ('bitfield', code, lbit) def elem_bitset(self, elem): name = elem.get("name") arrname = self.temp_array_name(name) vals = self.process_children(elem) + + # While printing the array, collect addresses of the + # array elements to a dict based on low bit position. + self.out("static struct elem_bitfield %s[] =\n{" % arrname) - for t, v in vals: self.out("\t%s," % v) + index = 0 + bfmap = {} + for t, v, lb in vals: + bfmap[lb] = "%s[%s]" % (arrname, index) + self.out("\t%s," % v) + index += 1 self.out("};") - self.out( "static struct elem_bitset %s = " \ - "{ .name = \"%s\",\t.fields = %s,\t.len = %d };\n" % \ - (self.def_name(name), name, arrname, len(vals)) ) + + # Store our address dictionary for use on elem_reg32(). + self.bitsets[name] = bfmap + return None def elem_reg8(self, elem): @@ -127,26 +139,54 @@ def elem_reg32(self, elem): name = elem.get("name") vals = self.process_children(elem) + + # Create an array of bitfields, note the low bit positions + # and indexes. + bflist = filter(lambda x: x[0] == 'bitfield', vals) + bfmap = {} + if len(bflist) > 0: + bfarrname = self.temp_array_name(name) + self.out( "static struct elem_bitfield %s[] =\n{" % + bfarrname ) + index = 0 + for t, v, lb in bflist: + bfmap[lb] = "%s[%d]" % (bfarrname, index) + self.out( "\t%s," % v) + index += 1 + self.out("};\n") + + bslist = filter(lambda x: x[0] == 'use-bitset', vals) + for t, v in bslist: + bfmap.update(self.bitsets[v]) + if len(vals) > 0: arrname = self.temp_array_name(name) if vals[0][0] in ('value', 'use-enum'): - stype = 'uni_value' + self.out("static struct uni_value %s[] =\n{" % + arrname) + for t, v in vals: + self.out("\t{ .itype = %s,\t%s = %s }," + % (self.itypes[t], self.fields[t], v) ) ctype = 'REGISTER_VALUES' field = '.u.values' + length = len(vals) elif vals[0][0] in ('bitfield', 'use-bitset'): - stype = 'uni_bitfield' ctype = 'REGISTER_BITFIELDS' - field = '.u.bitfields' - self.out( "static struct %s %s[] =\n{" % ( - stype, arrname) ) - for t, v in vals: - self.out( "\t{ .itype = %s,\t%s = %s }," % ( - self.itypes[t], self.fields[t], v) ) + field = '.u.pbitfields' + self.out("static const struct elem_bitfield *" + " %s[] =\n{" % arrname) + bits = bfmap.keys() + bits.sort() + for k in bits: + self.out("\t&%s, /* lbit %d */" % + (bfmap[k], k) ) + length = len(bits) self.out("};\n") else: arrname = "NULL" ctype = 'REGISTER_VALUES' field = '.u.values' + length = 0 try: vtype = self.valtypes[getatt(elem, "type")] @@ -159,7 +199,7 @@ name, elem.get("offset"), vtype, self.accesses[getatt(elem, "access")], - ctype, field, arrname, len(vals) ) + ctype, field, arrname, length ) return ('reg32', code) def elem_array(self, elem): @@ -254,7 +294,7 @@ return ('use-enum', "&"+self.def_name(elem.get("ref"))) def elem_use_bitset(self, elem): - return ('use-bitset', "&"+self.def_name(elem.get("ref"))) + return ('use-bitset', elem.get("ref")) def elem_use_group(self, elem): return ('use-group', "&"+self.def_name(elem.get("ref"))) |
From: <nou...@li...> - 2007-05-06 17:22:22
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: For bitfields wider than one bit, print also shift count macro. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- headergen.py 15 Apr 2007 15:59:54 -0000 1.3 +++ headergen.py 6 May 2007 17:22:20 -0000 1.4 @@ -180,6 +180,8 @@ mask = 2**(high+1) - 2**low value = "0x%08x" % mask self.out(self.make_def(name, value) + " /*BF*/") + if high != low: + self.out(self.make_def(name+"__SHIFT", "%d" % low)) self.ctx.append( (base, strides, name + "_") ) self.process_children(elem) self.ctx.pop() |
From: <nou...@li...> - 2007-05-06 17:53:05
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: New CLI option: --type-comments Comment about a definition type is not automatically printed, but enabled via this option. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- headergen.py 6 May 2007 17:22:20 -0000 1.4 +++ headergen.py 6 May 2007 17:53:04 -0000 1.5 @@ -33,13 +33,19 @@ macrovars = [ 'i', 'j', 'k', 'l' ] - def __init__(self, table): + def __init__(self, table, options={}): """As parameter, provide the dictionary collected by class Collector, so that <use-foo> elements can work.""" RulesngHandler.__init__(self) self.table = table + # process optional features + self.options = { + 'type-comments' : False + } + self.options.update(options) + # This is the 'search context' stack. The current context # is at the top. The context is the tuple: # ( offset, array stride list, name_prefix ) @@ -131,7 +137,10 @@ name = prefix + myname if self.check_duplicate(name, offset): return - self.out(self.make_addrdef(name, offset) + " /*A*/") + addrdef = self.make_addrdef(name, offset) + if self.options['type-comments']: + addrdef += " /*A*/" + self.out(addrdef) name += "_" self.out(self.make_def(name + "_LEN", "0x%x" % length)) if not isstripe: @@ -164,7 +173,10 @@ return #if elem.text is not None and len(elem.text) > 0: # print "/* %s */" % self.trim_comment(elem.text) - self.out(self.make_addrdef(name, offset) + " /*%dR*/" % size) + addrdef = self.make_addrdef(name, offset) + if self.options['type-comments']: + addrdef += " /*%dR*/" % size + self.out(addrdef) self.ctx.append( (offset + base, strides, name + "_") ) self.process_children(elem) self.ctx.pop() @@ -179,7 +191,10 @@ else: mask = 2**(high+1) - 2**low value = "0x%08x" % mask - self.out(self.make_def(name, value) + " /*BF*/") + defstr = self.make_def(name, value) + if self.options['type-comments']: + defstr += " /*BF*/" + self.out(defstr) if high != low: self.out(self.make_def(name+"__SHIFT", "%d" % low)) self.ctx.append( (base, strides, name + "_") ) @@ -196,7 +211,10 @@ else: # the parent is a bitfield, so use the bit shift value = "(" + elem.get("value") + "<<%s)" % lowbit - self.out(self.make_def(name, value) + " /*V*/") + defstr = self.make_def(name, value) + if self.options['type-comments']: + defstr += " /*V*/" + self.out(defstr) def elem_use_bitset(self, elem): bitset = self.table["bitset"+elem.get("ref")] @@ -221,6 +239,8 @@ return "Usage: %s [options] inputfile\n" \ "inputfile must be a valid rules-ng XML file.\n" \ "Options:\n" \ + " -c, --type-comments\n" \ + " \tAfter each define, put a comment noting its type.\n" \ " -h, --help\n" \ " \tDescription and this help.\n" \ " -s, --schema sfile\n" \ @@ -231,7 +251,7 @@ def main(argv): try: - opts, args = getopt.getopt(argv, 'hs:o:', + opts, args = getopt.getopt(argv, 'chs:o:', ['help', 'schema=', 'output=']) except getopt.GetoptError: eprint(usage()) @@ -239,9 +259,12 @@ schemafile = "rules-ng.xsd" outfile = None + options = {} for opt, arg in opts: - if opt in ('-h', '--help'): + if opt in ('-c', '--type-comments'): + options['type-comments'] = True + elif opt in ('-h', '--help'): print usage() print "This program is for converting a rules-ng "\ "style database (XML) into C language\n"\ @@ -266,7 +289,7 @@ coll = Collector() coll.dispatch_elem(root) - writer = CheaderWriter(coll.table) + writer = CheaderWriter(coll.table, options) if outfile is not None: writer.outsock = open(outfile, "w") writer.dispatch_elem(root) |
From: <nou...@li...> - 2007-05-06 18:34:16
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: CLI: New long options for formatting numbers. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- headergen.py 6 May 2007 17:53:04 -0000 1.5 +++ headergen.py 6 May 2007 18:34:17 -0000 1.6 @@ -42,7 +42,10 @@ # process optional features self.options = { - 'type-comments' : False + 'type-comments' : False, + 'address-fmt' : "0x%08x", + 'value-fmt' : "0x%08x", + 'offset-fmt' : "0x%x" } self.options.update(options) @@ -87,10 +90,11 @@ """Build an address macro using current stack.""" (base, strides, prefix) = self.ctx[-1] n = len(strides) - code = "0x%08x" % (base+offset) + code = self.options['address-fmt'] % (base+offset) if n > 0: pairs = map(None, self.macrovars, strides) - terms = ["(%s)*0x%x" % (v,s) for v,s in pairs[:n] ] + terms = [("(%s)*"+self.options['offset-fmt']) % (v,s) + for v,s in pairs[:n] ] code = "(" + code + "+" + "+".join(terms) + ")" name += "(" + ",".join(self.macrovars[:n]) + ")" return self.make_def(name, code) @@ -142,10 +146,11 @@ addrdef += " /*A*/" self.out(addrdef) name += "_" - self.out(self.make_def(name + "_LEN", "0x%x" % length)) + self.out(self.make_def(name + "_LEN", + self.options['offset-fmt'] % length)) if not isstripe: self.out(self.make_def(name + "_ESIZE", - "0x%x" % stride)) + self.options['offset-fmt'] % stride)) else: name = prefix self.ctx.append( (base + offset, strides, name) ) @@ -190,7 +195,7 @@ value = "(1<<%d)" % low else: mask = 2**(high+1) - 2**low - value = "0x%08x" % mask + value = self.options['value-fmt'] % mask defstr = self.make_def(name, value) if self.options['type-comments']: defstr += " /*BF*/" @@ -246,13 +251,22 @@ " -s, --schema sfile\n" \ " \tUse rules-ng schema sfile.\n" \ " -o, --output file\n" \ - " \tOutput to file\n" % sys.argv[0] + " \tOutput to file\n" \ + "\nNumber formatting with printf format strings:\n" \ + " --address-fmt str\n" \ + " \taddresses, e.g. \"0x%%08x\"\n"\ + " --offset-fmt str\n" \ + " \toffsets, strides, e.g. \"0x%%x\"\n" \ + " --value-fmt str\n" \ + " \tbit masks, e.g. \"0x%%08x\"\n"\ + % sys.argv[0] def main(argv): try: opts, args = getopt.getopt(argv, 'chs:o:', - ['help', 'schema=', 'output=']) + ['type-comments', 'help', 'schema=', 'output=', + 'address-fmt=', 'value-fmt=', 'offset-fmt=']) except getopt.GetoptError: eprint(usage()) sys.exit(2) @@ -275,6 +289,12 @@ schemafile = arg elif opt in ('-o', '--output'): outfile = arg + elif opt == '--address-fmt': + options['address-fmt'] = arg + elif opt == '--value-fmt': + options['value-fmt'] = arg + elif opt == '--offset-fmt': + options['offset-fmt'] = arg if len(args) != 1: eprint("Error: exactly one file argument required.\n") |
From: <nou...@li...> - 2007-05-06 18:53:57
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: Add date to output. Remind me to implement --header. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -3 -r1.6 -r1.7 --- headergen.py 6 May 2007 18:34:17 -0000 1.6 +++ headergen.py 6 May 2007 18:53:52 -0000 1.7 @@ -1,6 +1,7 @@ #!/usr/bin/python from rulesng import * +from time import gmtime, strftime import sys import sre import getopt @@ -105,9 +106,11 @@ def elem_database(self, elem): self.out( - "/**************************************************\n"\ - " * Generated file - DO NOT EDIT! *\n"\ - " * Generated by headergen.py (rules-ng) *\n"\ + "/**************************************************\n" + " * Generated file - DO NOT EDIT! *\n" + " * Generated by headergen.py (rules-ng) *\n" + " * " + strftime("%Y-%m-%d %H:%M UTC", gmtime()) + + " *\n" " **************************************************/\n") self.process_children(elem) @@ -252,6 +255,8 @@ " \tUse rules-ng schema sfile.\n" \ " -o, --output file\n" \ " \tOutput to file\n" \ + " --header hfile\n" \ + " \tImplement me!\n" \ "\nNumber formatting with printf format strings:\n" \ " --address-fmt str\n" \ " \taddresses, e.g. \"0x%%08x\"\n"\ |
From: <nou...@li...> - 2007-06-22 16:07:10
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: Documentation CLI fags. Brief documentation should probably work, long documentation is not implemented. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -3 -r1.7 -r1.8 --- headergen.py 6 May 2007 18:53:52 -0000 1.7 +++ headergen.py 22 Jun 2007 16:06:48 -0000 1.8 @@ -46,7 +46,9 @@ 'type-comments' : False, 'address-fmt' : "0x%08x", 'value-fmt' : "0x%08x", - 'offset-fmt' : "0x%x" + 'offset-fmt' : "0x%x", + 'brief-doc' : False, + 'long-doc' : False } self.options.update(options) @@ -103,6 +105,19 @@ def trim_comment(self, text): return sre.sub("\\A\\s*|\\s*\\Z", "", text) + def output_brief_doc(self, elem): + if not self.options['brief-doc']: + return + bfilt = lambda x: (x.tag == rules_ns_+"brief") + belem = filter(bfilt , elem.getchildren()) + if len(belem) == 0: + return + belem = belem[0] + if belem is None or len(belem.text) < 1: + return + self.out("%s/* %s */" % (self.indent(), + self.trim_comment(belem.text)) ) + def elem_database(self, elem): self.out( @@ -112,6 +127,7 @@ " * " + strftime("%Y-%m-%d %H:%M UTC", gmtime()) + " *\n" " **************************************************/\n") + self.output_brief_doc(elem) self.process_children(elem) def elem_domain(self, elem): @@ -123,6 +139,7 @@ def elem_enum(self, elem): self.out("/* enum %s */" % elem.get("name")) + self.output_brief_doc(elem) self.process_children(elem) self.out('') @@ -140,6 +157,7 @@ stride = int(elem.get("stride"), 0) if length > 1: strides = strides + [stride] + self.output_brief_doc(elem) if myname is not None: name = prefix + myname if self.check_duplicate(name, offset): @@ -163,6 +181,7 @@ def elem_translation(self, elem): self.out("/* translation to %s */" % elem.get("domain")) + self.output_brief_doc(elem) self.process_children(elem) self.out('') @@ -179,8 +198,7 @@ n = len(strides) if self.check_duplicate(name, offset): return - #if elem.text is not None and len(elem.text) > 0: - # print "/* %s */" % self.trim_comment(elem.text) + self.output_brief_doc(elem) addrdef = self.make_addrdef(name, offset) if self.options['type-comments']: addrdef += " /*%dR*/" % size @@ -202,6 +220,7 @@ defstr = self.make_def(name, value) if self.options['type-comments']: defstr += " /*BF*/" + self.output_brief_doc(elem) self.out(defstr) if high != low: self.out(self.make_def(name+"__SHIFT", "%d" % low)) @@ -222,7 +241,9 @@ defstr = self.make_def(name, value) if self.options['type-comments']: defstr += " /*V*/" + self.output_brief_doc(elem) self.out(defstr) + self.process_children(elem) def elem_use_bitset(self, elem): bitset = self.table["bitset"+elem.get("ref")] @@ -239,6 +260,10 @@ self.process_children(group) self.out('') + def elem_doc(self, elem): + pass + #self.out("<DOC> "+elem.text) + def eprint(msg): sys.stderr.write(msg + "\n") @@ -257,6 +282,10 @@ " \tOutput to file\n" \ " --header hfile\n" \ " \tImplement me!\n" \ + " --doc-brief\n" \ + " \tInclude brief descriptions as comments\n" \ + " --doc-long\n" \ + " \tInclude long descriptions as comments (broken)\n" \ "\nNumber formatting with printf format strings:\n" \ " --address-fmt str\n" \ " \taddresses, e.g. \"0x%%08x\"\n"\ @@ -271,7 +300,8 @@ try: opts, args = getopt.getopt(argv, 'chs:o:', ['type-comments', 'help', 'schema=', 'output=', - 'address-fmt=', 'value-fmt=', 'offset-fmt=']) + 'address-fmt=', 'value-fmt=', 'offset-fmt=', + 'doc-brief', 'doc-long']) except getopt.GetoptError: eprint(usage()) sys.exit(2) @@ -300,6 +330,10 @@ options['value-fmt'] = arg elif opt == '--offset-fmt': options['offset-fmt'] = arg + elif opt == '--doc-brief': + options['brief-doc'] = True + elif opt == '--doc-long': + options['long-doc'] = True if len(args) != 1: eprint("Error: exactly one file argument required.\n") |
From: <nou...@li...> - 2007-06-24 10:23:26
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: rulesng.py Log Message: Clear error message for missing the lxml module. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/rulesng.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -3 -r1.1.1.1 -r1.2 --- rulesng.py 9 Apr 2007 10:52:26 -0000 1.1.1.1 +++ rulesng.py 24 Jun 2007 10:23:23 -0000 1.2 @@ -1,5 +1,11 @@ -from lxml import etree 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/}' |
From: <nou...@li...> - 2007-06-24 12:01:28
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py Log Message: Generating <value> names from enums was incorrect. Now the names take the proper prefix. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- headergen.py 22 Jun 2007 16:06:48 -0000 1.8 +++ headergen.py 24 Jun 2007 12:01:29 -0000 1.9 @@ -137,12 +137,6 @@ self.out("/* for variant(s) %s */" % elem.get("id")) self.process_children(elem) - def elem_enum(self, elem): - self.out("/* enum %s */" % elem.get("name")) - self.output_brief_doc(elem) - self.process_children(elem) - self.out('') - def elem_array(self, elem): self.array_like(elem, False) @@ -252,7 +246,10 @@ self.out('') def elem_use_enum(self, elem): - self.out(self.indent()+"/* uses enum %s */" % elem.get("ref")) + enum = self.table["enum"+elem.get("ref")] + self.out("/* from enum %s */" % elem.get("ref")) + self.process_children(enum) + self.out('') def elem_use_group(self, elem): group = self.table["group"+elem.get("ref")] |
From: <nou...@li...> - 2007-06-24 17:20:17
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Added Files: names2html.py Log Message: The beginnings of implementing the first HTML generator. Does not do anything yet. |
From: <nou...@li...> - 2007-07-02 12:50:26
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Started to implement data gathering, and a simple text output formatter. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- names2html.py 24 Jun 2007 17:20:20 -0000 1.1 +++ names2html.py 2 Jul 2007 12:50:24 -0000 1.2 @@ -13,7 +13,7 @@ address and full name, with applicable variants. Attributes: - variants a tuple of variant id strings + variants a set of variant id strings base the absolute base address, integer prefix name prefix string elem reference to the lxml element object @@ -24,7 +24,7 @@ """ def __init__(self, elem): - self.variants = () + self.variants = set() self.base = 0 self.prefix = "" self.elem = elem @@ -35,17 +35,17 @@ def getType(self): """Returns the name of the XML element as string.""" - return elem.tag.replace(rules_ns_, '') + return self.elem.tag.replace(rules_ns_, '') def getAddress(self): """Returns the absolute address (related to offset attribute). """ - return self.base + int(elem.get("offset"), 0) + return self.base + int(self.elem.get("offset"), 0) def getName(self): """Returns the complete name with prefixes.""" - myname = elem.get("name") + myname = self.elem.get("name") if myname is not None: return self.prefix + myname else: @@ -91,20 +91,16 @@ } self.options.update(options) - # This is the 'search context' stack. The current context - # is at the top. The context is the tuple: - # ( offset, array stride list, name_prefix ) - self.ctx = [ ( 0, [], "" ) ] - # Context stacks for different aspects - self.variants = [] - self.base = [0] - self.prefix = [""] - self.containers = [] - self.parents = [] + self.variants = [] # set + self.base = [0] # integer + self.prefix = [""] # string + self.parents = [] # RulesngElement + self.containers = [] # string (group etc. name) self.translation = [] - # dictionary for all symbols, full names + # dictionary for all symbols, keys are full names, + # values are lists of RulesngElement refs. self.symbols = {}; # the default output is stdout @@ -113,11 +109,44 @@ def out(self, msg): self.outsock.write(msg + "\n") + def addToSymbolList(self, re): + name = re.getName() + try: + lst = self.symbols[name] + # Check for duplicate names, accounting for variants + for item in lst: + ids = item.variants.intersection(re.variants) + if len(ids) > 0 or \ + ( len(item.variants) == 0 and \ + len(re.variants) == 0 ): + eprint("Warning: name %s multiply " + "defined for variants %s" + % (name, + ", ".join(ids) or "(all)") + ) + lst.append(re) + except KeyError: + self.symbols[name] = [re] + + def newRElem(self, elem): + re = RulesngElement(elem) + if len(self.variants) > 0: + re.variants = self.variants[-1] + re.base = self.base[-1] + re.prefix = self.prefix[-1] + if len(self.parents) > 0: + re.parent = self.parents[-1] + re.containers = list(self.containers) + self.addToSymbolList(re) + return re + + def elem_database(self, elem): self.process_children(elem) def elem_domain(self, elem): - self.containers.append(elem.get("name")) + #self.containers.append(elem.get("name")) + pass def elem_variant(self, elem): ids = set(elem.get("id").split(' ')) @@ -129,6 +158,97 @@ self.variants.append(ids) self.process_children(elem) self.variants.pop() + + def elem_reg32(self, elem): + re = self.newRElem(elem) + self.prefix.append(re.getName() + "_") + self.base.append(re.getAddress()) + self.parents.append(re) + re.children = flatten( self.process_children(elem) ) + self.parents.pop() + self.base.pop() + self.prefix.pop() + return re + + def elem_reg8(self, elem): + return self.elem_reg32(elem) + + def elem_array(self, elem): + pass + + def elem_stripe(self, elem): + pass + + def elem_bitfield(self, elem): + pass + + def elem_value(self, elem): + re = self.newRElem(elem) + return re + + def elem_translation(self, elem): + pass + + def elem_use_bitset(self, elem): + bitset = self.groups.bitsetTable[elem.get("ref")] + return self.process_children(bitset) + + def elem_use_enum(self, elem): + enum = self.groups.enumTable[elem.get("ref")] + return self.process_children(enum) + + def elem_use_group(self, elem): + ref = elem.get("ref") + group = self.groups.groupTable[ref] + self.containers.append(ref) + ret = self.process_children(group) + self.containers.pop() + return ret + + +class TextWriter: + """Simple printer for symbol list.""" + + def output(self, relem): + name = "out_" + relem.getType() + if hasattr(self, name): + return getattr(self, name)(relem) + + def getVarStr(self, relem): + if len(relem.variants) > 0: + lst = list(relem.variants) + lst.sort() + return ", ".join(lst) + else: + return "(all)" + + def childrenAndContainers(self, relem): + chldstr = ", ".join([x.getName() for x in relem.children]) + if chldstr: + print "\tchildren: " + chldstr + contastr = ", ".join(relem.containers) + if contastr: + print "\tcontainers: " + contastr + + def out_reg32(self, relem): + print "\t32 reg 0x%08x %s" % \ + (relem.getAddress(), + self.getVarStr(relem)) + self.childrenAndContainers(relem) + + def out_reg8(self, relem): + print "\t 8 reg 0x%08x %s" % \ + (relem.getAddress(), + self.getVarStr(relem)) + self.childrenAndContainers(relem) + + def out_value(self, relem): + print "\t value %s %s" % \ + (relem.elem.get("value"), + self.getVarStr(relem)) + print "\tfor %s" % relem.parent.getName() + self.childrenAndContainers(relem) + def eprint(msg): sys.stderr.write(msg + "\n") @@ -136,6 +256,41 @@ def usage(): return "Usage: %s [options] inputfile\n" % sys.argv[0] +def flatten(lst): + ret = [] + for i in lst: + if type(i) == list: + ret.extend(i) + else: + ret.append(i) + return ret + +def countTailMatch(lst1, lst2): + """Return the number of equivalent elements between two lists, + counting fron the end.""" + m = min(len(lst1), len(lst2)) + for i in range(1, m+1): + if lst1[-i] != lst2[-i]: + return i-1 + return m + +def combineRulesngElements(elemlist): + """Many time the same registers are included from the same groups + under many different variants. This function combines all those + different instances into single RulesngElement objects.""" + newlist = [] + for re in elemlist: + for nre in newlist: + ctm = countTailMatch(re.containers, nre.containers) + if re.getAddress() == nre.getAddress() and ctm > 0: + nre.variants.update(re.variants) + l = len(nre.containers) + del nre.containers[1:(l-ctm+1)] + break + else: + newlist.append(re) + return newlist + def main(argv): try: @@ -179,6 +334,13 @@ if outfile is not None: namecoll.outsock = open(outfile, "w") namecoll.dispatch_elem(root) + + tw = TextWriter() + for name in namecoll.symbols.keys(): + print "%s:" % name + for re in combineRulesngElements(namecoll.symbols[name]): + tw.output(re) + if __name__ == "__main__": |
From: <nou...@li...> - 2007-07-03 11:18:29
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Implement <stripe> handling without making part of the object tree. Fix combineRulesngElements() to update parent/children references properly. Add RulesngElement.copy(), which is not used. <use-bitset> and <use-enum> track properly 'containers'. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- names2html.py 2 Jul 2007 12:50:24 -0000 1.2 +++ names2html.py 3 Jul 2007 11:18:28 -0000 1.3 @@ -15,6 +15,7 @@ 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 @@ -26,6 +27,7 @@ def __init__(self, elem): self.variants = set() self.base = 0 + self.arrinfo = [] self.prefix = "" self.elem = elem self.parent = None @@ -33,6 +35,20 @@ self.containers = [] self.translation = None + 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_, '') @@ -43,6 +59,12 @@ """ 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") @@ -94,6 +116,7 @@ # Context stacks for different aspects self.variants = [] # set self.base = [0] # integer + self.arrinfo = [] # (stride, len) tuples self.prefix = [""] # string self.parents = [] # RulesngElement self.containers = [] # string (group etc. name) @@ -133,6 +156,7 @@ if len(self.variants) > 0: re.variants = self.variants[-1] re.base = self.base[-1] + re.arrinfo = list(self.arrinfo) re.prefix = self.prefix[-1] if len(self.parents) > 0: re.parent = self.parents[-1] @@ -177,7 +201,20 @@ pass def elem_stripe(self, elem): - pass + dummy = RulesngElement(elem) + dummy.base = self.base[-1] + dummy.prefix = self.prefix[-1] + nameless = elem.get("name") is None + if not nameless: + self.prefix.append(dummy.getName() + "_") + self.base.append(dummy.getAddress()) + self.arrinfo.append( (dummy.getStride(), dummy.getLength()) ) + ret = self.process_children(elem) + self.arrinfo.pop() + self.base.pop() + if not nameless: + self.prefix.pop() + return flatten(ret) def elem_bitfield(self, elem): pass @@ -190,12 +227,20 @@ pass def elem_use_bitset(self, elem): - bitset = self.groups.bitsetTable[elem.get("ref")] - return self.process_children(bitset) + ref = elem.get("ref") + bitset = self.groups.bitsetTable[ref] + self.containers.append(ref) + ret = self.process_children(bitset) + self.containers.pop() + return ret def elem_use_enum(self, elem): - enum = self.groups.enumTable[elem.get("ref")] - return self.process_children(enum) + ref = elem.get("ref") + enum = self.groups.enumTable[ref] + self.containers.append(ref) + ret = self.process_children(enum) + self.containers.pop() + return ret def elem_use_group(self, elem): ref = elem.get("ref") @@ -230,15 +275,22 @@ if contastr: print "\tcontainers: " + contastr + def addrString(self, relem): + s = "0x%08x" % relem.getAddress() + for stride, length in relem.arrinfo: + if length > 1: + s+= " + 0x%x*[0..%d]" % (stride, length-1) + return s + def out_reg32(self, relem): - print "\t32 reg 0x%08x %s" % \ - (relem.getAddress(), + print "\t32 reg %s %s" % \ + (self.addrString(relem), self.getVarStr(relem)) self.childrenAndContainers(relem) def out_reg8(self, relem): - print "\t 8 reg 0x%08x %s" % \ - (relem.getAddress(), + print "\t 8 reg %s %s" % \ + (self.addrString(relem), self.getVarStr(relem)) self.childrenAndContainers(relem) @@ -277,19 +329,31 @@ def combineRulesngElements(elemlist): """Many time the same registers are included from the same groups under many different variants. This function combines all those - different instances into single RulesngElement objects.""" + different instances into single RulesngElement objects. + + After successful processing, elemlist is modified IN PLACE.""" newlist = [] for re in elemlist: for nre in newlist: ctm = countTailMatch(re.containers, nre.containers) + # Can re be combinet into nre? if re.getAddress() == nre.getAddress() and ctm > 0: + # update variant set nre.variants.update(re.variants) + # cut containers list to only the common part l = len(nre.containers) del nre.containers[1:(l-ctm+1)] + # fix all references to the old object + for child in re.children: + child.parent = nre + if re.parent: + re.parent.child = nre break else: newlist.append(re) - return newlist + # modify elemlist in place + del elemlist[:] + elemlist.extend(newlist) def main(argv): @@ -336,9 +400,13 @@ namecoll.dispatch_elem(root) tw = TextWriter() - for name in namecoll.symbols.keys(): + keys = namecoll.symbols.keys() + keys.sort() + for name in keys: + relist = namecoll.symbols[name] + combineRulesngElements(relist) print "%s:" % name - for re in combineRulesngElements(namecoll.symbols[name]): + for re in relist: tw.output(re) |
From: <nou...@li...> - 2007-07-03 14:45:12
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Implement <array> handling, and small improvements. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- names2html.py 3 Jul 2007 11:18:28 -0000 1.3 +++ names2html.py 3 Jul 2007 14:45:10 -0000 1.4 @@ -71,7 +71,7 @@ if myname is not None: return self.prefix + myname else: - return self.prefix + "*" + return self.prefix class GroupCollector(RulesngHandler): @@ -134,19 +134,21 @@ def addToSymbolList(self, re): name = re.getName() + if len(name) == 0: + eprint("Warning: nameless symbol found.") try: lst = self.symbols[name] # Check for duplicate names, accounting for variants for item in lst: ids = item.variants.intersection(re.variants) - if len(ids) > 0 or \ - ( len(item.variants) == 0 and \ - len(re.variants) == 0 ): + if len(ids) > 0: eprint("Warning: name %s multiply " "defined for variants %s" - % (name, - ", ".join(ids) or "(all)") - ) + % (name, ", ".join(ids)) ) + if len(item.variants) == 0 and \ + len(re.variants) == 0: + eprint("Warning: name %s multiply " + "defined" % name) lst.append(re) except KeyError: self.symbols[name] = [re] @@ -198,7 +200,20 @@ return self.elem_reg32(elem) def elem_array(self, elem): - pass + re = self.newRElem(elem) + nameless = elem.get("name") is None + if not nameless: + self.prefix.append(re.getName() + "_") + self.base.append(re.getAddress()) + self.arrinfo.append( (re.getStride(), re.getLength()) ) + self.parents.append(re) + re.children = flatten(self.process_children(elem)) + self.parents.pop() + self.arrinfo.pop() + self.base.pop() + if not nameless: + self.prefix.pop() + return re def elem_stripe(self, elem): dummy = RulesngElement(elem) @@ -268,6 +283,8 @@ return "(all)" def childrenAndContainers(self, relem): + if relem.parent is not None: + print "\tparent: " + relem.parent.getName() chldstr = ", ".join([x.getName() for x in relem.children]) if chldstr: print "\tchildren: " + chldstr @@ -294,6 +311,22 @@ self.getVarStr(relem)) self.childrenAndContainers(relem) + def out_array(self, relem): + print "\tarray %s %s" % \ + (self.addrString(relem), + self.getVarStr(relem)) + print "\tstride: 0x%x, length: %d" % ( + relem.getStride(), relem.getLength()) + self.childrenAndContainers(relem) + + def out_stripe(self, relem): + print "\tstripe %s %s" % \ + (self.addrString(relem), + self.getVarStr(relem)) + print "\tstride: 0x%x, length: %d" % ( + relem.getStride(), relem.getLength()) + self.childrenAndContainers(relem) + def out_value(self, relem): print "\t value %s %s" % \ (relem.elem.get("value"), @@ -405,7 +438,7 @@ for name in keys: relist = namecoll.symbols[name] combineRulesngElements(relist) - print "%s:" % name + print "%s:" % (name or "(anonymous)") for re in relist: tw.output(re) |
From: <nou...@li...> - 2007-07-03 15:28:45
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Implement <bitfield> handling. Rework combineRulesngElements() to properly combine registers, array-likes, bitfields and values. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- names2html.py 3 Jul 2007 14:45:10 -0000 1.4 +++ names2html.py 3 Jul 2007 15:28:47 -0000 1.5 @@ -232,7 +232,13 @@ return flatten(ret) def elem_bitfield(self, elem): - pass + re = self.newRElem(elem) + self.prefix.append(re.getName() + "_") + self.parents.append(re) + re.children = flatten( self.process_children(elem) ) + self.parents.pop() + self.prefix.pop() + return re def elem_value(self, elem): re = self.newRElem(elem) @@ -306,7 +312,7 @@ self.childrenAndContainers(relem) def out_reg8(self, relem): - print "\t 8 reg %s %s" % \ + print "\t8 reg %s %s" % \ (self.addrString(relem), self.getVarStr(relem)) self.childrenAndContainers(relem) @@ -327,11 +333,16 @@ relem.getStride(), relem.getLength()) self.childrenAndContainers(relem) + def out_bitfield(self, relem): + print "\tbitfield, bits %s-%s %s" % ( + relem.elem.get("low"), relem.elem.get("high"), + self.getVarStr(relem)) + self.childrenAndContainers(relem) + def out_value(self, relem): - print "\t value %s %s" % \ + print "\tvalue %s %s" % \ (relem.elem.get("value"), self.getVarStr(relem)) - print "\tfor %s" % relem.parent.getName() self.childrenAndContainers(relem) @@ -365,23 +376,39 @@ different instances into single RulesngElement objects. After successful processing, elemlist is modified IN PLACE.""" + + addr_cmp = lambda a, b: a.getAddress() != b.getAddress() + value_cmp = lambda a, b: False + cmp_switch = { + 'reg8' : addr_cmp, + 'reg32' : addr_cmp, + 'array' : addr_cmp, + 'stripe' : addr_cmp, + 'value' : value_cmp, + 'bitfield' : value_cmp + } + newlist = [] for re in elemlist: for nre in newlist: ctm = countTailMatch(re.containers, nre.containers) - # Can re be combinet into nre? - if re.getAddress() == nre.getAddress() and ctm > 0: - # update variant set - nre.variants.update(re.variants) - # cut containers list to only the common part - l = len(nre.containers) - del nre.containers[1:(l-ctm+1)] - # fix all references to the old object - for child in re.children: - child.parent = nre - if re.parent: - re.parent.child = nre - break + # Can re be combined into nre? + if ctm == 0: + continue + if cmp_switch[re.getType()](re, nre): + continue + + # update variant set + nre.variants.update(re.variants) + # cut containers list to only the common part + l = len(nre.containers) + del nre.containers[1:(l-ctm+1)] + # fix all references to the old object + for child in re.children: + child.parent = nre + if re.parent: + re.parent.child = nre + break else: newlist.append(re) # modify elemlist in place @@ -441,6 +468,7 @@ print "%s:" % (name or "(anonymous)") for re in relist: tw.output(re) + print |
From: <nou...@li...> - 2007-07-08 11:11:42
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: combineRulesngElements(): combine only elements of the same type. newRElem(): do not call addToSymbolList() Take only register-like elements into the symbol list. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- names2html.py 3 Jul 2007 15:28:47 -0000 1.5 +++ names2html.py 8 Jul 2007 11:11:41 -0000 1.6 @@ -122,8 +122,8 @@ self.containers = [] # string (group etc. name) self.translation = [] - # dictionary for all symbols, keys are full names, - # values are lists of RulesngElement refs. + # dictionary for all register-like symbols, + # keys are full names, values are lists of RulesngElement refs. self.symbols = {}; # the default output is stdout @@ -163,7 +163,6 @@ if len(self.parents) > 0: re.parent = self.parents[-1] re.containers = list(self.containers) - self.addToSymbolList(re) return re @@ -187,6 +186,7 @@ def elem_reg32(self, elem): re = self.newRElem(elem) + self.addToSymbolList(re) self.prefix.append(re.getName() + "_") self.base.append(re.getAddress()) self.parents.append(re) @@ -201,6 +201,7 @@ def elem_array(self, elem): re = self.newRElem(elem) + self.addToSymbolList(re) nameless = elem.get("name") is None if not nameless: self.prefix.append(re.getName() + "_") @@ -216,14 +217,12 @@ return re def elem_stripe(self, elem): - dummy = RulesngElement(elem) - dummy.base = self.base[-1] - dummy.prefix = self.prefix[-1] + re = self.newRElem(elem) nameless = elem.get("name") is None if not nameless: - self.prefix.append(dummy.getName() + "_") - self.base.append(dummy.getAddress()) - self.arrinfo.append( (dummy.getStride(), dummy.getLength()) ) + self.prefix.append(re.getName() + "_") + self.base.append(re.getAddress()) + self.arrinfo.append( (re.getStride(), re.getLength()) ) ret = self.process_children(elem) self.arrinfo.pop() self.base.pop() @@ -395,6 +394,8 @@ # Can re be combined into nre? if ctm == 0: continue + if re.getType() != nre.getType(): + continue if cmp_switch[re.getType()](re, nre): continue |
From: <nou...@li...> - 2007-07-08 11:31:03
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Use out() method instead of print in TextWriter. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -3 -r1.6 -r1.7 --- names2html.py 8 Jul 2007 11:11:41 -0000 1.6 +++ names2html.py 8 Jul 2007 11:31:01 -0000 1.7 @@ -274,6 +274,12 @@ class TextWriter: """Simple printer for symbol list.""" + def __init__(self): + self.indentlevel = 1 + + def out(self, msg): + sys.stdout.write(self.indentlevel * "\t" + msg + "\n") + def output(self, relem): name = "out_" + relem.getType() if hasattr(self, name): @@ -289,13 +295,14 @@ def childrenAndContainers(self, relem): if relem.parent is not None: - print "\tparent: " + relem.parent.getName() + pname = relem.parent.getName() or "(anonymous)" + self.out("parent: %s" % pname) chldstr = ", ".join([x.getName() for x in relem.children]) if chldstr: - print "\tchildren: " + chldstr + self.out("children: %s" % chldstr) contastr = ", ".join(relem.containers) if contastr: - print "\tcontainers: " + contastr + self.out("containers: %s" % contastr) def addrString(self, relem): s = "0x%08x" % relem.getAddress() @@ -305,43 +312,38 @@ return s def out_reg32(self, relem): - print "\t32 reg %s %s" % \ - (self.addrString(relem), - self.getVarStr(relem)) + self.out("32 reg %s" % self.addrString(relem)) + self.out("variants: %s" % self.getVarStr(relem)) self.childrenAndContainers(relem) def out_reg8(self, relem): - print "\t8 reg %s %s" % \ - (self.addrString(relem), - self.getVarStr(relem)) + self.out("8 reg %s" % self.addrString(relem)) + self.out("variants: %s" % self.getVarStr(relem)) self.childrenAndContainers(relem) def out_array(self, relem): - print "\tarray %s %s" % \ - (self.addrString(relem), - self.getVarStr(relem)) - print "\tstride: 0x%x, length: %d" % ( - relem.getStride(), relem.getLength()) + self.out("array %s" % self.addrString(relem)) + self.out("variants: %s" % self.getVarStr(relem)) + self.out("stride: 0x%x, length: %d" % ( + relem.getStride(), relem.getLength())) self.childrenAndContainers(relem) def out_stripe(self, relem): - print "\tstripe %s %s" % \ - (self.addrString(relem), - self.getVarStr(relem)) - print "\tstride: 0x%x, length: %d" % ( - relem.getStride(), relem.getLength()) + self.out("stripe %s" % self.addrString(relem)) + self.out("variants: %s" % self.getVarStr(relem)) + self.out("stride: 0x%x, length: %d" % ( + relem.getStride(), relem.getLength())) self.childrenAndContainers(relem) def out_bitfield(self, relem): - print "\tbitfield, bits %s-%s %s" % ( - relem.elem.get("low"), relem.elem.get("high"), - self.getVarStr(relem)) + self.out("bitfield, bits %s-%s" % ( + relem.elem.get("low"), relem.elem.get("high")) ) + self.out("variants: %s" % self.getVarStr(relem)) self.childrenAndContainers(relem) def out_value(self, relem): - print "\tvalue %s %s" % \ - (relem.elem.get("value"), - self.getVarStr(relem)) + sel.fout("value %s %s" % relem.elem.get("value")) + self.out("variants: %s" % self.getVarStr(relem)) self.childrenAndContainers(relem) |
From: <nou...@li...> - 2007-07-08 12:21:47
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Output values and bitfields under registers. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -3 -r1.7 -r1.8 --- names2html.py 8 Jul 2007 11:31:01 -0000 1.7 +++ names2html.py 8 Jul 2007 12:21:46 -0000 1.8 @@ -275,15 +275,21 @@ """Simple printer for symbol list.""" def __init__(self): - self.indentlevel = 1 + self.indentlevel = 0 def out(self, msg): sys.stdout.write(self.indentlevel * "\t" + msg + "\n") def output(self, relem): name = "out_" + relem.getType() + self.out("%s:" % (relem.getName() or "(anonymous)")) + self.indentlevel += 1 + ret = None if hasattr(self, name): - return getattr(self, name)(relem) + ret = getattr(self, name)(relem) + self.indentlevel -= 1 + self.out("") + return ret def getVarStr(self, relem): if len(relem.variants) > 0: @@ -293,16 +299,31 @@ else: return "(all)" - def childrenAndContainers(self, relem): + def parentAndContainers(self, relem): if relem.parent is not None: pname = relem.parent.getName() or "(anonymous)" - self.out("parent: %s" % pname) - chldstr = ", ".join([x.getName() for x in relem.children]) - if chldstr: - self.out("children: %s" % chldstr) + self.out("Contained in array: %s" % pname) contastr = ", ".join(relem.containers) if contastr: - self.out("containers: %s" % contastr) + self.out("Group containers: %s" % contastr) + + def outValues(self, relem): + valfilt = lambda x: x.getType() == 'value' + vallist = filter(valfilt, relem.children) + vallist.sort(None, lambda x: int(x.elem.get("value"),0)) + if len(vallist) > 0: + self.out("Values:"); + for child in vallist: + self.out_value(child) + + def outBitfields(self, relem): + bitfilt = lambda x: x.getType() == 'bitfield' + bitlist = filter(bitfilt, relem.children) + bitlist.sort(None, lambda x: int(x.elem.get("low"),0)) + if len(bitlist) > 0: + self.out("Bitfields:"); + for child in bitlist: + self.out_bitfield(child) def addrString(self, relem): s = "0x%08x" % relem.getAddress() @@ -314,37 +335,47 @@ def out_reg32(self, relem): self.out("32 reg %s" % self.addrString(relem)) self.out("variants: %s" % self.getVarStr(relem)) - self.childrenAndContainers(relem) + self.parentAndContainers(relem) + self.outValues(relem) + self.outBitfields(relem) def out_reg8(self, relem): self.out("8 reg %s" % self.addrString(relem)) self.out("variants: %s" % self.getVarStr(relem)) - self.childrenAndContainers(relem) + self.parentAndContainers(relem) + self.outValues(relem) + self.outBitfields(relem) def out_array(self, relem): self.out("array %s" % self.addrString(relem)) self.out("variants: %s" % self.getVarStr(relem)) self.out("stride: 0x%x, length: %d" % ( relem.getStride(), relem.getLength())) - self.childrenAndContainers(relem) + self.parentAndContainers(relem) + if len(relem.children) > 0: + self.out("Contained registers:"); + self.indentlevel += 1 + for child in relem.children: + self.out(child.getName()) + self.indentlevel -= 1 def out_stripe(self, relem): self.out("stripe %s" % self.addrString(relem)) self.out("variants: %s" % self.getVarStr(relem)) self.out("stride: 0x%x, length: %d" % ( relem.getStride(), relem.getLength())) - self.childrenAndContainers(relem) + self.parentAndContainers(relem) def out_bitfield(self, relem): - self.out("bitfield, bits %s-%s" % ( + self.out("%s\tbits %2s - %2s" % (relem.getName(), relem.elem.get("low"), relem.elem.get("high")) ) - self.out("variants: %s" % self.getVarStr(relem)) - self.childrenAndContainers(relem) + self.indentlevel += 1 + self.outValues(relem) + self.indentlevel -= 1 def out_value(self, relem): - sel.fout("value %s %s" % relem.elem.get("value")) - self.out("variants: %s" % self.getVarStr(relem)) - self.childrenAndContainers(relem) + self.out("%s = %s" % (relem.getName(), + relem.elem.get("value"))) def eprint(msg): @@ -468,10 +499,8 @@ for name in keys: relist = namecoll.symbols[name] combineRulesngElements(relist) - print "%s:" % (name or "(anonymous)") for re in relist: tw.output(re) - print |
From: <nou...@li...> - 2007-07-08 19:50:55
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py Log Message: Output redirection in TextWriter. Output translation info. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- names2html.py 8 Jul 2007 12:21:46 -0000 1.8 +++ names2html.py 8 Jul 2007 19:50:57 -0000 1.9 @@ -21,7 +21,7 @@ parent reference to the parent RulesngElement object children list of references to child Rulesnglement objects containers list of container names; groups, bitsets, enums - translation translation id string, or None + translation reference to the translation RulesngElement, or None """ def __init__(self, elem): @@ -120,17 +120,13 @@ self.prefix = [""] # string self.parents = [] # RulesngElement self.containers = [] # string (group etc. name) - self.translation = [] + + # Current translation in effect + self.translation = None # dictionary for all register-like symbols, # keys are full names, values are lists of RulesngElement refs. self.symbols = {}; - - # the default output is stdout - self.outsock = sys.stdout - - def out(self, msg): - self.outsock.write(msg + "\n") def addToSymbolList(self, re): name = re.getName() @@ -163,6 +159,7 @@ if len(self.parents) > 0: re.parent = self.parents[-1] re.containers = list(self.containers) + re.translation = self.translation return re @@ -244,7 +241,11 @@ return re def elem_translation(self, elem): - pass + re = self.newRElem(elem) + self.translation = re + re.children = flatten(self.process_children(elem)) + self.translation = None + return re def elem_use_bitset(self, elem): ref = elem.get("ref") @@ -276,9 +277,15 @@ def __init__(self): self.indentlevel = 0 + self.outsock = sys.stdout + + # process optional features + self.options = { + } + #self.options.update(options) def out(self, msg): - sys.stdout.write(self.indentlevel * "\t" + msg + "\n") + self.outsock.write(self.indentlevel * "\t" + msg + "\n") def output(self, relem): name = "out_" + relem.getType() @@ -332,19 +339,28 @@ s+= " + 0x%x*[0..%d]" % (stride, length-1) return s - def out_reg32(self, relem): - self.out("32 reg %s" % self.addrString(relem)) + def outRegCommon(self, relem): + if relem.translation is not None: + tr = relem.translation.elem + vari = getatt(tr, "variant") + if vari is None: + vari = "the current variant" + else: + vari = "variant '%s'" % vari + self.out("translation to '%s' using %s." % ( + tr.get("domain"), vari)) self.out("variants: %s" % self.getVarStr(relem)) self.parentAndContainers(relem) self.outValues(relem) self.outBitfields(relem) + def out_reg32(self, relem): + self.out("32 reg %s" % self.addrString(relem)) + self.outRegCommon(relem) + def out_reg8(self, relem): self.out("8 reg %s" % self.addrString(relem)) - self.out("variants: %s" % self.getVarStr(relem)) - self.parentAndContainers(relem) - self.outValues(relem) - self.outBitfields(relem) + self.outRegCommon(relem) def out_array(self, relem): self.out("array %s" % self.addrString(relem)) @@ -489,11 +505,11 @@ coll.dispatch_elem(root) namecoll = NameCollector(coll, options) - if outfile is not None: - namecoll.outsock = open(outfile, "w") namecoll.dispatch_elem(root) tw = TextWriter() + if outfile is not None: + tw.outsock = open(outfile, "w") keys = namecoll.symbols.keys() keys.sort() for name in keys: |
From: <nou...@li...> - 2007-07-13 12:40:57
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: names2html.py rulesng.py Added Files: rulesngCollectors.py Log Message: Moved large chunks of code from names2html.py to rulesng and rulesngCollectors modules. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- names2html.py 8 Jul 2007 19:50:57 -0000 1.9 +++ names2html.py 13 Jul 2007 12:40:53 -0000 1.10 @@ -1,277 +1,13 @@ #!/usr/bin/python from rulesng import * +from rulesngCollectors import * from time import gmtime, strftime import sys import sre import getopt -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 - """ - - 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 - - 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: - return self.prefix + myname - else: - return self.prefix - - -class GroupCollector(RulesngHandler): - """Collector object only goes through the <database> element - and collects references to all <enum>, <bitset> and <group> - elements into a dictionary""" - - def __init__(self): - RulesngHandler.__init__(self) - self.enumTable = {} - self.groupTable = {} - self.bitsetTable = {} - - def elem_enum(self, elem): - self.enumTable[elem.get("name")] = elem - - def elem_group(self, elem): - self.groupTable[elem.get("name")] = elem - - def elem_bitset(self, elem): - self.bitsetTable[elem.get("name")] = elem - - def elem_database(self, elem): - self.process_children(elem) - - -class NameCollector(RulesngHandler): - """Collect all names into a dictionary.""" - - def __init__(self, groupcoll, options={}): - """As parameter, provide a reference to executed - GroupCollector object, so that <use-foo> elements can work.""" - - RulesngHandler.__init__(self) - self.groups = groupcoll - - # process optional features - self.options = { - } - self.options.update(options) - - # Context stacks for different aspects - self.variants = [] # set - self.base = [0] # integer - self.arrinfo = [] # (stride, len) tuples - self.prefix = [""] # string - self.parents = [] # RulesngElement - self.containers = [] # string (group etc. name) - - # Current translation in effect - self.translation = None - - # dictionary for all register-like symbols, - # keys are full names, values are lists of RulesngElement refs. - self.symbols = {}; - - def addToSymbolList(self, re): - name = re.getName() - if len(name) == 0: - eprint("Warning: nameless symbol found.") - try: - lst = self.symbols[name] - # Check for duplicate names, accounting for variants - for item in lst: - ids = item.variants.intersection(re.variants) - if len(ids) > 0: - eprint("Warning: name %s multiply " - "defined for variants %s" - % (name, ", ".join(ids)) ) - if len(item.variants) == 0 and \ - len(re.variants) == 0: - eprint("Warning: name %s multiply " - "defined" % name) - lst.append(re) - except KeyError: - self.symbols[name] = [re] - - def newRElem(self, elem): - re = RulesngElement(elem) - if len(self.variants) > 0: - re.variants = self.variants[-1] - re.base = self.base[-1] - re.arrinfo = list(self.arrinfo) - re.prefix = self.prefix[-1] - if len(self.parents) > 0: - re.parent = self.parents[-1] - re.containers = list(self.containers) - re.translation = self.translation - return re - - - def elem_database(self, elem): - self.process_children(elem) - - def elem_domain(self, elem): - #self.containers.append(elem.get("name")) - pass - - def elem_variant(self, elem): - ids = set(elem.get("id").split(' ')) - if len(self.variants) > 0: - valids = ids.intersection(self.variants[-1]) - if valids != ids: - eprint("variant error: " + str(ids) + - " != " + str(valids) ) - self.variants.append(ids) - self.process_children(elem) - self.variants.pop() - - def elem_reg32(self, elem): - re = self.newRElem(elem) - self.addToSymbolList(re) - self.prefix.append(re.getName() + "_") - self.base.append(re.getAddress()) - self.parents.append(re) - re.children = flatten( self.process_children(elem) ) - self.parents.pop() - self.base.pop() - self.prefix.pop() - return re - - def elem_reg8(self, elem): - return self.elem_reg32(elem) - - def elem_array(self, elem): - re = self.newRElem(elem) - self.addToSymbolList(re) - nameless = elem.get("name") is None - if not nameless: - self.prefix.append(re.getName() + "_") - self.base.append(re.getAddress()) - self.arrinfo.append( (re.getStride(), re.getLength()) ) - self.parents.append(re) - re.children = flatten(self.process_children(elem)) - self.parents.pop() - self.arrinfo.pop() - self.base.pop() - if not nameless: - self.prefix.pop() - return re - - def elem_stripe(self, elem): - re = self.newRElem(elem) - nameless = elem.get("name") is None - if not nameless: - self.prefix.append(re.getName() + "_") - self.base.append(re.getAddress()) - self.arrinfo.append( (re.getStride(), re.getLength()) ) - ret = self.process_children(elem) - self.arrinfo.pop() - self.base.pop() - if not nameless: - self.prefix.pop() - return flatten(ret) - - def elem_bitfield(self, elem): - re = self.newRElem(elem) - self.prefix.append(re.getName() + "_") - self.parents.append(re) - re.children = flatten( self.process_children(elem) ) - self.parents.pop() - self.prefix.pop() - return re - - def elem_value(self, elem): - re = self.newRElem(elem) - return re - - def elem_translation(self, elem): - re = self.newRElem(elem) - self.translation = re - re.children = flatten(self.process_children(elem)) - self.translation = None - return re - - def elem_use_bitset(self, elem): - ref = elem.get("ref") - bitset = self.groups.bitsetTable[ref] - self.containers.append(ref) - ret = self.process_children(bitset) - self.containers.pop() - return ret - - def elem_use_enum(self, elem): - ref = elem.get("ref") - enum = self.groups.enumTable[ref] - self.containers.append(ref) - ret = self.process_children(enum) - self.containers.pop() - return ret - - def elem_use_group(self, elem): - ref = elem.get("ref") - group = self.groups.groupTable[ref] - self.containers.append(ref) - ret = self.process_children(group) - self.containers.pop() - return ret - - class TextWriter: """Simple printer for symbol list.""" @@ -394,77 +130,9 @@ relem.elem.get("value"))) -def eprint(msg): - sys.stderr.write(msg + "\n") - def usage(): return "Usage: %s [options] inputfile\n" % sys.argv[0] -def flatten(lst): - ret = [] - for i in lst: - if type(i) == list: - ret.extend(i) - else: - ret.append(i) - return ret - -def countTailMatch(lst1, lst2): - """Return the number of equivalent elements between two lists, - counting fron the end.""" - m = min(len(lst1), len(lst2)) - for i in range(1, m+1): - if lst1[-i] != lst2[-i]: - return i-1 - return m - -def combineRulesngElements(elemlist): - """Many time the same registers are included from the same groups - under many different variants. This function combines all those - different instances into single RulesngElement objects. - - After successful processing, elemlist is modified IN PLACE.""" - - addr_cmp = lambda a, b: a.getAddress() != b.getAddress() - value_cmp = lambda a, b: False - cmp_switch = { - 'reg8' : addr_cmp, - 'reg32' : addr_cmp, - 'array' : addr_cmp, - 'stripe' : addr_cmp, - 'value' : value_cmp, - 'bitfield' : value_cmp - } - - newlist = [] - for re in elemlist: - for nre in newlist: - ctm = countTailMatch(re.containers, nre.containers) - # Can re be combined into nre? - if ctm == 0: - continue - if re.getType() != nre.getType(): - continue - if cmp_switch[re.getType()](re, nre): - continue - - # update variant set - nre.variants.update(re.variants) - # cut containers list to only the common part - l = len(nre.containers) - del nre.containers[1:(l-ctm+1)] - # fix all references to the old object - for child in re.children: - child.parent = nre - if re.parent: - re.parent.child = nre - break - else: - newlist.append(re) - # modify elemlist in place - del elemlist[:] - elemlist.extend(newlist) - def main(argv): try: =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/rulesng.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- rulesng.py 24 Jun 2007 10:23:23 -0000 1.2 +++ rulesng.py 13 Jul 2007 12:40:54 -0000 1.3 @@ -75,3 +75,69 @@ """Mangle object name to create a known private name in C.""" return "__%s_def" % oname + +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 + """ + + 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 + + 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: + return self.prefix + myname + else: + return self.prefix |
From: <nou...@li...> - 2007-07-13 13:36:58
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: headergen.py names2html.py rulesng.py rulesngCollectors.py Log Message: Objects that require supporting Collector objects now create them internally. API changes. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/headergen.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- headergen.py 24 Jun 2007 12:01:29 -0000 1.9 +++ headergen.py 13 Jul 2007 13:36:51 -0000 1.10 @@ -1,45 +1,24 @@ #!/usr/bin/python from rulesng import * +from rulesngCollectors import GroupCollector from time import gmtime, strftime import sys import sre import getopt -class Collector(RulesngHandler): - """Collector object only goes through the <database> element - and collects references to all <enum>, <bitset> and <group> - elements into a dictionary""" - - def __init__(self): - RulesngHandler.__init__(self) - self.table = {} - - def elem_enum(self, elem): - self.table["enum"+elem.get("name")] = elem - - def elem_group(self, elem): - self.table["group"+elem.get("name")] = elem - - def elem_bitset(self, elem): - self.table["bitset"+elem.get("name")] = elem - - def elem_database(self, elem): - self.process_children(elem) - - class CheaderWriter(RulesngHandler): """Generate commented C header file of registers""" macrovars = [ 'i', 'j', 'k', 'l' ] - def __init__(self, table, options={}): + def __init__(self, options={}): """As parameter, provide the dictionary collected by class Collector, so that <use-foo> elements can work.""" RulesngHandler.__init__(self) - self.table = table + self.groups = None # process optional features self.options = { @@ -64,6 +43,11 @@ # the default output is stdout self.outsock = sys.stdout + def processXMLTree(self, rootnode): + self.groups = GroupCollector() + self.groups.dispatch_elem(rootnode) + self.dispatch_elem(rootnode) + def out(self, msg): self.outsock.write(msg + "\n") @@ -240,19 +224,19 @@ self.process_children(elem) def elem_use_bitset(self, elem): - bitset = self.table["bitset"+elem.get("ref")] + bitset = self.groups.bitsetTable[elem.get("ref")] self.out("/* from bitset %s */" % elem.get("ref")) self.process_children(bitset) self.out('') def elem_use_enum(self, elem): - enum = self.table["enum"+elem.get("ref")] + enum = self.groups.enumTable[elem.get("ref")] self.out("/* from enum %s */" % elem.get("ref")) self.process_children(enum) self.out('') def elem_use_group(self, elem): - group = self.table["group"+elem.get("ref")] + group = self.groups.groupTable[elem.get("ref")] self.out("/* from group %s */" % elem.get("ref")) self.process_children(group) self.out('') @@ -342,13 +326,10 @@ root = db.getroot() - coll = Collector() - coll.dispatch_elem(root) - - writer = CheaderWriter(coll.table, options) + writer = CheaderWriter(options) if outfile is not None: writer.outsock = open(outfile, "w") - writer.dispatch_elem(root) + writer.processXMLTree(root) if __name__ == "__main__": =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/names2html.py,v retrieving revision 1.10 retrieving revision 1.11 diff -u -3 -r1.10 -r1.11 --- names2html.py 13 Jul 2007 12:40:53 -0000 1.10 +++ names2html.py 13 Jul 2007 13:36:52 -0000 1.11 @@ -11,14 +11,15 @@ class TextWriter: """Simple printer for symbol list.""" - def __init__(self): + def __init__(self, options = {}): self.indentlevel = 0 self.outsock = sys.stdout # process optional features self.options = { + # no optional features } - #self.options.update(options) + self.options.update(options) def out(self, msg): self.outsock.write(self.indentlevel * "\t" + msg + "\n") @@ -150,9 +151,7 @@ if opt in ('-h', '--help'): print usage() print "This program is for converting a rules-ng "\ - "style database (XML) into C language\n"\ - "header file containing register definitions"\ - " as #defines." + "style database (XML) into HTML documentation." sys.exit() elif opt in ('-s', '--schema'): schemafile = arg @@ -169,11 +168,8 @@ root = db.getroot() - coll = GroupCollector() - coll.dispatch_elem(root) - - namecoll = NameCollector(coll, options) - namecoll.dispatch_elem(root) + namecoll = NameCollector() + namecoll.processXMLTree(root) tw = TextWriter() if outfile is not None: @@ -182,7 +178,6 @@ keys.sort() for name in keys: relist = namecoll.symbols[name] - combineRulesngElements(relist) for re in relist: tw.output(re) =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/rulesng.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- rulesng.py 13 Jul 2007 12:40:54 -0000 1.3 +++ rulesng.py 13 Jul 2007 13:36:52 -0000 1.4 @@ -141,3 +141,9 @@ 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) =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/rulesngCollectors.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- rulesngCollectors.py 13 Jul 2007 12:40:54 -0000 1.1 +++ rulesngCollectors.py 13 Jul 2007 13:36:52 -0000 1.2 @@ -4,7 +4,8 @@ class GroupCollector(RulesngHandler): """Collector object only goes through the <database> element and collects references to all <enum>, <bitset> and <group> - elements into a dictionary""" + elements into a dictionary. + Traverses the lxml object tree according to Rules-ng specs.""" def __init__(self): RulesngHandler.__init__(self) @@ -28,15 +29,16 @@ class NameCollector(RulesngHandler): """Collect all names into a dictionary.""" - def __init__(self, groupcoll, options={}): + def __init__(self, options={}): """As parameter, provide a reference to executed GroupCollector object, so that <use-foo> elements can work.""" RulesngHandler.__init__(self) - self.groups = groupcoll + self.groups = None # process optional features self.options = { + # no optional features } self.options.update(options) @@ -55,6 +57,12 @@ # keys are full names, values are lists of RulesngElement refs. self.symbols = {}; + def processXMLTree(self, rootnode): + self.groups = GroupCollector() + self.groups.dispatch_elem(rootnode) + self.dispatch_elem(rootnode) + self.combineElements() + def addToSymbolList(self, re): name = re.getName() if len(name) == 0: @@ -89,6 +97,13 @@ re.translation = self.translation return re + def combineElements(self): + """Call combineRulesngElements for each object list in + NameCollector.symbols.""" + + for k in self.symbols.keys(): + combineRulesngElements(self.symbols[k]) + def elem_database(self, elem): self.process_children(elem) |
From: <nou...@li...> - 2007-07-14 18:35:11
|
NouVeau CVS commit Author : ppaalanen Project : rules-ng Module : parsers Dir : rules-ng/parsers Modified Files: rulesng.py Log Message: Added id number attribute to RulesngElement. =================================================================== RCS file: /cvsroot/nouveau/rules-ng/parsers/rulesng.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- rulesng.py 13 Jul 2007 13:36:52 -0000 1.4 +++ rulesng.py 14 Jul 2007 18:35:10 -0000 1.5 @@ -91,8 +91,11 @@ 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 @@ -103,6 +106,8 @@ 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 |