diff options
author | dcorbacho <dparracorbacho@piotal.io> | 2020-11-18 14:27:41 +0000 |
---|---|---|
committer | dcorbacho <dparracorbacho@piotal.io> | 2020-11-18 14:27:41 +0000 |
commit | f23a51261d9502ec39df0f8db47ba6b22aa7659f (patch) | |
tree | 53dcdf46e7dc2c14e81ee960bce8793879b488d3 /deps/amqp10_common/codegen.py | |
parent | afa2c2bf6c7e0e9b63f4fb53dc931c70388e1c82 (diff) | |
parent | 9f6d64ec4a4b1eeac24d7846c5c64fd96798d892 (diff) | |
download | rabbitmq-server-git-stream-timestamp-offset.tar.gz |
Merge remote-tracking branch 'origin/master' into stream-timestamp-offsetstream-timestamp-offset
Diffstat (limited to 'deps/amqp10_common/codegen.py')
-rwxr-xr-x | deps/amqp10_common/codegen.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/deps/amqp10_common/codegen.py b/deps/amqp10_common/codegen.py new file mode 100755 index 0000000000..dc4480a181 --- /dev/null +++ b/deps/amqp10_common/codegen.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import sys +import os +import re +from xml.dom.minidom import parse + +def safe(str): + return str.replace('-', '_') + +class AMQPType: + def __init__(self, dom): + self.name = safe(dom.getAttribute('name')) + self.source = dom.getAttribute('source') + self.desc = dom.getElementsByTagName('descriptor')[0].getAttribute('name') + self.code = dom.getElementsByTagName('descriptor')[0].getAttribute('code') + self.number = parse_code(self.code) + self.fields = [safe(el.getAttribute('name')) for el in + dom.getElementsByTagName('field')] + # These are 'restricted' types, rather than composite, so they + # do not have defined fields. + if self.desc in ['amqp:data:binary', 'amqp:amqp-sequence:list', + 'amqp:amqp-value:*', 'amqp:application-properties:map', + 'amqp:delivery-annotations:map', + 'amqp:message-annotations:map', 'amqp:footer:map']: + self.fields = ['content'] + + def define(self): + return ('SYMBOL_%s' % self.name.upper(), self.desc) + +class AMQPDefines: + def __init__(self, dom): + self.name = safe(dom.getAttribute('name')) + self.source = dom.getAttribute('source') + self.options = [(self.name.upper() + '_' + + (safe(el.getAttribute('name')).upper()), + el.getAttribute('value')) for el in + dom.getElementsByTagName('choice')] + +def print_erl(types): + print("""-module(amqp10_framing0). +-export([record_for/1, fields/1, encode/1, symbol_for/1, number_for/1]). +-include("amqp10_framing.hrl").""") + for t in types: + print("""record_for({symbol, <<"%s">>}) -> + #'v1_0.%s'{};""" % (t.desc, t.name)) + if t.code: + print("""record_for({_, %d}) -> + #'v1_0.%s'{};""" % (t.number, t.name)) + print("%% %s\n" % t.code) + + print("""record_for(Other) -> exit({unknown, Other}). + +""") + for t in types: + print("""fields(#'v1_0.%s'{}) -> record_info(fields, 'v1_0.%s');""" % (t.name, t.name)) + print("""fields(_Other) -> unknown. + +""") + for t in types: + print("""encode(Frame = #'v1_0.%s'{}) -> + amqp10_framing:encode_described('%s', %s, Frame);""" % (t.name, t.source, t.number)) + print("""encode(undefined) -> null; +encode(Other) -> Other. + +""") + for t in types: + print("""symbol_for(#'v1_0.%s'{}) -> + {symbol, <<"%s">>};""" % (t.name, t.desc)) + print("""symbol_for(Other) -> exit({unknown, Other}). + +""") + for t in types: + print("""number_for(#'v1_0.%s'{}) -> + {ulong, %s};""" % (t.name, t.number)) + print("""number_for(Other) -> exit({unknown, Other}).""") + +def print_hrl(types, defines): + for t in types: + print("""-record('v1_0.%s', {%s}).""" % (t.name, ", ".join(t.fields))) + print_define(t.define(), 'symbol') + for d in defines: + if len(d.options) > 0: + print(""" %% %s""" % (d.name)) + for opt in d.options: + print_define(opt, d.source) + print(""" +-define(DESCRIBED, 0:8). +-define(DESCRIBED_BIN, <<?DESCRIBED>>). +""") + + +def print_define(opt, source): + (name, value) = opt + if source == 'symbol': + quoted = '<<"%s">>' % value + else: + quoted = value + print("""-define(V_1_0_%s, {%s, %s}).""" % (name, source, quoted)) + +def want_type(el): + descriptors = el.getElementsByTagName('descriptor') + return len(descriptors) > 0 + +def want_define(el): + klass = el.getAttribute('class') + return klass == 'restricted' + +def parse_code(code): + res = re.match('0x([0-9a-fA-F]{8,8}):0x([0-9a-fA-F]{8,8})', code) + return res and int(res.group(1) + res.group(2), 16) + +types = [] +defines = [] +mode = sys.argv[1] + +for file in sys.argv[2:]: + tree = parse(file) + types.extend([AMQPType(el) for el in tree.getElementsByTagName('type') + if want_type(el)]) + defines.extend([AMQPDefines(el) for el in tree.getElementsByTagName('type') + if want_define(el)]) + +if mode == 'erl': + print_erl(types) +elif mode == 'hrl': + print_hrl(types, defines) +else: + raise "Mode != erl or hrl" |