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/28 18:53:53 UTC
svn commit: r632075 - in /incubator/qpid/trunk/qpid/cpp:
rubygen/0-10/specification.rb rubygen/amqpgen.rb rubygen/cppgen.rb
rubygen/generate src/tests/Makefile.am src/tests/ProxyTemplate.cpp
Author: aconway
Date: Thu Feb 28 09:53:47 2008
New Revision: 632075
URL: http://svn.apache.org/viewvc?rev=632075&view=rev
Log:
amqp_0_10::ProxyTemplate - tested & functional.
Added:
incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp (with props)
Modified:
incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.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/tests/Makefile.am
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb?rev=632075&r1=632074&r2=632075&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb Thu Feb 28 09:53:47 2008
@@ -46,11 +46,9 @@
genl "static const char* NAME;"
consts.each { |c| genl "static const uint8_t #{c.upcase}=#{x.send c or 0};"}
genl "static const uint8_t CLASS_CODE=#{x.containing_class.nsname}::CODE;"
- genl
- genl "#{x.classname}();"
- scope("#{x.classname}(",");") { genl x.parameters } unless x.fields.empty?
- genl
- genl "void accept(Visitor&) const;"
+ ctor_decl(x.classname,[])
+ ctor_decl(x.classname, x.parameters) unless x.fields.empty?
+ function_decl("void accept", ["Visitor&"], "const")
genl
yield if block
}
@@ -60,15 +58,9 @@
genl
genl "const char* #{x.classname}::NAME=\"#{x.fqname}\";"
genl
- genl "#{x.classname}::#{x.classname}() {}";
- genl
- if not x.fields.empty?
- scope("#{x.classname}::#{x.classname}(",") :") { genl x.parameters }
- indent() { genl x.initializers }
- genl "{}"
- genl
- end
- scope("void #{x.classname}::accept(Visitor&) const {","}") {
+ ctor_defn(x.classname) {}
+ ctor_defn(x.classname, x.parameters, x.initializers) {} if not x.fields.empty?
+ function_defn("void #{x.classname}::accept", ["Visitor&"], "const") {
genl "// FIXME aconway 2008-02-27: todo"
}
end
@@ -82,11 +74,10 @@
def action_h(a)
action_struct_h(a, a.base, ["code"]) {
- scope("template <class T> void invoke(T& target) {","}") {
- scope("target.#{a.funcname}(", ");") { genl a.values }
+ function_defn("template <class T> void invoke", ["T& target"]) {
+ genl "target.#{a.funcname}(#{a.values.join(', ')});"
}
- genl
- scope("template <class S> void serialize(S& s) {","}") {
+ function_defn("template <class S> void serialize", ["S& s"]) {
gen "s"
a.fields.each { |f| gen "(#{f.cppname})"}
genl ";"
@@ -141,19 +132,20 @@
end
def gen_proxy()
- h_file("#{@dir}/Proxy.h") {
+ h_file("#{@dir}/ProxyTemplate.h") {
include "#{@dir}/specification"
namespace(@ns) {
- genl "template <class F, class R=F::result_type>"
+ genl "template <class F, class R=typename F::result_type>"
cpp_class("ProxyTemplate") {
public
- genl "ProxyTemplate(F f) : functor(f) {}"
+ genl "ProxyTemplate(F f=F()) : functor(f) {}"
@amqp.classes.each { |c|
c.actions.each { |a|
- scope("R #{a.funcname}(", ")") { genl a.parameters }
- scope() {
+ genl
+ function_defn("R #{a.funcname}", a.parameters) {
var=a.name.funcname
- scope("#{a.classname} #{var}(",");") { genl a.arguments }
+ args = a.arguments.empty? ? "" : "("+a.arguments.join(", ")+")"
+ genl("#{a.fqclassname} #{var}#{args};")
genl "return functor(#{var});"
}
}
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb?rev=632075&r1=632074&r2=632075&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/amqpgen.rb Thu Feb 28 09:53:47 2008
@@ -136,9 +136,6 @@
@cache_child[[elname,name]] ||= children(elname).find { |c| c.name==name }
end
- # Fully qualified amqp dotted name of this element
- def dotted_name() (parent ? parent.dotted_name+"." : "") + name; end
-
# The root <amqp> element.
def root() @root ||=parent ? parent.root : self; end
@@ -167,6 +164,7 @@
class AmqpResponse < AmqpElement
def initialize(xml, parent) super; end
+ def fqname() (parent ? parent.dotted_name+"." : "") + "response"; end
end
class AmqpDoc < AmqpElement
@@ -454,7 +452,7 @@
end
# Append multi-line string to generated code, prefixing each line.
- def gen (str)
+ def gen(str)
str.each_line { |line|
@out << @prefix.last unless @midline
@out << line
@@ -465,10 +463,7 @@
end
# Append str + '\n' to generated code.
- def genl(str="")
- gen str
- gen "\n"
- end
+ def genl(str="") gen str+"\n"; end
# Generate code with added prefix.
def prefix(add, &block)
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb?rev=632075&r1=632074&r2=632075&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/cppgen.rb Thu Feb 28 09:53:47 2008
@@ -61,14 +61,14 @@
name=path.pop
return name.typename if path.empty?
path.map! { |n| n.nsname }
- return (path << name.caps).join("::")
+ return (path << name.caps.cppsafe).join("::")
end
- alias :typename :caps
- alias :nsname :bars
- alias :constname :shout
- alias :funcname :lcaps
- alias :varname :lcaps
+ def typename() caps.cppsafe; end
+ def nsname() bars.cppsafe; end
+ def constname() shout.cppsafe; end
+ def funcname() lcaps.cppsafe; end
+ def varname() lcaps.cppsafe; end
end
# Hold information about a C++ type.
@@ -112,22 +112,21 @@
def to_s() name; end;
end
-class AmqpElement
- def cppfqname()
- names=parent.dotted_name.split(".")
- # Field children are moved up to method in C++b
- prefix.pop if parent.is_a? AmqpField
- prefix.push cppname
- prefix.join("::")
- end
-end
-
class AmqpField
def cppname() name.lcaps.cppsafe; end
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
+ # FIXME aconway 2008-02-27: qualified
+ def paramtype()
+ fqtype=type_
+ unless type_.index(".")
+ c=containing_class
+ return c.domain(type_).fqtypename if c.domain(type_)
+ return c.struct(type_).fqclassname if c.struct(type_)
+ end
+ "call_traits<#{fqtype.amqp2cpp}>::param_type";
+ end
end
class AmqpMethod
@@ -138,26 +137,17 @@
end
module AmqpHasFields
- 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
+ def parameters() fields.map { |f| "#{f.paramtype} #{f.cppname}_"} end
+ def arguments() fields.map { |f| "#{f.cppname}_"} end
+ def values() fields.map { |f| "#{f.cppname}"} end
+ def initializers() fields.map { |f| "#{f.cppname}(#{f.cppname}_)"} end
end
class AmqpAction
def classname() name.typename; end
def funcname() parent.name.funcname + name.caps; end
+ def fqclassname() parent.name+"::"+classname; end
+
include AmqpHasFields
end
@@ -194,6 +184,11 @@
def cppname() name.caps; end
+ def fqtypename()
+ return containing_class.nsname+"::"+name.typename if containing_class
+ name.typename
+ end
+
def cpptype()
d=unalias
@cpptype ||= @@typemap[d.type_] or
@@ -220,7 +215,7 @@
end
def cpptype() parent.cpptype; end # preview
def cppname() cpptype.name; end # preview
-
+ def fqclassname() containing_class.nsname+"::"+name.typename; end
def classname() name.typename; end
end
@@ -319,6 +314,38 @@
# Generate code in namespace for each class
def each_class_ns()
@amqp.classes.each { |c| namespace(c.nsname) { yield c } }
+ end
+
+ def signature(ret_name, params, trailer="")
+ if params.size <= 1
+ genl ret_name+"(#{params})"+trailer
+ else
+ scope(ret_name+"(",")"+trailer) { genl params.join(",\n") }
+ end
+ end
+
+ def function_decl(ret_name, params=[], trailer="")
+ signature(ret_name, params, trailer+";")
+ end
+
+ def function_defn(ret_name, params=[], trailer="")
+ genl
+ signature(ret_name, params, trailer)
+ scope() { yield }
+ end
+
+ def ctor_decl(name, params=[]) function_decl(name, params); end
+
+ def ctor_defn(name, params=[], inits=[])
+ signature(name+"::"+name, params)
+ scope(":","") { genl inits.join(",\n")} if not inits.empty?
+ scope() { yield }
+ end
+
+ def function_call(name, params=[], trailer="")
+ gen name
+ list "(",params, ")"
+ gen trailer
end
end
Modified: incubator/qpid/trunk/qpid/cpp/rubygen/generate
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/generate?rev=632075&r1=632074&r2=632075&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/generate (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/generate Thu Feb 28 09:53:47 2008
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-require 'amqpgen'
require 'pathname'
+require 'amqpgen'
#
# Run a set of code generation templates.
@@ -21,14 +21,16 @@
# Create array of specs by version
def parse_specs(files)
- specs=Hash.new { |h,k| h[k]=[] }
+ lists=Hash.new { |h,k| h[k]=[] }
files.each { |f|
spec=AmqpRoot.new(File.new(f))
- specs[spec.version] << spec
+ lists[spec.version] << spec
}
- specs.each_pair { |k,v|
- specs[k] = v.size==1 ? v.first : AmqpRoot.new(*v.map { |s| s.xml})
+ specs={}
+ lists.each_pair { |k,l|
+ specs[k] = l.size==1 ? l.first : AmqpRoot.new(*l.map { |s| s.xml})
}
+ return specs
end
# Run selected templates
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/Makefile.am?rev=632075&r1=632074&r2=632075&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/Makefile.am Thu Feb 28 09:53:47 2008
@@ -38,7 +38,8 @@
InlineVector.cpp \
ISList.cpp IList.cpp \
ClientSessionTest.cpp \
- serialize.cpp
+ serialize.cpp \
+ ProxyTemplate.cpp
# FIXME aconway 2008-02-20: removed RefCountedMap.cpp due to valgrind error.
check_LTLIBRARIES += libshlibtest.la
Added: incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp?rev=632075&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp Thu Feb 28 09:53:47 2008
@@ -0,0 +1,49 @@
+/*
+ *
+ * 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 "unit_test.h"
+#include "qpid/amqp_0_10/ProxyTemplate.h"
+#include <boost/any.hpp>
+
+QPID_AUTO_TEST_SUITE(ProxyTemplateTestSuite)
+
+using namespace qpid::amqp_0_10;
+
+struct ToAny {
+ template <class T>
+ boost::any operator()(const T& t) { return boost::any(t); }
+};
+
+struct AnyProxy : public ProxyTemplate<ToAny, boost::any> {};
+
+BOOST_AUTO_TEST_CASE(testAnyProxy) {
+ AnyProxy p;
+ boost::any a=p.connectionTune(1,2,3,4);
+ BOOST_CHECK_EQUAL(a.type().name(), typeid(connection::Tune).name());
+ connection::Tune* tune=boost::any_cast<connection::Tune>(&a);
+ BOOST_REQUIRE(tune);
+ BOOST_CHECK_EQUAL(tune->channelMax, 1u);
+ BOOST_CHECK_EQUAL(tune->maxFrameSize, 2u);
+ BOOST_CHECK_EQUAL(tune->heartbeatMin, 3u);
+ BOOST_CHECK_EQUAL(tune->heartbeatMax, 4u);
+}
+
+QPID_AUTO_TEST_SUITE_END()
Propchange: incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/qpid/trunk/qpid/cpp/src/tests/ProxyTemplate.cpp
------------------------------------------------------------------------------
svn:keywords = Rev Date