+ return elem.getElementsByTagName(path)
+
+def get_text_contents(node):
+ result = ""
+ for c in node.childNodes:
+ if c.nodeType==xml.dom.Node.TEXT_NODE or c.nodeType==xml.dom.Node.CDATA_SECTION_NODE:
+ result += c.data
+ else:
+ result += get_text_contents(c)
+ return result
+
+def parse_file(fn):
+ doc = xml.dom.minidom.parse(fn)
+ root = doc.documentElement
+ commands = get_nested_elements(root, "commands/command")
+ for cmd in commands:
+ name = get_text_contents(get_nested_elements(cmd, "proto/name")[0])
+ func = funcs.get(name)
+ if not func:
+ func = Function(name)
+ funcs[name] = func
+
+ aliases = cmd.getElementsByTagName("alias")
+ for a in aliases:
+ func.aliases.append(a.getAttribute("name"))
+
+ vec = cmd.getElementsByTagName("vecequiv")
+ if vec:
+ func.vectorequiv = vec[0].getAttribute("name")
+
+ features = root.getElementsByTagName("feature")
+ for feat in features:
+ api = feat.getAttribute("api")
+ if api=="gl":
+ version = feat.getAttribute("number")
+
+ commands = get_nested_elements(feat, "require/command")
+ for c in commands:
+ name = c.getAttribute("name")
+ func = funcs.get(name)
+ if func:
+ func.version = version
+
+ if feat.getAttribute("name")=="MSPGL_REMOVE":
+ commands = get_nested_elements(feat, "remove/command")
+ for c in commands:
+ name = c.getAttribute("name")
+ if name in funcs:
+ del funcs[name]
+
+ extensions = get_nested_elements(root, "extensions/extension")
+ for ext in extensions:
+ ext_name = ext.getAttribute("name")
+ if ext_name.startswith("GL_"):
+ ext_name = ext_name[3:]
+ supported = ext.getAttribute("supported").split('|')
+ if "gl" in supported:
+ commands = get_nested_elements(ext, "require/command")
+ for c in commands:
+ name = c.getAttribute("name")
+ func = funcs.get(name)
+ if func:
+ func.category = ext_name
+
+parse_file("gl.xml")
+parse_file("gl.fixes.xml")
+
+for f in funcs.itervalues():
+ if f.category==ext or f.category in secondary:
+ for a in f.aliases:
+ aliasfunc = funcs.get(a)
+ if aliasfunc:
+ aliasfunc.extfunc = f
+
+def is_relevant(f):
+ if f.category==ext and not f.aliases:
+ return True
+ if f.extfunc:
+ e = f.extfunc
+ if e.category==ext or e.category in secondary:
+ return True
+ return False
+
+funcs = [f for f in funcs.itervalues() if is_relevant(f)]
+funcs.sort(key=(lambda f: f.name))
+
+for f in funcs:
+ if not ver:
+ ver = f.version
+
+ if f.category and not f.name.endswith(exttype):
+ bp_ext = f.category