You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2008/02/27 17:37:59 UTC
svn commit: r631638 - in /incubator/qpid/trunk/qpid/cpp: ./ rubygen/
rubygen/0-10/ rubygen/99-0/ rubygen/templates/ src/ src/qpid/amqp_0_10/
src/tests/ xml/
Author: aconway
Date: Wed Feb 27 08:37:48 2008
New Revision: 631638
URL: http://svn.apache.org/viewvc?rev=631638&view=rev
Log:
Generate code for both 0-99 preview and 0-10 final specs .
0-10 final: extended code generation and non-generated support classes.
Added:
incubator/qpid/trunk/qpid/cpp/rubygen/0-10/
incubator/qpid/trunk/qpid/cpp/rubygen/0-10/amqp_0_10.rb
- copied, changed from r631476, incubator/qpid/trunk/qpid/cpp/rubygen/templates/amqp_0_10.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/
- copied from r631476, incubator/qpid/trunk/qpid/cpp/rubygen/templates/
incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp (with props)
Removed:
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/amqp_0_10.rb
incubator/qpid/trunk/qpid/cpp/rubygen/templates/
Modified:
incubator/qpid/trunk/qpid/cpp/configure.ac
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyConstVisitor.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyDefaultVisitor.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodHolder.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Operations.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/OperationsInvoker.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Proxy.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Session.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/all_method_bodies.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/constants.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/frame_body_lists.rb
incubator/qpid/trunk/qpid/cpp/rubygen/99-0/structs.rb
incubator/qpid/trunk/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb
incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb
incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
incubator/qpid/trunk/qpid/cpp/rubygen/generate
incubator/qpid/trunk/qpid/cpp/src/Makefile.am
incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h
incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.h
incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp
incubator/qpid/trunk/qpid/cpp/xml/cluster.xml
Modified: incubator/qpid/trunk/qpid/cpp/configure.ac
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/configure.ac?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/configure.ac (original)
+++ incubator/qpid/trunk/qpid/cpp/configure.ac Wed Feb 27 08:37:48 2008
@@ -122,11 +122,11 @@
test -z "$RUBY" && AC_MSG_ERROR([Missing ruby installation (try "yum install ruby").])
specdir=`pwd`/$srcdir/../specs
-AMQP_XML=$specdir/amqp.0-10-preview.xml
-AC_SUBST(AMQP_XML)
-ls $AMQP_XML >/dev/null 2>&1 || generate=no
-
-AM_CONDITIONAL([GENERATE], [test x$generate = xyes])
+AMQP_PREVIEW_XML=$specdir/amqp.0-10-preview.xml
+AMQP_FINAL_XML=$specdir/amqp.0-10.xml
+AC_SUBST(AMQP_PREVIEW_XML)
+AC_SUBST(AMQP_FINAL_XML)
+AM_CONDITIONAL([GENERATE], [ls $AMQP_FINAL_XML >/dev/null])
# URL and download URL for the package.
URL=http://rhm.et.redhat.com/qpidc
Copied: incubator/qpid/trunk/qpid/cpp/rubygen/0-10/amqp_0_10.rb (from r631476, incubator/qpid/trunk/qpid/cpp/rubygen/templates/amqp_0_10.rb)
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/0-10/amqp_0_10.rb?p2=incubator/qpid/trunk/qpid/cpp/rubygen/0-10/amqp_0_10.rb&p1=incubator/qpid/trunk/qpid/cpp/rubygen/templates/amqp_0_10.rb&r1=631476&r2=631638&rev=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/templates/amqp_0_10.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/0-10/amqp_0_10.rb Wed Feb 27 08:37:48 2008
@@ -3,62 +3,173 @@
require 'cppgen'
class Amqp_0_10 < CppGen
+ ArrayTypes={
+ "str16-array" => "Str16",
+ "amqp-host-array" => "connection::AmqpHostUrl",
+ "command-fragments" => "session::CommandFragment",
+ "in-doubt" => "dtx::Xid"
+ }
def initialize(outdir, amqp)
super(outdir, amqp)
- @namespace="qpid::amqp_0_10"
- @filename="qpid/amqp_0_10"
+ @ns="qpid::amqp_0_10"
+ @dir="qpid/amqp_0_10"
end
- def action_h(a, base)
- struct(a.cppname, "public #{base}") {
- genl "static const uint8_t CODE=#{a.code};"
- a.fields.each { |f|
- genl "#{(f.type_.amqp2cpp)} #{f.cppname};"
+ # domains
+
+ def domain_h(d)
+ typename=d.name.typename
+ if d.enum
+ scope("enum #{typename} {", "};") {
+ genl d.enum.choices.map { |c| "#{c.name.constname} = #{c.value}" }.join(",\n")
}
+ elsif d.type_ == "array"
+ @array_domains << "typedef Array<#{ArrayTypes[d.name]}> #{typename};\n"
+ else
+ genl "typedef #{d.type_.amqp2cpp} #{typename};"
+ end
+ end
+
+ # structs
+
+ # field members and MemberInfo
+ def member_h(m)
+ genl "static const MemberInfo INFO;"
+ m.fields.each { |f| genl "#{f.type_.amqp2cpp} #{f.cppname};" }
+ end
+
+ # MemberInfo constant definition.
+ def member_cpp(m)
+ infotype=m.is_a?(AmqpStruct) ? "Struct1Info" : "MemberInfo"
+ scope("{infotype} #{m.classname}::INFO = {","};") {
+ inits=[]
+ inits << (m.parent.is_a?(AmqpClass) ? "&CLASS_INFO" : "0")
+ inits << m.name << (m.code or "0");
+ if m.is_a?(AmqpStruct)
+ inits << (m.size or 0) << (m.pack or 0)
+ end
+ genl inits.join(", ")
}
end
- def action_cpp(a, base)
-
+ def struct_h(s) struct(s.classname, "public Struct") { member_h s }; end
+ def struct_cpp(s) member_cpp s; end
+ def gen_structs()
+ file="#{@dir}/structs"
+ h_file(file) {
+ include "#{@dir}/built_in_types.h"
+ include "#{@dir}/helpers.h"
+ include "<boost/call_traits.hpp>"
+ genl "using boost::call_traits;"
+ namespace(@ns) {
+ @amqp.structs.each { |s| struct_h s }
+ each_class_ns { |c| c.structs.each { |s| struct_h s }}
+ }
+ }
+ cpp_file(file) {
+ include file
+ namespace(@ns) {
+ @amqp.structs.each { |s| struct_h s }
+ each_class_ns { |c| c.structs.each { |s| struct_cpp s }}
+ }
+ }
end
- def gen_amqp_0_10_h
- h_file("#{@filename}.h") {
- namespace(@namespace) {
- @amqp.classes.each { |cl|
- namespace(cl.cppname) {
- struct("ClassInfo") {
- genl "static const uint8_t CODE=#{cl.code};"
- genl "static const char* NAME;"
- }
- cl.commands.each { |c| action_h c, "Command"}
- cl.controls.each { |c| action_h c, "Control"}
- }
+ # command and control
+
+ def action_h(a)
+ name=a.name.typename
+ struct(name, "public #{a.base}") {
+ genl "#{name}() {}"
+ scope("#{name}(",");") { genl a.parameters } unless a.fields.empty?
+ scope("template <class T> void invoke(T& target) {","}") {
+ scope("target.#{a.funcname}(", ");") { genl a.values }
+ }
+ scope("template <class S> void serialize(S& s) {","}") {
+ gen "s"
+ a.fields.each { |f| gen "(#{f.cppname})"}
+ genl ";"
+ } unless a.fields.empty?
+ member_h a
+ }
+ end
+
+ def action_cpp(a) # command or control
+ # ctor
+ scope("#{a.classname}::#{a.classname}(",") :") { genl a.parameters }
+ indent() { genl a.initializers }
+ genl "{}"
+ # member constants
+ member_cpp a
+ end
+
+ def class_h(c)
+ genl "extern const ClassInfo CLASS_INFO;"
+ @array_domains=""
+ c.domains.each { |d| domain_h d }
+ c.structs.each { |s| struct_h s }
+ gen @array_domains
+ end
+
+ def class_cpp(c)
+ genl "const ClassInfo CLASS_INFO = { #{c.code}, \"#{c.name}\" };"
+ c.structs.each { |s| struct_cpp s }
+ end
+
+ def gen_specification()
+ h_file("#{@dir}/specification") {
+ include "#{@dir}/built_in_types"
+ include "#{@dir}/helpers"
+ include "<boost/call_traits.hpp>"
+ genl "using boost::call_traits;"
+ namespace(@ns) {
+ # We don't generate top-level domains, as they have clashing values.
+ each_class_ns { |c| class_h c }
+ each_class_ns { |c| c.actions.each { |a| action_h a}
+ }
+ }
+ }
+ cpp_file("#{@dir}/specification") {
+ include "#{@dir}/specification"
+ namespace(@ns) {
+ each_class_ns { |c| class_cpp c }
+ each_class_ns { |c| c.actions.each { |a| action_cpp a}
}
}
}
end
-
- def gen_amqp_0_10_cpp
- cpp_file("#{@filename}.cpp") {
- include @filename
-
- namespace(@namespace) {
- @amqp.classes.each { |cl|
- namespace(cl.cppname) {
- genl "static const char* ClassInfo::NAME=\"#{cl.name};"
+
+ def gen_proxy()
+ h_file("#{@dir}/Proxy.h") {
+ include "#{@dir}/specification"
+ namespace(@ns) {
+ genl "template <class F, class R=F::result_type>"
+ cpp_class("ProxyTemplate") {
+ public
+ genl "ProxyTemplate(F f) : functor(f) {}"
+ @amqp.classes.each { |c|
+ c.actions.each { |a|
+ scope("R #{a.funcname}(", ")") { genl a.parameters }
+ scope() {
+ var=a.name.funcname
+ scope("#{a.classname} #{var}(",");") { genl a.arguments }
+ genl "return functor(#{var});"
+ }
+ }
}
+ private
+ genl "F functor;"
}
}
}
end
-
+
def generate
- gen_amqp_0_10_h
- gen_amqp_0_10_cpp
+ gen_specification
+ gen_proxy
end
end
-Amqp_0_10.new(Outdir, Amqp).generate();
+Amqp_0_10.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyConstVisitor.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyConstVisitor.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyConstVisitor.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyConstVisitor.rb Wed Feb 27 08:37:48 2008
@@ -23,5 +23,5 @@
end
end
-MethodBodyConstVisitorGen.new(Outdir, Amqp).generate();
+MethodBodyConstVisitorGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyDefaultVisitor.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyDefaultVisitor.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyDefaultVisitor.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodBodyDefaultVisitor.rb Wed Feb 27 08:37:48 2008
@@ -31,5 +31,5 @@
end
end
-MethodBodyDefaultVisitorGen.new(Outdir, Amqp).generate();
+MethodBodyDefaultVisitorGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodHolder.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodHolder.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodHolder.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/MethodHolder.rb Wed Feb 27 08:37:48 2008
@@ -96,5 +96,5 @@
end
end
-MethodHolderGen.new(Outdir, Amqp).generate();
+MethodHolderGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Operations.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Operations.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Operations.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Operations.rb Wed Feb 27 08:37:48 2008
@@ -91,6 +91,6 @@
end
end
-OperationsGen.new("client",ARGV[0], Amqp).generate()
-OperationsGen.new("server",ARGV[0], Amqp).generate()
+OperationsGen.new("client",ARGV[0], $amqp).generate()
+OperationsGen.new("server",ARGV[0], $amqp).generate()
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/OperationsInvoker.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/OperationsInvoker.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/OperationsInvoker.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/OperationsInvoker.rb Wed Feb 27 08:37:48 2008
@@ -88,5 +88,5 @@
end
end
-OperationsInvokerGen.new("client",ARGV[0], Amqp).generate()
-OperationsInvokerGen.new("server",ARGV[0], Amqp).generate()
+OperationsInvokerGen.new("client",ARGV[0], $amqp).generate()
+OperationsInvokerGen.new("server",ARGV[0], $amqp).generate()
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Proxy.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Proxy.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Proxy.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Proxy.rb Wed Feb 27 08:37:48 2008
@@ -62,7 +62,9 @@
include "<sstream>"
include "#{@classname}.h"
include "qpid/framing/amqp_types_full.h"
- Amqp.methods_on(@chassis).each { |m| include "qpid/framing/"+m.body_name }
+ @amqp.methods_on(@chassis).each {
+ |m| include "qpid/framing/"+m.body_name
+ }
genl
namespace("qpid::framing") {
genl "#{@classname}::#{@classname}(FrameHandler& f) :"
@@ -75,6 +77,6 @@
end
-ProxyGen.new("client", Outdir, Amqp).generate;
-ProxyGen.new("server", Outdir, Amqp).generate;
+ProxyGen.new("client", $outdir, $amqp).generate;
+ProxyGen.new("server", $outdir, $amqp).generate;
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Session.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Session.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Session.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/Session.rb Wed Feb 27 08:37:48 2008
@@ -190,6 +190,6 @@
end
end
-SessionNoKeywordGen.new(ARGV[0], Amqp).generate()
-SessionGen.new(ARGV[0], Amqp).generate()
+SessionNoKeywordGen.new(ARGV[0], $amqp).generate()
+SessionGen.new(ARGV[0], $amqp).generate()
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/all_method_bodies.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/all_method_bodies.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/all_method_bodies.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/all_method_bodies.rb Wed Feb 27 08:37:48 2008
@@ -17,5 +17,5 @@
end
end
-AllMethodBodiesGen.new(Outdir, Amqp).generate();
+AllMethodBodiesGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/constants.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/constants.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/constants.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/constants.rb Wed Feb 27 08:37:48 2008
@@ -78,5 +78,5 @@
end
end
-ConstantsGen.new(Outdir, Amqp).generate();
+ConstantsGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/frame_body_lists.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/frame_body_lists.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/frame_body_lists.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/frame_body_lists.rb Wed Feb 27 08:37:48 2008
@@ -26,6 +26,6 @@
end
end
-FrameBodyListsGen.new(ARGV[0], Amqp).generate;
+FrameBodyListsGen.new(ARGV[0], $amqp).generate;
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/99-0/structs.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/99-0/structs.rb?rev=631638&r1=631476&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/99-0/structs.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/99-0/structs.rb Wed Feb 27 08:37:48 2008
@@ -534,5 +534,5 @@
end
end
-StructGen.new(ARGV[0], Amqp).generate()
+StructGen.new(ARGV[0], $amqp).generate()
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb Wed Feb 27 08:37:48 2008
@@ -30,5 +30,5 @@
end
end
-MethodBodyDefaultVisitorGen.new(Outdir, Amqp).generate();
+MethodBodyDefaultVisitorGen.new($outdir, $amqp).generate();
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb Wed Feb 27 08:37:48 2008
@@ -119,7 +119,16 @@
# List of children of type elname, or all children if elname
# not specified.
def children(elname=nil)
- @cache_children[elname] ||= @children.select { |c| elname==c.xml.name }
+ if elname
+ @cache_children[elname] ||= @children.select { |c| elname==c.xml.name }
+ else
+ @children
+ end
+ end
+
+ def each_descendant(&block)
+ yield self
+ @children.each { |c| c.each_descendant(&block) }
end
# Look up child of type elname with attribute name.
@@ -264,17 +273,21 @@
amqp_attr_reader :implement
end
-class AmqpControl < AmqpElement
+# Base class for command and control.
+class AmqpAction < AmqpElement
def initialize(xml,amqp) super; end
amqp_child_reader :implement, :field, :response
amqp_attr_reader :code
end
-class AmqpCommand < AmqpElement
+class AmqpControl < AmqpAction
+ def initialize(xml,amqp) super; end
+end
+
+class AmqpCommand < AmqpAction
def initialize(xml,amqp) super; end
- amqp_child_reader :implement, :field, :exception, :response
+ amqp_child_reader :exception
amqp_single_child_reader :result, :segments
- amqp_attr_reader :code
end
class AmqpClass < AmqpElement
@@ -295,6 +308,8 @@
def l4?() # preview
!["connection", "session", "execution"].include?(name)
end
+
+ def actions() controls+commands; end
end
class AmqpType < AmqpElement
@@ -321,6 +336,8 @@
super(xml, nil)
end
+ def merge(root) xml_merge(xml, root.xml); end
+
def version() major + "-" + minor; end
# Find the element corresponding to an amqp dotted name.
@@ -370,25 +387,30 @@
def initialize (outdir, amqp)
@amqp=amqp
@outdir=outdir
- @prefix='' # For indentation or comments.
+ @prefix=[''] # For indentation or comments.
@indentstr=' ' # One indent level.
@outdent=2
Pathname.new(@outdir).mkpath unless @outdir=="-" or File.directory?(@outdir)
end
# Create a new file, set @out.
- def file(file)
+ def file(file, &block)
GenFiles.add file
if (@outdir != "-")
- path=Pathname.new "#{@outdir}/#{file}"
- path.parent.mkpath
+ @path=Pathname.new "#{@outdir}/#{file}"
+ @path.parent.mkpath
@out=String.new # Generate in memory first
- yield # Generate to @out
- if path.exist? and path.read == @out
- puts "Skipped #{path} - unchanged" # Dont generate if unchanged
+ if block then yield; endfile; end
+ end
+ end
+
+ def endfile()
+ if @outdir != "-"
+ if @path.exist? and @path.read == @out
+ puts "Skipped #{@path} - unchanged" # Dont generate if unchanged
else
- path.open('w') { |f| f << @out }
- puts "Generated #{path}"
+ @path.open('w') { |f| f << @out }
+ puts "Generated #{@path}"
end
end
end
@@ -396,7 +418,7 @@
# Append multi-line string to generated code, prefixing each line.
def gen (str)
str.each_line { |line|
- @out << @prefix unless @midline
+ @out << @prefix.last unless @midline
@out << line
@midline = nil
}
@@ -411,23 +433,25 @@
end
# Generate code with added prefix.
- def prefix(add)
- save=@prefix
- @prefix+=add
- yield
- @prefix=save
+ def prefix(add, &block)
+ @prefix.push @prefix.last+add
+ if block then yield; endprefix; end
+ end
+
+ def endprefix()
+ @prefix.pop
end
# Generate indented code
def indent(n=1,&block) prefix(@indentstr * n,&block); end
+ alias :endindent :endprefix
# Generate outdented code
def outdent(&block)
- save=@prefix
- @prefix=@prefix[0...-2]
- yield
- @prefix=save
+ @prefix.push @prefix.last[0...-2]
+ if block then yield; endprefix; end
end
+ alias :endoutdent :endprefix
attr_accessor :out
end
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Wed Feb 27 08:37:48 2008
@@ -55,12 +55,20 @@
class String
def cppsafe() CppMangle.include?(self) ? self+"_" : self; end
+
def amqp2cpp()
path=split(".")
name=path.pop
- path.map! { |n| n.bars }
- (path << name.caps).join("::")
+ return name.typename if path.empty?
+ path.map! { |n| n.nsname }
+ return "amqp_0_10::"+(path << name.caps).join("::")
end
+
+ alias :typename :caps
+ alias :nsname :bars
+ alias :constname :shout
+ alias :funcname :lcaps
+ alias :varname :lcaps
end
# Hold information about a C++ type.
@@ -119,6 +127,7 @@
def cpptype() domain.cpptype; end
def bit?() domain.type_ == "bit"; end
def signature() cpptype.param+" "+cppname; end
+ def paramtype() "call_traits<#{type_.amqp2cpp}>::param_type"; end
end
class AmqpMethod
@@ -128,8 +137,40 @@
def body_name() parent.name.caps+name.caps+"Body"; end
end
+class AmqpAction
+ def nsname() name.namespace; end
+ def classname() name.typename; end
+ def funcname() parent.name.funcname + name.caps; end
+
+ def parameters()
+ fields.map { |f| "#{f.paramtype} #{f.cppname}_"}.join(",\n")
+ end
+
+ def arguments()
+ fields.map { |f| "#{f.cppname}_"}.join(",\n")
+ end
+
+ def values()
+ fields.map { |f| "#{f.cppname}"}.join(",\n")
+ end
+
+ def initializers()
+ fields.map { |f| "#{f.cppname}(#{f.cppname}_)}"}.join(",\n")
+ end
+
+end
+
+class AmqpCommand
+ def base() "Command"; end
+end
+
+class AmqpControl
+ def base() "Control"; end
+end
+
class AmqpClass
def cppname() name.caps; end
+ def nsname() name.nsname; end
end
class AmqpDomain
@@ -172,17 +213,20 @@
class AmqpStruct
def cpp_pack_type() AmqpDomain.lookup_type(pack()) or CppType.new("uint16_t"); end
- def cpptype() parent.cpptype; end
- def cppname() cpptype.name; end
+ def cpptype() parent.cpptype; end # preview
+ def cppname() cpptype.name; end # preview
+ def classname() name.typename; end
end
class CppGen < Generator
def initialize(outdir, *specs)
super(outdir,*specs)
+ # need to sort classes for dependencies
+ @actions=[] # Stack of end-scope actions
end
# Write a header file.
- def h_file(path)
+ def h_file(path, &block)
path = (/\.h$/ === path ? path : path+".h")
guard=path.upcase.tr('./-','_')
file(path) {
@@ -190,12 +234,12 @@
gen "#define #{guard}\n"
gen Copyright
yield
- gen "#endif /*!#{guard}*/\n"
+ gen "#endif /*!#{guard}*/\n"
}
end
# Write a .cpp file.
- def cpp_file(path)
+ def cpp_file(path, &block)
path = (/\.cpp$/ === path ? path : path+".cpp")
file(path) do
gen Copyright
@@ -209,10 +253,12 @@
genl "#include #{header}"
end
- def scope(open="{",close="}", &block)
- genl open; indent(&block); genl close
+ def scope(open="{",close="}", &block)
+ genl open
+ indent &block
+ genl close
end
-
+
def namespace(name, &block)
genl
names = name.split("::")
@@ -231,7 +277,7 @@
indent { gen "#{bases.join(",\n")}" }
end
genl
- scope("{","};") { yield }
+ scope("{","};", &block)
end
def struct(name, *bases, &block)
@@ -262,6 +308,11 @@
genl "/**"
prefix(" * ",&block)
genl " */"
+ end
+
+ # Generate code in namespace for each class
+ def each_class_ns()
+ @amqp.classes.each { |c| namespace(c.nsname) { yield c } }
end
end
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/generate
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/generate?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/generate (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/generate Wed Feb 27 08:37:48 2008
@@ -1,5 +1,6 @@
#!/usr/bin/env ruby
require 'amqpgen'
+require 'pathname'
#
# Run a set of code generation templates.
@@ -18,17 +19,39 @@
exit 1
end
-Outdir=ARGV[0]
-Specs=ARGV.grep(/\.xml$/)
-Amqp=AmqpRoot.new(*Specs)
+# Create array of specs by version
+def parse_specs(specs)
+ roots={ }
+ specs.each { |spec|
+ root=AmqpRoot.new(spec)
+ ver=root.version
+ if (roots[ver])
+ roots[ver].merge(root)
+ else
+ roots[ver]=root
+ end
+ }
+ roots
+end
# Run selected templates
if ARGV.any? { |arg| arg=="all" }
- templates=Dir["#{File.dirname __FILE__}/templates/*.rb"]
+ templates=Dir["#{File.dirname __FILE__}/*/*.rb"]
else
templates=ARGV.grep(/\.rb$/)
end
-templates.each { |t| load t }
+
+$outdir=ARGV[0]
+$models=parse_specs(ARGV.grep(/\.xml$/))
+templates.each { |t|
+ ver=Pathname.new(t).dirname.basename.to_s
+ $amqp=$models[ver]
+ if $amqp
+ load t
+ else
+ puts "Warning: skipping #{t}, no spec file for version #{ver}."
+ end
+}
def make_continue(lines) lines.join(" \\\n "); end
@@ -40,7 +63,7 @@
generator_files=Dir["**/*.rb"] << File.basename(__FILE__)
Dir.chdir dir
rgen_generator=generator_files.map{ |f| "$(rgen_dir)/#{f}" }
- rgen_srcs=GenFiles.get.map{ |f| "#{Outdir}/#{f}" }
+ rgen_srcs=GenFiles.get.map{ |f| "#{$outdir}/#{f}" }
File.open(makefile, 'w') { |out|
out << <<EOS
Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Wed Feb 27 08:37:48 2008
@@ -11,10 +11,12 @@
# This phony target is needed by generated makefile fragments:
force:
-# AMQP_XML is defined in ../configure.ac
-specs=@AMQP_XML@ $(top_srcdir)/xml/cluster.xml
-
if GENERATE
+
+# AMQP_PREVIEW_XML and AMQP_FINAL_XML are defined in ../configure.ac
+amqp_99_0_xml=@AMQP_PREVIEW_XML@ $(top_srcdir)/xml/cluster.xml
+amqp_0_10_xml=@AMQP_FINAL_XML@
+specs=$(amqp_99_0_xml) $(amqp_0_10_xml)
# Ruby generator.
rgen_dir=$(top_srcdir)/rubygen
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h Wed Feb 27 08:37:48 2008
@@ -29,6 +29,7 @@
#include <boost/array.hpp>
#include <stdint.h>
#include <string>
+#include <vector>
/**@file Mapping from built-in AMQP types to C++ types */
@@ -66,7 +67,7 @@
typedef float Float;
typedef framing::SequenceNumber SequenceNo;
using framing::Uuid;
-typedef sys::AbsTime DateTime;
+typedef sys::AbsTime Datetime;
typedef Decimal<Uint8, Int32> Dec32;
typedef Decimal<Uint8, Int64> Dec64;
@@ -89,14 +90,18 @@
typedef CodableString<Uint8, Uint32> Vbin32;
-/** FIXME aconway 2008-02-20: todo
-byte-ranges 2 byte ranges within a 64-bit payload
-sequence-set 2 ranged set representation
-map 0xa8 4 a mapping of keys to typed values
-list 0xa9 4 a series of consecutive type-value pairs
-array 0xaa 4 a defined length collection of values of a single type
-struct32 0xab 4 a coded struct with a 32-bit size
-*/
+// FIXME aconway 2008-02-26: array encoding
+template <class T> struct Array : public std::vector<T> {};
+
+// FIXME aconway 2008-02-26: Unimplemented types:
+struct ByteRanges {};
+struct SequenceSet {};
+struct Map {};
+struct List {};
+struct Struct32 {};
+
+// Top level enum definitions.
+enum SegmentType { CONTROL, COMMAND, HEADER, BODY };
}} // namespace qpid::amqp_0_10
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp?rev=631638&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp Wed Feb 27 08:37:48 2008
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.
+ *
+ */
+#include "helpers.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+Control::~Control() {}
+Command::~Command() {}
+Struct::~Struct() {}
+
+}} // namespace qpid::amqp_0_10
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.cpp
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.h?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/helpers.h Wed Feb 27 08:37:48 2008
@@ -8,7 +8,7 @@
* 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
+n * "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
@@ -27,43 +27,58 @@
namespace amqp_0_10 {
-struct ClassAttributes { uint8_t code; const char* name };
+/** Static information about an AMQP class */
+struct ClassInfo { uint8_t code; const char* name; };
-struct MemberAttributes {
- ClassAttributes class_;
- const char* name
- uint8_t code;
+/** Info about a class memeber - command, control or struct */
+struct MemberInfo {
+ ClassInfo* class_; // 0 for top level struct.
+ const char* name;
+ uint8_t code;
std::string fullName() const {
- return std::string(class_.name)+"."+name;
+ return std::string(class_->name)+"."+name;
}
};
-struct StructAttributes : public MemberAttributes { uint8_t size, pack; };
+/** Info about a struct */
+struct StructInfo : public MemberInfo { uint8_t size, pack; };
-static const ClassAttributes getClass(uint8_t code);
-static const MemberAttributes getCommand(uint8_t classCode, uint8_t code);
-static const MemberAttributes getControl(uint8_t classCode, uint8_t code);
+// Look up info by code.
+const ClassInfo& getClassInfo(uint8_t code);
+const MemberInfo& getCommandInfo(uint8_t classCode, uint8_t code);
+const MemberInfo& getControlInfo(uint8_t classCode, uint8_t code);
+const StructInfo& getStructInfo(uint8_t classCode, uint8_t code);
-struct Command : public Member {
+struct Command {
+ virtual ~Command();
class Visitor;
- virtual const MemberAttributes& attributes() const = 0;
+ virtual const MemberInfo& info() const = 0;
virtual void accept(Visitor&) const = 0;
};
-struct Control : public Member {
+struct Control {
+ virtual ~Control();
class Visitor;
- struct Attributes { uint8_t classCode, code };
-
- virtual const MemberAttributes& attributes() const = 0;
+ virtual const MemberInfo& info() const = 0;
virtual void accept(Visitor&) const = 0;
};
-
-struct Struct : public Member {
- virtual const StructAttributes& attributes() const = 0;
+struct Struct {
+ virtual ~Struct();
+ virtual const StructInfo& info() const = 0;
};
+/** Base class for generated enum domains.
+ * Enums map to classes for type safety and to provide separate namespaces
+ * for clashing values.
+ */
+struct Enum {
+ int value;
+ Enum(int v=0) : value(v) {}
+ operator int() const { return value; }
+ template <class S> void serialize(S &s) { s(value); }
+};
}} // namespace qpid::amqp_0_10
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp Wed Feb 27 08:37:48 2008
@@ -79,7 +79,7 @@
typedef mpl::vector<Bit, Boolean, Char, Int32, Int64, Int8, Uint16, CharUtf32, Uint32, Uint64, Bin8, Uint8>::type IntegralTypes;
typedef mpl::vector<Bin1024, Bin128, Bin16, Bin256, Bin32, Bin40, Bin512, Bin64, Bin72>::type BinTypes;
typedef mpl::vector<Double, Float>::type FloatTypes;
-typedef mpl::vector<SequenceNo, Uuid, DateTime, Dec32, Dec64> FixedSizeClassTypes;
+typedef mpl::vector<SequenceNo, Uuid, Datetime, Dec32, Dec64> FixedSizeClassTypes;
typedef mpl::vector<Vbin8, Str8Latin, Str8, Str8Utf16, Vbin16, Str16Latin, Str16, Str16Utf16, Vbin32> VariableSizeTypes;
@@ -106,7 +106,7 @@
void testValue(bool& b) { b = true; }
template <class T> typename boost::enable_if<boost::is_arithmetic<T> >::type testValue(T& n) { n=42; }
void testValue(long long& l) { l = 12345; }
-void testValue(DateTime& dt) { dt = qpid::sys::now(); }
+void testValue(Datetime& dt) { dt = qpid::sys::now(); }
void testValue(Uuid& uuid) { uuid=Uuid(true); }
template <class E, class M> void testValue(Decimal<E,M>& d) { d.exponent=2; d.mantissa=1234; }
void testValue(SequenceNo& s) { s = 42; }
Modified: incubator/qpid/trunk/qpid/cpp/xml/cluster.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/xml/cluster.xml?rev=631638&r1=631637&r2=631638&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/xml/cluster.xml (original)
+++ incubator/qpid/trunk/qpid/cpp/xml/cluster.xml Wed Feb 27 08:37:48 2008
@@ -20,7 +20,7 @@
-
-->
-<amqp major="0" minor="10" port="5672">
+<amqp major="99" minor="0" port="5672">
<class name = "cluster" index = "201">