diff options
| author | Alan Conway <aconway@apache.org> | 2008-02-22 23:13:43 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2008-02-22 23:13:43 +0000 |
| commit | 162cbcc4766122da3b939ed9f9b979bd726cb175 (patch) | |
| tree | 5907f23e78ef413d1fa66254c46dee283e9ddca9 /qpid/cpp/rubygen | |
| parent | ad50f325f63c819de67af9ae7276aafc0238bc40 (diff) | |
| download | qpid-python-162cbcc4766122da3b939ed9f9b979bd726cb175.tar.gz | |
Fixed rubygen to skip unchanged generated files, prevents needless
rebuilding every time the code generator changes.
Start of amqp 0-10 mapping, work in progress.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@630353 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/rubygen')
| -rwxr-xr-x | qpid/cpp/rubygen/amqpgen.rb | 37 | ||||
| -rwxr-xr-x | qpid/cpp/rubygen/cppgen.rb | 25 | ||||
| -rwxr-xr-x | qpid/cpp/rubygen/generate | 2 | ||||
| -rwxr-xr-x | qpid/cpp/rubygen/templates/amqp_0_10.rb | 64 |
4 files changed, 112 insertions, 16 deletions
diff --git a/qpid/cpp/rubygen/amqpgen.rb b/qpid/cpp/rubygen/amqpgen.rb index f998909ec8..da6ed689a3 100755 --- a/qpid/cpp/rubygen/amqpgen.rb +++ b/qpid/cpp/rubygen/amqpgen.rb @@ -127,6 +127,9 @@ class AmqpElement @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 @@ -142,7 +145,9 @@ class AmqpElement end -AmqpResponse = AmqpElement +class AmqpResponse < AmqpElement + def initialize(xml, parent) super; end +end class AmqpDoc < AmqpElement def initialize(xml,parent) super; end @@ -183,7 +188,6 @@ class AmqpField < AmqpElement def initialize(xml, amqp) super; end; def domain() root.domain(xml.attributes["domain"]); end amqp_single_child_reader :struct # preview - # FIXME aconway 2008-02-21: exceptions in fields - need to update c++ mapping. amqp_child_reader :exception amqp_attr_reader :type, :default, :code, :required end @@ -198,11 +202,6 @@ class AmqpConstant < AmqpElement amqp_attr_reader :value, :class end -# FIXME aconway 2008-02-21: -# class AmqpResponse < AmqpElement -# def initialize(xml, parent) super; end -# end - class AmqpResult < AmqpElement def initialize(xml, parent) super; end amqp_single_child_reader :struct # preview @@ -236,8 +235,8 @@ class AmqpStruct < AmqpElement amqp_attr_reader :size, :code, :pack amqp_child_reader :field - alias :raw_pack :pack # preview - preview code needs default "short" for pack. + alias :raw_pack :pack def pack() raw_pack or (not parent.final? and "short"); end def result?() parent.xml.name == "result"; end def domain?() parent.xml.name == "domain"; end @@ -299,9 +298,14 @@ class AmqpClass < AmqpElement end class AmqpType < AmqpElement + def initialize(xml,amqp) super; end amqp_attr_reader :code, :fixed_width, :variable_width end +class AmqpXref < AmqpElement + def initialize(xml,amqp) super; end +end + # AMQP root element. class AmqpRoot < AmqpElement amqp_attr_reader :major, :minor, :port, :comment @@ -319,9 +323,9 @@ class AmqpRoot < AmqpElement def version() major + "-" + minor; end - # Find a child node from a dotted amqp name, e.g. message.transfer - def lookup(dotted_name) elements[dotted_name.gsub(/\./,"/")]; end - + # Find the element corresponding to an amqp dotted name. + def lookup(dotted_name) xml.elements[dotted_name.gsub(/\./,"/")]; end + # preview - only struct child reader remains for new mapping def domain_structs() domains.map{ |d| d.struct }.compact; end def result_structs() @@ -353,7 +357,7 @@ end # Collect information about generated files. class GenFiles @@files =[] - def GenFiles.add(f) @@files << f; puts f; end + def GenFiles.add(f) @@files << f; end def GenFiles.get() @@files; end end @@ -378,7 +382,14 @@ class Generator if (@outdir != "-") path=Pathname.new "#{@outdir}/#{file}" path.parent.mkpath - path.open('w') { |@out| yield } + @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 + else + path.open('w') { |f| f << @out } + puts "Generated #{path}" + end end end diff --git a/qpid/cpp/rubygen/cppgen.rb b/qpid/cpp/rubygen/cppgen.rb index 60a653e18d..d3cdcca603 100755 --- a/qpid/cpp/rubygen/cppgen.rb +++ b/qpid/cpp/rubygen/cppgen.rb @@ -54,12 +54,23 @@ CppKeywords = Set.new(["and", "and_eq", "asm", "auto", "bitand", CppMangle = CppKeywords+Set.new(["string"]) class String - def cppsafe() - CppMangle.include?(self) ? self+"_" : self + def cppsafe() CppMangle.include?(self) ? self+"_" : self; end + def amqp2cpp() + path=split(".") + name=path.pop + path.map! { |n| n.bars } + (path << name.caps).join("::") end end # Hold information about a C++ type. +# +# preview - new mapping does not use CppType, +# Each amqp type corresponds exactly by dotted name +# to a type, domain or struct, which in turns +# corresponds by name to a C++ type or typedef. +# (see String.amqp2cpp) +# class CppType def initialize(name) @name=@param=@ret=name; end attr_reader :name, :param, :ret, :code @@ -93,6 +104,16 @@ class CppType 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 diff --git a/qpid/cpp/rubygen/generate b/qpid/cpp/rubygen/generate index 94b194aaa4..f7bf334569 100755 --- a/qpid/cpp/rubygen/generate +++ b/qpid/cpp/rubygen/generate @@ -69,7 +69,7 @@ EOS } out << <<EOS if GENERATE -$(rgen_srcs) $(srcdir)/#{File.basename makefile}: $(rgen_generator) $(specs) +$(srcdir)/#{File.basename makefile}: $(rgen_generator) $(specs) $(rgen_cmd) # Empty rule in case a generator file is renamed/removed. diff --git a/qpid/cpp/rubygen/templates/amqp_0_10.rb b/qpid/cpp/rubygen/templates/amqp_0_10.rb new file mode 100755 index 0000000000..ef779c9015 --- /dev/null +++ b/qpid/cpp/rubygen/templates/amqp_0_10.rb @@ -0,0 +1,64 @@ +#!/usr/bin/env ruby +$: << ".." # Include .. in load path +require 'cppgen' + +class Amqp_0_10 < CppGen + + def initialize(outdir, amqp) + super(outdir, amqp) + @namespace="qpid::amqp_0_10" + @filename="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};" + } + } + end + + def action_cpp(a, base) + + 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"} + } + } + } + } + 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};" + } + } + } + } + end + + def generate + gen_amqp_0_10_h + gen_amqp_0_10_cpp + end +end + +Amqp_0_10.new(Outdir, Amqp).generate(); + |
