summaryrefslogtreecommitdiff
path: root/qpid/cpp/rubygen/generate
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/rubygen/generate')
-rwxr-xr-xqpid/cpp/rubygen/generate103
1 files changed, 103 insertions, 0 deletions
diff --git a/qpid/cpp/rubygen/generate b/qpid/cpp/rubygen/generate
new file mode 100755
index 0000000000..9f0ddf0f1c
--- /dev/null
+++ b/qpid/cpp/rubygen/generate
@@ -0,0 +1,103 @@
+#!/usr/bin/env ruby
+require 'pathname'
+require 'amqpgen'
+
+#
+# Run a set of code generation templates.
+#
+if ARGV.size < 3
+ puts <<EOS
+Usage: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] TEMPLATE.rb [ ... ]
+or: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] all [ makefragment.mk ]
+
+Parse all SPEC.xml files to create an AMQP model, run each TEMPLATE
+putting the resulting files under OUTDIR. Prints a list of files
+generated to standard output.
+
+If OUTDIR is '-' then just prints file list without generating files.
+EOS
+ exit 1
+end
+
+# Create array of specs by version
+def parse_specs(files)
+ lists=Hash.new { |h,k| h[k]=[] }
+ files.each { |f|
+ spec=AmqpRoot.new(File.new(f))
+ lists[spec.version] << spec
+ }
+ 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
+if ARGV.any? { |arg| arg=="all" }
+ templates=Dir["#{File.dirname __FILE__}/*/*.rb"]
+else
+ templates=ARGV.grep(/\.rb$/)
+end
+
+$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
+
+# Generate makefile
+makefile=ARGV.grep(/.mk$/)[0]
+if makefile
+ dir=Dir.getwd
+ Dir.chdir File.dirname(__FILE__)
+ 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}" }
+
+ File.open(makefile, 'w') { |out|
+ out << <<EOS
+# Generated makefile fragment.
+# Including makefile defines $(rgen_dir) $(rgen_cmd) and $(specs).
+
+rgen_generator=#{make_continue rgen_generator}
+
+rgen_client_cpp=#{make_continue(rgen_srcs.grep(%r|/qpid/client/.+\.cpp$|))}
+
+rgen_common_cpp=#{make_continue(rgen_srcs.grep(%r{qpid/(framing|amqp_.+)/.+\.cpp$}))}
+
+rgen_srcs=#{make_continue rgen_srcs}
+
+# Header file install rules.
+EOS
+ ["amqp_0_10", "framing", "client/no_keyword","client", "broker"].each { |ns|
+ dir="qpid/#{ns}"
+ dir_ = dir.tr("/", "_")
+ regex=%r|#{dir}/[^/]+\.h$|
+ out << <<EOS
+#{dir_}dir = $(includedir)/#{dir}
+dist_#{dir_}_HEADERS = #{make_continue rgen_srcs.grep(regex)}
+
+EOS
+ }
+ out << <<EOS
+if GENERATE
+$(srcdir)/#{File.basename makefile}: $(rgen_generator) $(specs)
+ $(rgen_cmd)
+
+# Empty rule in case a generator file is renamed/removed.
+$(rgen_generator):
+endif
+EOS
+ }
+end
+