#!/usr/bin/python # -*- coding: utf-8 -*- # List of namespaces.The 2nd part in the array states whether the attributes # should be in the namespace namespaces = { "xhtml": ['"http://www.w3.org/1999/xhtml"', False, 0 ], "empty": [ "DOMString()", False, 1 ], "svg": ['"http://www.w3.org/2000/svg"', False, 2 ], "xlink": ['"http://www.w3.org/1999/xlink"', True, 3 ], "xmlns": ['"http://www.w3.org/2000/xmlns/"', True, 4 ], "xml": ['"http://www.w3.org/XML/1998/namespace"', True, 5 ], } cache = {} namesList = [] additionalCaseSensitiveAttrs = [] lastCaseInsensitiveAttr = 0 def constName(prefix, ns, i): if namespaces[ns][1]: return (prefix + "_%s_%s") % (ns.upper(), i.upper().replace("-", "_")); else: return (prefix + "_%s") % i.upper().replace("-", "_"); def parseFile(fname, ns, isAttrs, isHtmlAttrs): global cache global namesList global additionalCaseSensitiveAttrs global lastCaseInsensitiveAttr prefix = "ID" if isAttrs: prefix = "ATTR" f = open(fname, "r") for i in f.xreadlines(): i = i.strip() if i.startswith("#") or i == "": continue if isHtmlAttrs and i.startswith("END_CI"): lastCaseInsensitiveAttr = len(cache) continue # don't add it twice to names list cons = constName(prefix, ns, i) alreadyDefined = [k for k in namesList if k[2] == cons] if len(alreadyDefined) > 0: continue if i.upper() == "TEXT" and isAttrs: # hack to get ID_TEXT and ATTR_TEXT be different key = len(cache) + 1 cache["TEXT#"] = -1 else: key = cache.get(i, len(cache) + 1) if isHtmlAttrs and lastCaseInsensitiveAttr > 0 and key <= len(cache): additionalCaseSensitiveAttrs.append(cons) cache[i] = key namesList.append([key, i, cons, ns]) f.close(); def parseTags(fname, ns): parseFile(fname, ns, False, False) def parseAttrs(fname, ns, isHtml): parseFile(fname, ns, True, isHtml) # parse htmltags.in parseTags("htmltags.in", "xhtml"); lastTagId = len(cache) # parse htmlattrs.in file parseAttrs("htmlattrs.in", "xhtml", True) lastAttrId = len(cache) # parse SVG tags, attrs parseTags("../svg/svgtags.in", "svg") parseAttrs("../svg/svgattrs.in", "svg", False) # parse XLink attrs parseAttrs("../svg/xlinkattrs.in", "xlink", False) # and XML attrs parseAttrs("xmlattrs.in", "xml", False) # sort the list def func(a, b): return cmp(a[0], b[0]) or -cmp(a[2], b[2]) namesList.sort(func) ######################################## # END OF PARSING, START WRITING FILES ######################################## out = open("htmlnames.h", "w") out.write("/* This file is automatically generated from htmltags.in and htmlattrs.in by gennames.py, do not edit */\n") out.write("/* Copyright 2008 Vyacheslav Tokarev */\n") out.write("\n") out.write("#ifndef HTMLNames_h\n") out.write("#define HTMLNames_h\n") out.write("\n") out.write("#include \"misc/idstring.h\"\n") out.write("\n") # Print out namespace string constants for n in namespaces.keys(): uri = namespaces[n][0]; if uri.startswith('"'): out.write("#define %s_NAMESPACE %s\n" % (n.upper(), uri)) # Now the main macros and constants out.write("namespace DOM {\n\ \n\ #define NodeImpl_IdNSMask 0xffff0000\n\ #define NodeImpl_IdLocalMask 0x0000ffff\n\ \n"); for n in namespaces.keys(): out.write("const quint32 %sNamespace = %d;\n" % (n, namespaces[n][2])); out.write("const quint16 anyNamespace = 0xffff;\n\ const quint16 anyLocalName = 0xffff;\n\ const quint16 emptyPrefix = 0;\n\ const quint16 xmlPrefix = 1;\n\ const quint16 xmlnsPrefix = 2;\n\ \n\ inline quint16 localNamePart(quint32 id) { return id & NodeImpl_IdLocalMask; }\n\ inline quint16 namespacePart(quint32 id) { return (((unsigned int)id) & NodeImpl_IdNSMask) >> 16; }\n\ inline quint32 makeId(quint16 n, quint16 l) { return (n << 16) | l; }\n\ \n\ const quint32 anyQName = makeId(anyNamespace, anyLocalName);\n\ \n\ }\n") out.write("\n") # Now the ATTR_ and ID_ constants out.write("\n") for i in namesList: if i[2].startswith("ATTR"): attrNS = i[3] useNS = "empty" if namespaces[attrNS][1]: useNS = attrNS out.write("#define %s ((DOM::%s << 16) | %d)\n" % (i[2], useNS + "Namespace", i[0])) else: out.write("#define %s %d\n" % (i[2], i[0])) out.write("#define ID_LAST_TAG %d\n" % (lastTagId)) out.write("#define ID_CLOSE_TAG 16384\n") out.write("#define ATTR_LAST_ATTR %d\n" % (lastAttrId)) out.write("#define ATTR_LAST_CI_ATTR %d\n" % (lastCaseInsensitiveAttr)) out.write("\n") s = "((localNamePart(id)) > ATTR_LAST_CI_ATTR" for i in additionalCaseSensitiveAttrs: s = s + " || (id) == %s" % i s = s + ")" out.write("#define caseSensitiveAttr(id) (%s)\n" % s) out.write("\n") out.write("namespace khtml {\n\ \n\ class NamespaceFactory {\n\ public:\n\ static IDTable* idTable() {\n\ return s_idTable;\n\ }\n\ static IDTable* initIdTable();\n\ protected:\n\ static IDTable* s_idTable;\n\ };\n\ \n\ class LocalNameFactory {\n\ public:\n\ static IDTable* idTable() {\n\ return s_idTable;\n\ }\n\ static IDTable* initIdTable();\n\ protected:\n\ static IDTable* s_idTable;\n\ };\n\ \n\ class PrefixFactory {\n\ public:\n\ static IDTable* idTable() {\n\ return s_idTable;\n\ }\n\ static IDTable* initIdTable();\n\ protected:\n\ static IDTable* s_idTable;\n\ };\n") out.write("\n") out.write("}\n") out.write("\n") out.write("namespace DOM {\n\ \n\ typedef khtml::IDString NamespaceName;\n\ typedef khtml::IDString LocalName;\n\ typedef khtml::IDString PrefixName;\n\ extern PrefixName emptyPrefixName;\n\ extern LocalName emptyLocalName;\n\ extern NamespaceName emptyNamespaceName;\n\ \n\ QString getPrintableName(int id);\n\n") out.write("}\n\n") out.write("#endif\n") out.close() temp = "" prev = 0 for i in namesList: if prev and prev[0] == i[0]: continue if i[2] == "ID_TEXT" or i[2] == "ID_COMMENT": temp = temp + (" s_idTable->addHiddenMapping(%s, \"%s\");\n" % (i[2], i[1])) else: temp = temp + (" s_idTable->addStaticMapping(localNamePart(%s), \"%s\");\n" % (i[2], i[1])) prev = i out = open("htmlnames.cpp", "w") out.write("#include \"misc/htmlnames.h\"\n") out.write("#include \"dom/dom_string.h\"\n") out.write("\nusing namespace DOM;\n") out.write("\n") out.write("namespace khtml {\n\n") out.write("IDTable* NamespaceFactory::s_idTable;\n\ IDTable* NamespaceFactory::initIdTable()\n\ {\n\ if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\ s_idTable = new IDTable();\n"); for n in namespaces.keys(): uri = namespaces[n][0]; if uri.startswith('"'): out.write(" s_idTable->addStaticMapping(DOM::%sNamespace, %s_NAMESPACE);\n" % (n, n.upper())) else: out.write(" s_idTable->addStaticMapping(DOM::%sNamespace, %s);\n" % (n, uri)) out.write(" return s_idTable;\n\ }\n\ \n\ IDTable* LocalNameFactory::s_idTable;\n\ IDTable* LocalNameFactory::initIdTable()\n\ {\n\ if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\ s_idTable = new IDTable();\n\ s_idTable->addStaticMapping(0, DOMString());\n\ %s\ return s_idTable;\n\ }\n\ \n\ IDTable* PrefixFactory::s_idTable;\n\ IDTable* PrefixFactory::initIdTable()\n\ {\n\ if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\ s_idTable = new IDTable();\n\ s_idTable->addStaticMapping(DOM::emptyPrefix, DOMString());\n\ s_idTable->addStaticMapping(DOM::xmlPrefix, \"xml\");\n\ s_idTable->addStaticMapping(DOM::xmlnsPrefix, \"xmlns\");\n\ return s_idTable;\n\ }\n" % temp) out.write("\n}\n") out.write("\n") out.write("namespace DOM {\n\n") out.write("LocalName emptyLocalName;// = LocalName::fromId(0);\n") out.write("PrefixName emptyPrefixName;// = PrefixName::fromId(0);\n") out.write("NamespaceName emptyNamespaceName;// = NamespaceName::fromId(0);\n") out.write("\n") out.write("""QString getPrintableName(int id) { QString local = QString("null"); QString namespacename = QString("null"); if (localNamePart(id) != anyLocalName) { DOMString localName = LocalName::fromId(localNamePart(id)).toString(); if (localName.implementation()) local = localName.string(); } else { local = "*"; } if (namespacePart(id) != anyNamespace) { DOMString namespaceName = NamespaceName::fromId(namespacePart(id)).toString(); if (namespaceName.implementation()) namespacename = namespaceName.string(); } else { namespacename = "*"; } return "{ns:" + QString::number(namespacePart(id)) + ",[" + namespacename + "] local:" + QString::number(localNamePart(id)) + ",[" + local + "]}"; }\n""") out.write("\n}\n") out.close() # kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;