diff --git a/c/src/encodings.h.py b/c/src/encodings.h.py index f03f3a288c..33e9e04b39 100644 --- a/c/src/encodings.h.py +++ b/c/src/encodings.h.py @@ -18,13 +18,13 @@ # under the License. # -import mllib -import optparse import os -import sys +import xml.etree.ElementTree as ET +ns = {'amqp': 'http://www.amqp.org/schema/amqp.xsd'} xml = os.path.join(os.path.dirname(__file__), "types.xml") -doc = mllib.xml_parse(xml) +doc = ET.parse(xml).getroot() + print("/* generated from %s */" % xml) print("#ifndef _PROTON_ENCODINGS_H") @@ -32,13 +32,14 @@ print() print("#define PNE_DESCRIPTOR (0x00)") -for enc in doc.query["amqp/section/type/encoding"]: - name = enc["@name"] or enc.parent["@name"] - # XXX: a bit hacky - if name == "ieee-754": - name = enc.parent["@name"] +types = doc.findall('./amqp:section/amqp:type', ns) +encodings = [(t.attrib['name'], e) for t in types for e in t.findall('./amqp:encoding', ns)] +for parentname, enc in encodings: + name = enc.attrib.get("name") + if not name or name == "ieee-754": + name = parentname cname = "PNE_" + name.replace("-", "_").upper() - print("#define %s%s(%s)" % (cname, " " * (20 - len(cname)), enc["@code"])) + print("#define %s%s(%s)" % (cname, " " * (20 - len(cname)), enc.attrib["code"])) print() print("#endif /* encodings.h */") diff --git a/c/src/protocol.h.py b/c/src/protocol.h.py index a6a789e709..620d72917c 100644 --- a/c/src/protocol.h.py +++ b/c/src/protocol.h.py @@ -30,10 +30,10 @@ for type in TYPES: fidx = 0 - for f in type.query["field"]: + for f in type.findall("amqp:field", ns): print("#define %s_%s (%s)" % (field_kw(type), field_kw(f), fidx)) fidx += 1 - d = f["@default"] + d = f.attrib.get("default") if d: ft = ftype(f) # Don't bother to emit a boolean default that is False @@ -51,13 +51,13 @@ idx = 0 for type in TYPES: - desc = type["descriptor"] - name = type["@name"].upper().replace("-", "_") - print("#define %s_SYM (\"%s\")" % (name, desc["@name"])) - hi, lo = [int(x, 0) for x in desc["@code"].split(":")] + desc = type.find("./amqp:descriptor", ns) + name = type.attrib["name"].upper().replace("-", "_") + print("#define %s_SYM (\"%s\")" % (name, desc.attrib["name"])) + hi, lo = [int(x, 0) for x in desc.attrib["code"].split(":")] code = (hi << 32) + lo print("#define %s ((uint64_t) %s)" % (name, code)) - fields[code] = (type["@name"], [f["@name"] for f in type.query["field"]]) + fields[code] = (type.attrib["name"], [f.attrib["name"] for f in type.findall("amqp:field", ns)]) idx += 1 print(""" diff --git a/c/src/protocol.py b/c/src/protocol.py index b112b00602..da37731509 100644 --- a/c/src/protocol.py +++ b/c/src/protocol.py @@ -16,25 +16,21 @@ # specific language governing permissions and limitations # under the License. # -import mllib import os -import sys +import xml.etree.ElementTree as ET -doc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "transport.xml")) -mdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "messaging.xml")) -tdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "transactions.xml")) -sdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "security.xml")) +ns = {'amqp': 'http://www.amqp.org/schema/amqp.xsd'} +doc = ET.parse(os.path.join(os.path.dirname(__file__), "transport.xml")).getroot() +mdoc = ET.parse(os.path.join(os.path.dirname(__file__), "messaging.xml")).getroot() +tdoc = ET.parse(os.path.join(os.path.dirname(__file__), "transactions.xml")).getroot() +sdoc = ET.parse(os.path.join(os.path.dirname(__file__), "security.xml")).getroot() -def eq(attr, value): - return lambda nd: nd[attr] == value - - -TYPEStmp = doc.query["amqp/section/type", eq("@class", "composite")] + \ - mdoc.query["amqp/section/type", eq("@class", "composite")] + \ - tdoc.query["amqp/section/type", eq("@class", "composite")] + \ - sdoc.query["amqp/section/type", eq("@class", "composite")] + \ - mdoc.query["amqp/section/type", eq("@provides", "section")] +TYPEStmp = doc.findall("./amqp:section/amqp:type/[@class='composite']", ns) + \ + mdoc.findall("./amqp:section/amqp:type/[@class='composite']", ns) + \ + tdoc.findall("./amqp:section/amqp:type/[@class='composite']", ns) + \ + sdoc.findall("./amqp:section/amqp:type/[@class='composite']", ns) + \ + mdoc.findall("./amqp:section/amqp:type/[@provides='section']", ns) TYPES = [] for ty in TYPEStmp: if ty not in TYPES: @@ -42,14 +38,14 @@ def eq(attr, value): RESTRICTIONS = {} COMPOSITES = {} -for type in doc.query["amqp/section/type"] + mdoc.query["amqp/section/type"] + \ - sdoc.query["amqp/section/type"] + tdoc.query["amqp/section/type"]: +for type in doc.findall("./amqp:section/amqp:type", ns) + mdoc.findall("./amqp:section/amqp:type", ns) + \ + sdoc.findall("./amqp:section/amqp:type", ns) + tdoc.findall("./amqp:section/amqp:type", ns): - source = type["@source"] + source = type.attrib["source"] if source: - RESTRICTIONS[type["@name"]] = source - if type["@class"] == "composite": - COMPOSITES[type["@name"]] = type + RESTRICTIONS[type.attrib["name"]] = source + if type.attrib["class"] == "composite": + COMPOSITES[type.attrib["name"]] = type def resolve(name): @@ -90,24 +86,24 @@ def resolve(name): def fname(field): - return field["@name"].replace("-", "_") + return field.attrib["name"].replace("-", "_") def tname(t): - return t["@name"].replace("-", "_") + return t.attrib["name"].replace("-", "_") def multi(f): - return f["@multiple"] == "true" + return f.attrib.get("multiple") == "true" def ftype(field): if multi(field): return "list" - elif field["@type"] in COMPOSITES: + elif field.attrib["type"] in COMPOSITES: return "box" else: - return resolve(field["@type"]).replace("-", "_") + return resolve(field.attrib["type"]).replace("-", "_") def fconstruct(field, expr): diff --git a/tools/python/mllib/__init__.py b/tools/python/mllib/__init__.py deleted file mode 100644 index 20daa3f9f2..0000000000 --- a/tools/python/mllib/__init__.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -""" -This module provides document parsing and transformation utilities for XML. -""" - -import os -import sys -import xml.sax -import types -from xml.sax.handler import ErrorHandler -from xml.sax.xmlreader import InputSource - -from io import StringIO - -from . import dom -from . import transforms -from . import parsers - -CLASS_TYPES = (type,) - -def transform(node, *args): - result = node - for t in args: - if isinstance(t, CLASS_TYPES): - t = t() - result = result.dispatch(t) - return result - - -class Resolver: - - def __init__(self, path): - self.path = path - - def resolveEntity(self, publicId, systemId): - for p in self.path: - fname = os.path.join(p, systemId) - if os.path.exists(fname): - source = InputSource(systemId) - source.setByteStream(open(fname)) - return source - return InputSource(systemId) - - -def xml_parse(filename, path=()): - h = parsers.XMLParser() - p = xml.sax.make_parser() - p.setContentHandler(h) - p.setErrorHandler(ErrorHandler()) - p.setEntityResolver(Resolver(path)) - p.parse(filename) - return h.parser.tree - - -def sexp(node): - s = transforms.Sexp() - node.dispatch(s) - return s.out diff --git a/tools/python/mllib/dom.py b/tools/python/mllib/dom.py deleted file mode 100644 index b991740575..0000000000 --- a/tools/python/mllib/dom.py +++ /dev/null @@ -1,331 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -""" -Simple DOM for both SGML and XML documents. -""" - -import sys -STRING_TYPES = (str,) - - -class Container: - - def __init__(self): - self.children = [] - - def add(self, child): - child.parent = self - self.children.append(child) - - def extend(self, children): - for child in children: - child.parent = self - self.children.append(child) - - -class Component: - - def __init__(self): - self.parent = None - - def index(self): - if self.parent: - return self.parent.children.index(self) - else: - return 0 - - def _line(self, file, line, column): - self.file = file - self.line = line - self.column = column - - -class DispatchError(Exception): - - def __init__(self, scope, f): - msg = "no such attribute" - - -class Dispatcher: - - def is_type(self, type): - cls = self - while cls is not None: - if cls.type == type: - return True - cls = cls.base - return False - - def dispatch(self, f, attrs=""): - cls = self - while cls is not None: - if hasattr(f, cls.type): - return getattr(f, cls.type)(self) - else: - cls = cls.base - - cls = self - while cls is not None: - if attrs: - sep = ", " - if cls.base is None: - sep += "or " - else: - sep = "" - attrs += "%s'%s'" % (sep, cls.type) - cls = cls.base - - raise AttributeError("'%s' object has no attribute %s" % - (f.__class__.__name__, attrs)) - - -class Node(Container, Component, Dispatcher): - - type = "node" - base = None - - def __init__(self): - Container.__init__(self) - Component.__init__(self) - self.query = Query([self]) - - def __getitem__(self, name): - for nd in self.query[name]: - return nd - - def text(self): - from . import transforms - return self.dispatch(transforms.Text()) - - def tag(self, name, *attrs, **kwargs): - t = Tag(name, *attrs, **kwargs) - self.add(t) - return t - - def data(self, s): - d = Data(s) - self.add(d) - return d - - def entity(self, s): - e = Entity(s) - self.add(e) - return e - - -class Tree(Node): - - type = "tree" - base = Node - - -class Tag(Node): - - type = "tag" - base = Node - - def __init__(self, _name, *attrs, **kwargs): - Node.__init__(self) - self.name = _name - self.attrs = list(attrs) - self.attrs.extend(kwargs.items()) - self.singleton = False - - def get_attr(self, name): - for k, v in self.attrs: - if name == k: - return v - - def _idx(self, attr): - idx = 0 - for k, v in self.attrs: - if k == attr: - return idx - idx += 1 - return None - - def set_attr(self, name, value): - idx = self._idx(name) - if idx is None: - self.attrs.append((name, value)) - else: - self.attrs[idx] = (name, value) - - def dispatch(self, f): - try: - attr = "do_" + self.name - method = getattr(f, attr) - except AttributeError: - return Dispatcher.dispatch(self, f, "'%s'" % attr) - return method(self) - - -class Leaf(Component, Dispatcher): - - type = "leaf" - base = None - - def __init__(self, data): - assert isinstance(data, STRING_TYPES) - self.data = data - - -class Data(Leaf): - type = "data" - base = Leaf - - -class Entity(Leaf): - type = "entity" - base = Leaf - - -class Character(Leaf): - type = "character" - base = Leaf - - -class Comment(Leaf): - type = "comment" - base = Leaf - -################### -## Query Classes ## -########################################################################### - - -class Adder: - - def __add__(self, other): - return Sum(self, other) - - -class Sum(Adder): - - def __init__(self, left, right): - self.left = left - self.right = right - - def __iter__(self): - for x in self.left: - yield x - for x in self.right: - yield x - - -class View(Adder): - - def __init__(self, source): - self.source = source - - -class Filter(View): - - def __init__(self, predicate, source): - View.__init__(self, source) - self.predicate = predicate - - def __iter__(self): - for nd in self.source: - if self.predicate(nd): - yield nd - - -class Flatten(View): - - def __iter__(self): - sources = [iter(self.source)] - while sources: - try: - nd = next(sources[-1]) - if isinstance(nd, Tree): - sources.append(iter(nd.children)) - else: - yield nd - except StopIteration: - sources.pop() - - -class Children(View): - - def __iter__(self): - for nd in self.source: - for child in nd.children: - yield child - - -class Attributes(View): - - def __iter__(self): - for nd in self.source: - for a in nd.attrs: - yield a - - -class Values(View): - - def __iter__(self): - for name, value in self.source: - yield value - - -def flatten_path(path): - if isinstance(path, STRING_TYPES): - for part in path.split("/"): - yield part - elif callable(path): - yield path - else: - for p in path: - for fp in flatten_path(p): - yield fp - - -class Query(View): - - def __iter__(self): - for nd in self.source: - yield nd - - def __getitem__(self, path): - query = self.source - for p in flatten_path(path): - if callable(p): - select = Query - pred = p - source = query - elif isinstance(p, STRING_TYPES): - if p[0] == "@": - select = Values - pred = lambda x, n=p[1:]: x[0] == n - source = Attributes(query) - elif p[0] == "#": - select = Query - pred = lambda x, t=p[1:]: x.is_type(t) - source = Children(query) - else: - select = Query - def pred(x, n=p): return isinstance(x, Tag) and x.name == n - source = Flatten(Children(query)) - else: - raise ValueError(p) - query = select(Filter(pred, source)) - - return query diff --git a/tools/python/mllib/parsers.py b/tools/python/mllib/parsers.py deleted file mode 100644 index 9904b88319..0000000000 --- a/tools/python/mllib/parsers.py +++ /dev/null @@ -1,105 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -""" -Parsers for XML to dom. -""" -import xml.sax.handler -from .dom import * - - -class Parser: - - def __init__(self): - self.tree = Tree() - self.node = self.tree - self.nodes = [] - - def line(self, id, lineno, colno): - while self.nodes: - n = self.nodes.pop() - n._line(id, lineno, colno) - - def add(self, node): - self.node.add(node) - self.nodes.append(node) - - def start(self, name, attrs): - tag = Tag(name, *attrs) - self.add(tag) - self.node = tag - - def end(self, name): - self.balance(name) - self.node = self.node.parent - - def data(self, data): - children = self.node.children - if children and isinstance(children[-1], Data): - children[-1].data += data - else: - self.add(Data(data)) - - def comment(self, comment): - self.add(Comment(comment)) - - def entity(self, ref): - self.add(Entity(ref)) - - def character(self, ref): - self.add(Character(ref)) - - def balance(self, name=None): - while self.node != self.tree and name != self.node.name: - self.node.parent.extend(self.node.children) - del self.node.children[:] - self.node.singleton = True - self.node = self.node.parent - - -class XMLParser(xml.sax.handler.ContentHandler): - - def __init__(self): - self.parser = Parser() - self.locator = None - - def line(self): - if self.locator is not None: - self.parser.line(self.locator.getSystemId(), - self.locator.getLineNumber(), - self.locator.getColumnNumber()) - - def setDocumentLocator(self, locator): - self.locator = locator - - def startElement(self, name, attrs): - self.parser.start(name, attrs.items()) - self.line() - - def endElement(self, name): - self.parser.end(name) - self.line() - - def characters(self, content): - self.parser.data(content) - self.line() - - def skippedEntity(self, name): - self.parser.entity(name) - self.line() diff --git a/tools/python/mllib/transforms.py b/tools/python/mllib/transforms.py deleted file mode 100644 index b84c7f65df..0000000000 --- a/tools/python/mllib/transforms.py +++ /dev/null @@ -1,171 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -""" -Useful transforms for dom objects. -""" -from . import dom -from io import StringIO - - -class Visitor: - - def descend(self, node): - for child in node.children: - child.dispatch(self) - - def node(self, node): - self.descend(node) - - def leaf(self, leaf): - pass - - -class Identity: - - def descend(self, node): - result = [] - for child in node.children: - result.append(child.dispatch(self)) - return result - - def default(self, tag): - result = dom.Tag(tag.name, *tag.attrs) - result.extend(self.descend(tag)) - return result - - def tree(self, tree): - result = dom.Tree() - result.extend(self.descend(tree)) - return result - - def tag(self, tag): - return self.default(tag) - - def leaf(self, leaf): - return leaf.__class__(leaf.data) - - -class Sexp(Identity): - - def __init__(self): - self.stack = [] - self.level = 0 - self.out = "" - - def open(self, s): - self.out += "(%s" % s - self.level += len(s) + 1 - self.stack.append(s) - - def line(self, s=""): - self.out = self.out.rstrip() - self.out += "\n" + " " * self.level + s - - def close(self): - s = self.stack.pop() - self.level -= len(s) + 1 - self.out = self.out.rstrip() - self.out += ")" - - def tree(self, tree): - self.open("+ ") - for child in tree.children: - self.line() - child.dispatch(self) - self.close() - - def tag(self, tag): - self.open("Node(%s) " % tag.name) - for child in tag.children: - self.line() - child.dispatch(self) - self.close() - - def leaf(self, leaf): - self.line("%s(%s)" % (leaf.__class__.__name__, leaf.data)) - - -class Output: - - def descend(self, node): - out = StringIO() - for child in node.children: - out.write(child.dispatch(self)) - return out.getvalue() - - def default(self, tag): - out = StringIO() - out.write("<%s" % tag.name) - for k, v in tag.attrs: - out.write(' %s="%s"' % (k, v)) - out.write(">") - out.write(self.descend(tag)) - if not tag.singleton: - out.write("" % tag.name) - return out.getvalue() - - def tree(self, tree): - return self.descend(tree) - - def tag(self, tag): - return self.default(tag) - - def data(self, leaf): - return leaf.data - - def entity(self, leaf): - return "&%s;" % leaf.data - - def character(self, leaf): - raise Exception("TODO") - - def comment(self, leaf): - return "" % leaf.data - - -class Empty(Output): - - def tag(self, tag): - return self.descend(tag) - - def data(self, leaf): - return "" - - def entity(self, leaf): - return "" - - def character(self, leaf): - return "" - - def comment(self, leaf): - return "" - - -class Text(Empty): - - def data(self, leaf): - return leaf.data - - def entity(self, leaf): - return "&%s;" % leaf.data - - def character(self, leaf): - # XXX: is this right? - return "&#%s;" % leaf.data