summaryrefslogtreecommitdiff
path: root/qpid/cpp/rubygen/generate
blob: 9f0ddf0f1c4f5af51d6a3aed2704eaa275b89794 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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