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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#!/usr/bin/env ruby
#
# 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.
#
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.cmake ]
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 cmake_continue(lines) lines.join(" \n "); end
# Generate makefile
makefile=ARGV.grep(/.cmake$/)[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).
set(rgen_generator #{cmake_continue rgen_generator})
EOS
rgen_subdirs.each_key { |subdir|
out << "\nset(rgen_#{subdir}_srcs #{cmake_continue(rgen_subdirs[subdir])})\n"
}
out << <<EOS
set(rgen_srcs #{cmake_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
set(#{dir_}dir \${includedir}/#{dir})
set(dist_#{dir_}_HEADERS #{cmake_continue rgen_srcs.grep(regex)})
EOS
}
}
end
|