File indexing completed on 2024-04-21 14:57:40

0001 #!/usr/bin/python
0002 # -*- coding: utf-8 -*-
0003 
0004 # List of namespaces.The 2nd part in the array states whether the attributes
0005 # should be in the namespace
0006 namespaces = {
0007     "xhtml": ['"http://www.w3.org/1999/xhtml"', False, 0 ],
0008     "empty": [ "DOMString()", False, 1 ],
0009     "svg":   ['"http://www.w3.org/2000/svg"', False, 2 ],
0010     "xlink": ['"http://www.w3.org/1999/xlink"', True, 3 ],
0011     "xmlns":   ['"http://www.w3.org/2000/xmlns/"', True, 4 ],
0012     "xml":   ['"http://www.w3.org/XML/1998/namespace"', True, 5 ],
0013 }
0014 
0015 cache = {}
0016 namesList = []
0017 
0018 additionalCaseSensitiveAttrs = []
0019 lastCaseInsensitiveAttr      = 0
0020 
0021 
0022 def constName(prefix, ns, i):
0023     if namespaces[ns][1]:
0024         return (prefix + "_%s_%s") % (ns.upper(), i.upper().replace("-", "_"));
0025     else:
0026         return (prefix + "_%s") % i.upper().replace("-", "_");
0027 
0028 def parseFile(fname, ns, isAttrs, isHtmlAttrs):
0029     global cache
0030     global namesList
0031 
0032     global additionalCaseSensitiveAttrs
0033     global lastCaseInsensitiveAttr
0034 
0035     prefix = "ID"
0036     if isAttrs:
0037         prefix = "ATTR"
0038 
0039     f = open(fname, "r")
0040     for i in f.xreadlines():
0041         i = i.strip()
0042         if i.startswith("#") or i == "": continue
0043         if isHtmlAttrs and i.startswith("END_CI"):
0044             lastCaseInsensitiveAttr = len(cache)
0045             continue
0046 
0047         # don't add it twice to names list
0048         cons = constName(prefix, ns, i)
0049         alreadyDefined = [k for k in namesList if k[2] == cons]
0050         if len(alreadyDefined) > 0:
0051             continue
0052 
0053         if i.upper() == "TEXT" and isAttrs: # hack to get ID_TEXT and ATTR_TEXT be different
0054             key = len(cache) + 1
0055             cache["TEXT#"] = -1
0056         else:
0057             key = cache.get(i, len(cache) + 1)
0058 
0059         if isHtmlAttrs and lastCaseInsensitiveAttr > 0 and key <= len(cache):
0060             additionalCaseSensitiveAttrs.append(cons)
0061 
0062         cache[i] = key
0063         namesList.append([key, i, cons, ns])
0064     f.close();
0065 
0066 def parseTags(fname, ns):
0067     parseFile(fname, ns, False, False)
0068 
0069 def parseAttrs(fname, ns, isHtml):
0070     parseFile(fname, ns, True, isHtml)
0071 
0072 # parse htmltags.in
0073 parseTags("htmltags.in", "xhtml");
0074 lastTagId = len(cache)
0075 
0076 # parse htmlattrs.in file
0077 parseAttrs("htmlattrs.in", "xhtml", True)
0078 lastAttrId = len(cache)
0079 
0080 # parse SVG tags, attrs
0081 parseTags("../svg/svgtags.in", "svg")
0082 parseAttrs("../svg/svgattrs.in", "svg", False)
0083 
0084 # parse XLink attrs
0085 parseAttrs("../svg/xlinkattrs.in", "xlink", False)
0086 
0087 # and XML attrs
0088 parseAttrs("xmlattrs.in", "xml", False)
0089 
0090 # sort the list
0091 def func(a, b):
0092     return cmp(a[0], b[0]) or -cmp(a[2], b[2])
0093 namesList.sort(func)
0094 
0095 ########################################
0096 # END OF PARSING, START WRITING FILES
0097 ########################################
0098 
0099 out = open("htmlnames.h", "w")
0100 out.write("/* This file is automatically generated from htmltags.in and htmlattrs.in by gennames.py, do not edit */\n")
0101 out.write("/* Copyright 2008 Vyacheslav Tokarev */\n")
0102 out.write("\n")
0103 out.write("#ifndef HTMLNames_h\n")
0104 out.write("#define HTMLNames_h\n")
0105 out.write("\n")
0106 out.write("#include \"misc/idstring.h\"\n")
0107 out.write("\n")
0108 
0109 # Print out namespace string constants
0110 for n in namespaces.keys():
0111     uri = namespaces[n][0];
0112     if uri.startswith('"'):
0113         out.write("#define %s_NAMESPACE %s\n" % (n.upper(), uri))
0114 
0115 # Now the main macros and constants
0116 out.write("namespace DOM {\n\
0117 \n\
0118 #define NodeImpl_IdNSMask    0xffff0000\n\
0119 #define NodeImpl_IdLocalMask 0x0000ffff\n\
0120 \n");
0121 
0122 for n in namespaces.keys():
0123     out.write("const quint32 %sNamespace = %d;\n" % (n, namespaces[n][2]));
0124 
0125 out.write("const quint16 anyNamespace = 0xffff;\n\
0126 const quint16 anyLocalName = 0xffff;\n\
0127 const quint16 emptyPrefix = 0;\n\
0128 const quint16 xmlPrefix = 1;\n\
0129 const quint16 xmlnsPrefix = 2;\n\
0130 \n\
0131 inline quint16 localNamePart(quint32 id) { return id & NodeImpl_IdLocalMask; }\n\
0132 inline quint16 namespacePart(quint32 id) { return (((unsigned int)id) & NodeImpl_IdNSMask) >> 16; }\n\
0133 inline quint32 makeId(quint16 n, quint16 l) { return (n << 16) | l; }\n\
0134 \n\
0135 const quint32 anyQName = makeId(anyNamespace, anyLocalName);\n\
0136 \n\
0137 }\n")
0138 out.write("\n")
0139 
0140 
0141 # Now the ATTR_ and ID_ constants
0142 out.write("\n")
0143 for i in namesList:
0144     if i[2].startswith("ATTR"):
0145         attrNS = i[3]
0146         useNS  = "empty"
0147         if namespaces[attrNS][1]:
0148             useNS = attrNS
0149         out.write("#define %s ((DOM::%s << 16) | %d)\n" % (i[2], useNS + "Namespace", i[0]))
0150     else:
0151         out.write("#define %s %d\n" % (i[2], i[0]))
0152 out.write("#define ID_LAST_TAG %d\n" % (lastTagId))
0153 out.write("#define ID_CLOSE_TAG 16384\n")
0154 out.write("#define ATTR_LAST_ATTR %d\n" % (lastAttrId))
0155 out.write("#define ATTR_LAST_CI_ATTR %d\n" % (lastCaseInsensitiveAttr))
0156 out.write("\n")
0157 s = "((localNamePart(id)) > ATTR_LAST_CI_ATTR"
0158 for i in additionalCaseSensitiveAttrs:
0159     s = s + " || (id) == %s" % i
0160 s = s + ")"
0161 out.write("#define caseSensitiveAttr(id) (%s)\n" % s)
0162 out.write("\n")
0163 out.write("namespace khtml {\n\
0164 \n\
0165 class NamespaceFactory {\n\
0166 public:\n\
0167     static IDTable<NamespaceFactory>* idTable() {\n\
0168         return s_idTable;\n\
0169     }\n\
0170     static IDTable<NamespaceFactory>* initIdTable();\n\
0171 protected:\n\
0172     static IDTable<NamespaceFactory>* s_idTable;\n\
0173 };\n\
0174 \n\
0175 class LocalNameFactory {\n\
0176 public:\n\
0177     static IDTable<LocalNameFactory>* idTable() {\n\
0178         return s_idTable;\n\
0179     }\n\
0180     static IDTable<LocalNameFactory>* initIdTable();\n\
0181 protected:\n\
0182     static IDTable<LocalNameFactory>* s_idTable;\n\
0183 };\n\
0184 \n\
0185 class PrefixFactory {\n\
0186 public:\n\
0187     static IDTable<PrefixFactory>* idTable() {\n\
0188         return s_idTable;\n\
0189     }\n\
0190     static IDTable<PrefixFactory>* initIdTable();\n\
0191 protected:\n\
0192     static IDTable<PrefixFactory>* s_idTable;\n\
0193 };\n")
0194 out.write("\n")
0195 out.write("}\n")
0196 out.write("\n")
0197 out.write("namespace DOM {\n\
0198 \n\
0199     typedef khtml::IDString<khtml::NamespaceFactory> NamespaceName;\n\
0200     typedef khtml::IDString<khtml::LocalNameFactory> LocalName;\n\
0201     typedef khtml::IDString<khtml::PrefixFactory> PrefixName;\n\
0202     extern PrefixName emptyPrefixName;\n\
0203     extern LocalName emptyLocalName;\n\
0204     extern NamespaceName emptyNamespaceName;\n\
0205 \n\
0206     QString getPrintableName(int id);\n\n")
0207 out.write("}\n\n")
0208 out.write("#endif\n")
0209 out.close()
0210 
0211 temp = ""
0212 prev = 0
0213 for i in namesList:
0214     if prev and prev[0] == i[0]: continue
0215     if i[2] == "ID_TEXT" or i[2] == "ID_COMMENT":
0216         temp = temp + ("    s_idTable->addHiddenMapping(%s, \"%s\");\n" % (i[2], i[1]))
0217     else:
0218         temp = temp + ("    s_idTable->addStaticMapping(localNamePart(%s), \"%s\");\n" % (i[2], i[1]))
0219     prev = i
0220 
0221 out = open("htmlnames.cpp", "w")
0222 out.write("#include \"misc/htmlnames.h\"\n")
0223 out.write("#include \"dom/dom_string.h\"\n")
0224 out.write("\nusing namespace DOM;\n")
0225 out.write("\n")
0226 out.write("namespace khtml {\n\n")
0227 out.write("IDTable<NamespaceFactory>* NamespaceFactory::s_idTable;\n\
0228 IDTable<NamespaceFactory>* NamespaceFactory::initIdTable()\n\
0229 {\n\
0230     if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\
0231     s_idTable = new IDTable<NamespaceFactory>();\n");
0232 for n in namespaces.keys():
0233     uri = namespaces[n][0];
0234     if uri.startswith('"'):
0235         out.write("    s_idTable->addStaticMapping(DOM::%sNamespace, %s_NAMESPACE);\n" % (n, n.upper()))
0236     else:
0237         out.write("    s_idTable->addStaticMapping(DOM::%sNamespace, %s);\n" % (n, uri))
0238 
0239 out.write("    return s_idTable;\n\
0240 }\n\
0241 \n\
0242 IDTable<LocalNameFactory>* LocalNameFactory::s_idTable;\n\
0243 IDTable<LocalNameFactory>* LocalNameFactory::initIdTable()\n\
0244 {\n\
0245     if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\
0246     s_idTable = new IDTable<LocalNameFactory>();\n\
0247     s_idTable->addStaticMapping(0, DOMString());\n\
0248 %s\
0249     return s_idTable;\n\
0250 }\n\
0251 \n\
0252 IDTable<PrefixFactory>* PrefixFactory::s_idTable;\n\
0253 IDTable<PrefixFactory>* PrefixFactory::initIdTable()\n\
0254 {\n\
0255     if (s_idTable) return s_idTable; // Can happen if KHTMLGlobal was recreated..\n\
0256     s_idTable = new IDTable<PrefixFactory>();\n\
0257     s_idTable->addStaticMapping(DOM::emptyPrefix, DOMString());\n\
0258     s_idTable->addStaticMapping(DOM::xmlPrefix, \"xml\");\n\
0259     s_idTable->addStaticMapping(DOM::xmlnsPrefix, \"xmlns\");\n\
0260     return s_idTable;\n\
0261 }\n" % temp)
0262 out.write("\n}\n")
0263 out.write("\n")
0264 out.write("namespace DOM {\n\n")
0265 out.write("LocalName emptyLocalName;// = LocalName::fromId(0);\n")
0266 out.write("PrefixName emptyPrefixName;// = PrefixName::fromId(0);\n")
0267 out.write("NamespaceName emptyNamespaceName;// = NamespaceName::fromId(0);\n")
0268 out.write("\n")
0269 out.write("""QString getPrintableName(int id) {
0270     QString local = QString("null");
0271     QString namespacename = QString("null");
0272 
0273     if (localNamePart(id) != anyLocalName) {
0274         DOMString localName = LocalName::fromId(localNamePart(id)).toString();
0275         if (localName.implementation())
0276             local = localName.string();
0277     } else {
0278         local = "*";
0279     }
0280 
0281     if (namespacePart(id) != anyNamespace) {
0282         DOMString namespaceName = NamespaceName::fromId(namespacePart(id)).toString();
0283         if (namespaceName.implementation())
0284             namespacename = namespaceName.string();
0285     } else {
0286         namespacename = "*";
0287     }
0288     return "{ns:" + QString::number(namespacePart(id)) + ",[" + namespacename + "] local:" + QString::number(localNamePart(id)) + ",[" + local + "]}";
0289 }\n""")
0290 out.write("\n}\n")
0291 out.close()
0292 
0293 # kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
0294