| #!/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 |
| |
| gendir=File.dirname(__FILE__) |
| |
| # Run selected templates |
| if ARGV.any? { |arg| arg=="all" } |
| templates=Dir["#{gendir}/*/*.rb"] |
| else |
| templates=ARGV.grep(/\.rb$/) |
| ARGV.each { |arg| |
| d=File.join gendir,arg |
| templates += Dir["#{d}/*.rb"] if File.directory? d |
| } |
| end |
| |
| $outdir=ARGV[0] |
| $models=parse_specs(ARGV.grep(/\.xml$/)) |
| templates.each { |t| |
| ver=Pathname.new(t).dirname.basename.to_s.split('.')[-1] |
| $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}" } |
| rgen_subdirs={} |
| rgen_srcs.each { |src| |
| if src.match(%r{#{$outdir}/qpid/([^/]+)/}) |
| subdir=$1 |
| rgen_subdirs[subdir] ||= [] |
| rgen_subdirs[subdir] << src |
| end |
| } |
| 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} |
| EOS |
| rgen_subdirs.each_key { |subdir| |
| out << "\nrgen_#{subdir}_srcs = #{make_continue(rgen_subdirs[subdir])}\n" |
| } |
| out << <<EOS |
| 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 |
| } |
| } |
| end |
| |