summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <scvalex@gmail.com>2010-06-03 14:47:25 +0100
committerAlexandru Scvortov <scvalex@gmail.com>2010-06-03 14:47:25 +0100
commit6f22a1a8aa9051bba1d9bf24250a466310f2bb53 (patch)
tree1af7c4601a549f5bb15342d9c358b627f6bc1bd1
parent24d60ac49c1bdadf96f3f38b48078356aefead63 (diff)
downloadrabbitmq-server-git-6f22a1a8aa9051bba1d9bf24250a466310f2bb53.tar.gz
rabbit_framing_spec.hrl is now generated
-rw-r--r--Makefile9
-rw-r--r--codegen.py125
-rw-r--r--include/rabbit_framing_spec.hrl62
3 files changed, 85 insertions, 111 deletions
diff --git a/Makefile b/Makefile
index 982780c747..99e0e50f4a 100644
--- a/Makefile
+++ b/Makefile
@@ -11,10 +11,10 @@ SOURCE_DIR=src
EBIN_DIR=ebin
INCLUDE_DIR=include
DOCS_DIR=docs
-INCLUDES=$(wildcard $(INCLUDE_DIR)/*.hrl) $(INCLUDE_DIR)/rabbit_framing.hrl
+INCLUDES=$(wildcard $(INCLUDE_DIR)/*.hrl) $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl
SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) $(SOURCE_DIR)/rabbit_framing.erl $(USAGES_ERL)
BEAM_TARGETS=$(patsubst $(SOURCE_DIR)/%.erl, $(EBIN_DIR)/%.beam, $(SOURCES))
-TARGETS=$(EBIN_DIR)/rabbit.app $(INCLUDE_DIR)/rabbit_framing.hrl $(BEAM_TARGETS)
+TARGETS=$(EBIN_DIR)/rabbit.app $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl $(BEAM_TARGETS)
WEB_URL=http://stage.rabbitmq.com/
MANPAGES=$(patsubst %.xml, %.gz, $(wildcard $(DOCS_DIR)/*.[0-9].xml))
WEB_MANPAGES=$(patsubst %.xml, %.man.xml, $(wildcard $(DOCS_DIR)/*.[0-9].xml) $(DOCS_DIR)/rabbitmq-service.xml)
@@ -84,6 +84,9 @@ $(EBIN_DIR)/%.beam:
$(INCLUDE_DIR)/rabbit_framing.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
$(PYTHON) codegen.py header $(AMQP_SPEC_JSON_FILES) $@
+$(INCLUDE_DIR)/rabbit_framing_spec.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
+ $(PYTHON) codegen.py spec $(AMQP_SPEC_JSON_FILES) $@
+
$(SOURCE_DIR)/rabbit_framing.erl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
$(PYTHON) codegen.py body $(AMQP_SPEC_JSON_FILES) $@
@@ -110,7 +113,7 @@ $(BASIC_PLT): $(BEAM_TARGETS)
clean:
rm -f $(EBIN_DIR)/*.beam
rm -f $(EBIN_DIR)/rabbit.app $(EBIN_DIR)/rabbit.boot $(EBIN_DIR)/rabbit.script $(EBIN_DIR)/rabbit.rel
- rm -f $(INCLUDE_DIR)/rabbit_framing.hrl $(SOURCE_DIR)/rabbit_framing.erl codegen.pyc
+ rm -f $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl $(SOURCE_DIR)/rabbit_framing.erl codegen.pyc
rm -f $(DOCS_DIR)/*.[0-9].gz $(DOCS_DIR)/*.man.xml $(DOCS_DIR)/*.erl $(USAGES_ERL)
rm -f $(RABBIT_PLT)
rm -f $(DEPS_FILE)
diff --git a/codegen.py b/codegen.py
index b8152423b4..6fcc67d0b1 100644
--- a/codegen.py
+++ b/codegen.py
@@ -314,6 +314,21 @@ def genErl(spec):
bitvalue(true) -> 1;
bitvalue(false) -> 0;
bitvalue(undefined) -> 0.
+
+%% Method signatures
+-spec(lookup_method_name/1 :: (amqp_method()) -> amqp_method_name()).
+-spec(method_id/1 :: (amqp_method_name()) -> amqp_method()).
+-spec(method_has_content/1 :: (amqp_method_name()) -> boolean()).
+-spec(is_method_synchronous/1 :: (amqp_method_record()) -> boolean()).
+-spec(method_record/1 :: (amqp_method_name()) -> amqp_method_record()).
+-spec(method_fieldnames/1 :: (amqp_method_name()) -> [amqp_method_field_name()]).
+-spec(decode_method_fields/2 :: (amqp_method_name(), binary()) -> amqp_method_record()).
+-spec(decode_properties/2 :: (non_neg_integer(), binary()) -> amqp_property_record()).
+-spec(encode_method_fields/1 :: (amqp_method_record()) -> binary()).
+-spec(encode_properties/1 :: (amqp_method_record()) -> binary()).
+-spec(lookup_amqp_exception/1 :: (amqp_exception()) -> {boolean(), amqp_exception_code(), binary()}).
+-spec(amqp_exception/1 :: (amqp_exception_code()) -> amqp_exception()).
+
"""
for m in methods: genLookupMethodName(m)
print "lookup_method_name({_ClassId, _MethodId} = Id) -> exit({unknown_method_id, Id})."
@@ -390,10 +405,6 @@ def genHrl(spec):
thingsPerLine = typesPerLine)
return "-type(%s ::\n\t%s)." % (typeName, sTs)
- def prettySpec(fName, fArgs, fValue, fModule = "rabbit_framing"):
- args = ", ".join(fArgs)
- return "-spec(%s:%s :: (%s) -> %s)." % (fModule, fName, args, fValue)
-
methods = spec.allMethods()
printFileHeader()
@@ -432,49 +443,68 @@ def genHrl(spec):
["'%s'" % erlangConstantName(c).lower() for (c, v, cls) in spec.constants])
print prettyType("amqp_exception_code()",
["%i" % v for (c, v, cls) in spec.constants])
+ # classIds = set()
+ # for m in methods:
+ # classIds.add(m.klass.index)
+ # print prettyType("amqp_class_id()",
+ # ["%i" % ci for ci in classIds])
+
+def genSpec(spec):
+ def multiLineFormat(things, prologue, separator, lineSeparator, epilogue, thingsPerLine = 4):
+ r = [prologue]
+ i = 0
+ for t in things:
+ if i != 0:
+ if i % thingsPerLine == 0:
+ r += [lineSeparator]
+ else:
+ r += [separator]
+ r += [t]
+ i += 1
+ r += [epilogue]
+ return "".join(r)
+
+ def prettyType(typeName, subTypes, typesPerLine = 4):
+ sTs = multiLineFormat(subTypes,
+ "( ", " | ", "\n\t| ", " )",
+ thingsPerLine = typesPerLine)
+ return "-type(%s ::\n\t%s)." % (typeName, sTs)
+
+ methods = spec.allMethods()
+
+ printFileHeader()
+ print """% Hard-coded types
+-type(amqp_field_type() ::
+ 'longstr' | 'signedint' | 'decimal' | 'timestamp' |
+ 'table' | 'byte' | 'double' | 'float' | 'long' |
+ 'short' | 'bool' | 'binary' | 'void').
+-type(amqp_property_type() ::
+ 'shortstr' | 'longstr' | 'octet' | 'shortint' | 'longint' |
+ 'longlongint' | 'timestamp' | 'bit' | 'table').
+%% we could make this more precise but ultimately are limited by
+%% dialyzer's lack of support for recursive types
+-type(amqp_table() :: [{binary(), amqp_field_type(), any()}]).
+%% TODO: make this more precise
+%% TODO: Are these tuples of the form {P_basic_property, any()} ?
+-type(amqp_properties() :: tuple()).
+%% TODO: make this more precise I can't find any restriction on this.
+%% Should I just check if it's 16bit ?
+-type(channel_number() :: non_neg_integer()).
+-type(resource_name() :: binary()).
+-type(routing_key() :: binary()).
+-type(username() :: binary()).
+-type(password() :: binary()).
+-type(vhost() :: binary()).
+-type(ctag() :: binary()).
+-type(exchange_type() :: atom()).
+-type(binding_key() :: binary()).
+"""
+ print "% Auto-generated types"
classIds = set()
- for m in methods:
+ for m in spec.allMethods():
classIds.add(m.klass.index)
- #print prettyType("amqp_class_id()",
- # ["%i" % ci for ci in classIds])
-
- print "%% Method signatures"
- print prettySpec("lookup_method_name/1",
- ["amqp_method()"],
- "amqp_method_name()")
- print prettySpec("method_id/1",
- ["amqp_method_name()"],
- "amqp_method()")
- print prettySpec("method_has_content/1",
- ["amqp_method_name()"],
- "boolean()")
- print prettySpec("is_method_synchronous/1",
- ["amqp_method_record()"],
- "boolean()")
- print prettySpec("method_record/1",
- ["amqp_method_name()"],
- "amqp_method_record()")
- print prettySpec("method_fieldnames/1",
- ["amqp_method_name()"],
- "[amqp_method_field_name()]")
- print prettySpec("decode_method_fields/2",
- ["amqp_method_name()", "binary()"],
- "amqp_method_record()")
- print prettySpec("decode_properties/2",
- ["non_neg_integer()", "binary()"],
- "amqp_property_record()")
- print prettySpec("encode_method_fields/1",
- ["amqp_method_record()"],
- "binary()")
- print prettySpec("encode_properties/1",
- ["amqp_method_record()"],
- "binary()")
- print prettySpec("lookup_amqp_exception/1",
- ["amqp_exception()"],
- "{boolean(), amqp_exception_code(), binary()}")
- print prettySpec("amqp_exception/1",
- ["amqp_exception_code()"],
- "amqp_exception()")
+ print prettyType("amqp_class_id()",
+ ["%i" % ci for ci in classIds])
def generateErl(specPath):
genErl(AmqpSpec(specPath))
@@ -482,6 +512,9 @@ def generateErl(specPath):
def generateHrl(specPath):
genHrl(AmqpSpec(specPath))
+def generateSpec(specPath):
+ genSpec(AmqpSpec(specPath))
+
if __name__ == "__main__":
- do_main(generateHrl, generateErl)
+ do_main(generateHrl, generateSpec, generateErl)
diff --git a/include/rabbit_framing_spec.hrl b/include/rabbit_framing_spec.hrl
deleted file mode 100644
index 5344695e92..0000000000
--- a/include/rabbit_framing_spec.hrl
+++ /dev/null
@@ -1,62 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (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.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-%% License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developers of the Original Code are LShift Ltd,
-%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
-%%
-%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
-%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
-%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
-%% Technologies LLC, and Rabbit Technologies Ltd.
-%%
-%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
-%% Ltd. Portions created by Cohesive Financial Technologies LLC are
-%% Copyright (C) 2007-2010 Cohesive Financial Technologies
-%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
-%% (C) 2007-2010 Rabbit Technologies Ltd.
-%%
-%% All Rights Reserved.
-%%
-%% Contributor(s): ______________________________________.
-%%
-
-%% TODO: much of this should be generated
-
--type(amqp_field_type() ::
- 'longstr' | 'signedint' | 'decimal' | 'timestamp' |
- 'table' | 'byte' | 'double' | 'float' | 'long' |
- 'short' | 'bool' | 'binary' | 'void').
--type(amqp_property_type() ::
- 'shortstr' | 'longstr' | 'octet' | 'shortint' | 'longint' |
- 'longlongint' | 'timestamp' | 'bit' | 'table').
-%% we could make this more precise but ultimately are limited by
-%% dialyzer's lack of support for recursive types
--type(amqp_table() :: [{binary(), amqp_field_type(), any()}]).
-%% TODO Remove this
--type(amqp_class_id() ::
- ( 100 | 70 | 40 | 10
- | 110 | 80 | 50 | 20
- | 120 | 90 | 60 | 30 )).
-%% TODO: make this more precise
-%% TODO: Are these tuples of the form {P_basic_property, any()} ?
--type(amqp_properties() :: tuple()).
-%% TODO: make this more precise I can't find any restriction on this.
-%% Should I just check if it's 16bit ?
--type(channel_number() :: non_neg_integer()).
--type(resource_name() :: binary()).
--type(routing_key() :: binary()).
--type(username() :: binary()).
--type(password() :: binary()).
--type(vhost() :: binary()).
--type(ctag() :: binary()).
--type(exchange_type() :: atom()).
--type(binding_key() :: binary()).