basechip 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +14 -0
- data/README.rdoc +19 -0
- data/VERSION +1 -0
- data/bin/basechip +25 -0
- data/collateral/block/block.rb.erb +20 -0
- data/collateral/configuration/configuration.rb.erb +19 -0
- data/collateral/project/Gemfile +19 -0
- data/collateral/project/gitignore +6 -0
- data/collateral/project/project.rb.erb +76 -0
- data/collateral/project/settings.rb.erb +26 -0
- data/collateral/recipes/icarus.rb +73 -0
- data/collateral/recipes/icarus.rb.erb +88 -0
- data/collateral/recipes/local_cluster.rb +27 -0
- data/lib/array.rb +26 -0
- data/lib/base_chip/action.rb +309 -0
- data/lib/base_chip/base.rb +105 -0
- data/lib/base_chip/block.rb +75 -0
- data/lib/base_chip/bom.rb +75 -0
- data/lib/base_chip/bom_file.rb +45 -0
- data/lib/base_chip/cli.rb +371 -0
- data/lib/base_chip/cluster.rb +93 -0
- data/lib/base_chip/cluster_type.rb +45 -0
- data/lib/base_chip/code_area.rb +30 -0
- data/lib/base_chip/configuration.rb +257 -0
- data/lib/base_chip/dsl.rb +593 -0
- data/lib/base_chip/exit_error.rb +20 -0
- data/lib/base_chip/generator_menu.rb +64 -0
- data/lib/base_chip/git.rb +32 -0
- data/lib/base_chip/hierarchy.rb +84 -0
- data/lib/base_chip/install_menu.rb +89 -0
- data/lib/base_chip/ipc.rb +50 -0
- data/lib/base_chip/list_menu.rb +134 -0
- data/lib/base_chip/menu.rb +70 -0
- data/lib/base_chip/out_file.rb +68 -0
- data/lib/base_chip/permutation.rb +26 -0
- data/lib/base_chip/permute.rb +25 -0
- data/lib/base_chip/post.rb +26 -0
- data/lib/base_chip/problem.rb +33 -0
- data/lib/base_chip/project.rb +472 -0
- data/lib/base_chip/requirement.rb +26 -0
- data/lib/base_chip/runable.rb +36 -0
- data/lib/base_chip/source_language.rb +40 -0
- data/lib/base_chip/source_type.rb +24 -0
- data/lib/base_chip/statistic.rb +27 -0
- data/lib/base_chip/task.rb +21 -0
- data/lib/base_chip/task_master.rb +50 -0
- data/lib/base_chip/taskable.rb +77 -0
- data/lib/base_chip/tasker.rb +260 -0
- data/lib/base_chip/test.rb +202 -0
- data/lib/base_chip/test_list.rb +120 -0
- data/lib/base_chip/tool.rb +51 -0
- data/lib/base_chip/tool_version.rb +34 -0
- data/lib/base_chip/top_menu.rb +203 -0
- data/lib/base_chip/track_state.rb +61 -0
- data/lib/base_chip.rb +215 -0
- data/lib/dir.rb +30 -0
- data/lib/reporting.rb +97 -0
- metadata +215 -0
@@ -0,0 +1,309 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'zlib'
|
18
|
+
require 'base_chip/runable'
|
19
|
+
require 'base_chip/statistic'
|
20
|
+
require 'base_chip/out_file'
|
21
|
+
|
22
|
+
module BaseChip
|
23
|
+
class Action
|
24
|
+
include Taskable
|
25
|
+
include TrackState
|
26
|
+
include Runable
|
27
|
+
include Dsl
|
28
|
+
include Base
|
29
|
+
|
30
|
+
define_settings({:zip_failing_action => [ Boolean ],
|
31
|
+
:zip_passing_action => [ Boolean ],
|
32
|
+
:clean_passing_action => [ Boolean ],
|
33
|
+
:run_action_in_tmp => [ Boolean ],
|
34
|
+
:depends => [ String , Array, Symbol ],
|
35
|
+
:before => [ Proc ],
|
36
|
+
:after => [ Proc ],
|
37
|
+
:environment => [ Hash ],
|
38
|
+
:command => [ String ],
|
39
|
+
:command_prefix => [ String ],
|
40
|
+
:command_suffix => [ String ],
|
41
|
+
:pre_commands => [ Array ],
|
42
|
+
:post_commands => [ Array ],
|
43
|
+
:name_regex => [ Regexp ],
|
44
|
+
:seed_options => [ String , Array ],
|
45
|
+
:args => [ String ],
|
46
|
+
:log_to => [ String ],
|
47
|
+
:stdout_to => [ String ],
|
48
|
+
:stderr_to => [ String ],
|
49
|
+
:echo_stdin => [ Boolean ],
|
50
|
+
:needs_clobber => [ Boolean ],
|
51
|
+
:clean_proc => [ Proc ]})
|
52
|
+
|
53
|
+
define_children({:out_file => OutFile })
|
54
|
+
|
55
|
+
def configure
|
56
|
+
return if @configured
|
57
|
+
unless @test
|
58
|
+
@bundle_name ||= if BaseChip.options.random_bundle_names
|
59
|
+
random_string
|
60
|
+
else
|
61
|
+
@name.to_s
|
62
|
+
end
|
63
|
+
@directory ||= @configuration.out_directory + "/#{@bundle_name}"
|
64
|
+
end
|
65
|
+
super
|
66
|
+
end
|
67
|
+
def run
|
68
|
+
if @run_action_in_tmp
|
69
|
+
bundle_name = random_string
|
70
|
+
run_directory = "/tmp/#{bundle_name}"
|
71
|
+
else
|
72
|
+
bundle_name = @bundle_name
|
73
|
+
run_directory = @directory
|
74
|
+
end
|
75
|
+
FileUtils.rm_rf run_directory
|
76
|
+
FileUtils.mkdir_p run_directory
|
77
|
+
Dir.pushd run_directory
|
78
|
+
|
79
|
+
File.open('seed','w') do |f|
|
80
|
+
f.write random_generator.seed
|
81
|
+
end
|
82
|
+
File.open('rerun.yaml','w') do |f|
|
83
|
+
f.write rerun_data.to_yaml
|
84
|
+
end
|
85
|
+
|
86
|
+
# Where the magic happens
|
87
|
+
inner_run
|
88
|
+
|
89
|
+
FileUtils.touch "#{run_directory}/.fail_detected" unless self.pass?
|
90
|
+
|
91
|
+
Dir.chdir '..'
|
92
|
+
if (@clean_passing_action && pass? && !@foreground)
|
93
|
+
FileUtils.rm_rf run_directory
|
94
|
+
else
|
95
|
+
bundle_tgz = nil
|
96
|
+
if @zip_failing_action || (@zip_passing_action && pass?)
|
97
|
+
bundle_tgz = run_directory + ".tgz"
|
98
|
+
@bundle_tgz = @directory + ".tgz"
|
99
|
+
tgz = Zlib::GzipWriter.new(File.open(bundle_tgz, 'wb'))
|
100
|
+
Archive::Tar::Minitar.pack(bundle_name, tgz)
|
101
|
+
FileUtils.rm_rf bundle_name
|
102
|
+
end
|
103
|
+
if @run_action_in_tmp
|
104
|
+
FileUtils.mkdir_p "#{@directory}/.."
|
105
|
+
FileUtils.mv((bundle_tgz || run_directory), "#{@directory}/..")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
puts "Debug information here: #{@bundle_tgz || @directory}" if @foreground
|
110
|
+
|
111
|
+
# p @totals if @foreground
|
112
|
+
Dir.popd
|
113
|
+
end
|
114
|
+
def inner_run
|
115
|
+
# puts "#{full_name} started"
|
116
|
+
script_file = "#{@name}.bash"
|
117
|
+
script = File.open(script_file,'w')
|
118
|
+
script.puts "#!/bin/bash"
|
119
|
+
# $environment.each do |n,v|
|
120
|
+
# script.puts "export #{n}=#{v}"
|
121
|
+
# end
|
122
|
+
if @environment
|
123
|
+
@environment.each do |n,v|
|
124
|
+
script.puts "export #{n}=#{v}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
script.puts "NAME=#{@name}"
|
129
|
+
script.puts "BLOCK=#{@block.name}"
|
130
|
+
if @args
|
131
|
+
script.puts "ARGS='#{@args.gsub(/'/,"\\'")}'"
|
132
|
+
end
|
133
|
+
|
134
|
+
# FIXME fault if commands and command both exist
|
135
|
+
if @commands
|
136
|
+
script.puts @commands
|
137
|
+
elsif @command
|
138
|
+
script.puts @pre_commands if @pre_commands
|
139
|
+
script.puts "#{@command_prefix} #{@command} #{@command_suffix} $*"
|
140
|
+
script.puts @post_commands if @post_commands
|
141
|
+
else
|
142
|
+
fault "Action #{@name} has no command(s) specified to run"
|
143
|
+
end
|
144
|
+
|
145
|
+
script.chmod 0777
|
146
|
+
script.close
|
147
|
+
process_status = nil
|
148
|
+
errmsg = ''
|
149
|
+
|
150
|
+
STDOUT.sync = true
|
151
|
+
STDERR.sync = true
|
152
|
+
|
153
|
+
@before.call if @before
|
154
|
+
|
155
|
+
script_call = (@foreground || @log_to || @stdout_to) ? script.path : "#{script.path} > /dev/null"
|
156
|
+
|
157
|
+
log_storage = ( @log_to ) ? File.open( @log_to, 'w') : nil
|
158
|
+
stdout_storage = (@stdout_to && @stdout_to != @log_to) ? File.open(@stdout_to, 'w') : nil
|
159
|
+
stderr_storage = (@stderr_to && @stderr_to != @log_to) ? File.open(@stderr_to, 'w') : nil
|
160
|
+
|
161
|
+
# stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
|
162
|
+
Open3.popen3(script_call) do |stdin, stdout, stderr, wait_thr|
|
163
|
+
|
164
|
+
to = Thread.new(stdout) do |pipe|
|
165
|
+
out_data = nil
|
166
|
+
loop do
|
167
|
+
begin
|
168
|
+
out_data = pipe.readpartial(4096)
|
169
|
+
rescue EOFError, IOError
|
170
|
+
break
|
171
|
+
end
|
172
|
+
STDOUT.print out_data if @foreground
|
173
|
+
log_storage.print out_data if log_storage
|
174
|
+
stderr_storage.print out_data if stderr_storage
|
175
|
+
end
|
176
|
+
end
|
177
|
+
ti = Thread.new(STDIN) do |pipe|
|
178
|
+
in_data = nil
|
179
|
+
loop do
|
180
|
+
begin
|
181
|
+
in_data = pipe.readpartial(4096)
|
182
|
+
rescue EOFError, IOError
|
183
|
+
break
|
184
|
+
end
|
185
|
+
stdin.print in_data if @foreground && !stdin.closed?
|
186
|
+
if @echo_stdin
|
187
|
+
STDOUT.print in_data if @foreground
|
188
|
+
log_storage.print in_data if log_storage
|
189
|
+
stderr_storage.print in_data if stdout_storage
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
te = Thread.new(stderr) do |pipe|
|
194
|
+
err_data = nil
|
195
|
+
loop do
|
196
|
+
begin
|
197
|
+
err_data = pipe.readpartial(4096)
|
198
|
+
rescue EOFError, IOError
|
199
|
+
break
|
200
|
+
end
|
201
|
+
errmsg += err_data
|
202
|
+
STDERR.print err_data if @foreground
|
203
|
+
log_storage.print err_data if log_storage
|
204
|
+
stderr_storage.print err_data if stderr_storage
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
begin
|
209
|
+
wait_thr.join
|
210
|
+
if @foreground
|
211
|
+
ti.kill
|
212
|
+
to.kill unless te.join(10)
|
213
|
+
end
|
214
|
+
te .kill unless te.join(10)
|
215
|
+
rescue Interrupt
|
216
|
+
if @foreground # && @int_for_shell
|
217
|
+
Process.kill 'INT', wait_thr.pid
|
218
|
+
retry
|
219
|
+
else
|
220
|
+
raise
|
221
|
+
end
|
222
|
+
end
|
223
|
+
process_status = wait_thr.value # Process::Status object returned.
|
224
|
+
end
|
225
|
+
|
226
|
+
log_storage.close if log_storage
|
227
|
+
stdout_storage.close if stdout_storage
|
228
|
+
stderr_storage.close if stderr_storage
|
229
|
+
|
230
|
+
@after.call if @after
|
231
|
+
|
232
|
+
statistics = {}
|
233
|
+
totals = {}
|
234
|
+
if @out_files
|
235
|
+
@out_files.each_value do |f|
|
236
|
+
f.go(@name)
|
237
|
+
|
238
|
+
take_state(f)
|
239
|
+
|
240
|
+
statistics.merge! f.statistics if f.statistics
|
241
|
+
totals .merge! f.totals if f.totals
|
242
|
+
|
243
|
+
# warning!(pf,ps) if f.warning?
|
244
|
+
# error!( pf,ps) if f.error?
|
245
|
+
# fault!( pf,ps) if f.fault?
|
246
|
+
end
|
247
|
+
end
|
248
|
+
error!(nil, errmsg) if !process_status.success? || errmsg.size > 0
|
249
|
+
|
250
|
+
@state ||= 'pass'
|
251
|
+
@state = 'fail' unless self.pass? # state is error, warning or fault up to this point
|
252
|
+
|
253
|
+
# puts "log file produced #{totals}"
|
254
|
+
totals.each do |k,v|
|
255
|
+
if statistics[k].for_states.include? @state
|
256
|
+
if statistics[k].across_states
|
257
|
+
@totals[k] = v
|
258
|
+
end
|
259
|
+
if statistics[k].per_state
|
260
|
+
@totals["#{@state}_#{k}"] = v
|
261
|
+
end
|
262
|
+
# FIXME error_if_missing
|
263
|
+
end
|
264
|
+
end
|
265
|
+
# puts "we collected #{@totals}"
|
266
|
+
|
267
|
+
unless pass?
|
268
|
+
@problem.bundle=(@bundle_tgz || @directory)
|
269
|
+
# error(@problem.to_s)
|
270
|
+
end
|
271
|
+
# puts "#{full_name} ended"
|
272
|
+
end
|
273
|
+
|
274
|
+
def clean
|
275
|
+
return if @needs_clobber
|
276
|
+
clobber
|
277
|
+
end
|
278
|
+
def clobber
|
279
|
+
@clean_proc.call(self) if @clean_proc
|
280
|
+
FileUtils.rm_rf @directory
|
281
|
+
FileUtils.rm_rf "#{@directory}.tgz"
|
282
|
+
end
|
283
|
+
|
284
|
+
attr_writer :random_generator
|
285
|
+
def random_generator
|
286
|
+
@random_generator ||= BaseChip.new_random_generator
|
287
|
+
end
|
288
|
+
def generate_seed(format, bits=32)
|
289
|
+
case format
|
290
|
+
when :num
|
291
|
+
@random_generator.rand(2 ** bits)
|
292
|
+
when :hex
|
293
|
+
(@random_generator.rand(2 ** bits)).to_hex
|
294
|
+
when :dec
|
295
|
+
(@random_generator.rand(2 ** bits)).to_s
|
296
|
+
when :alphanumeric
|
297
|
+
random_string(bits)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def rerun_data
|
302
|
+
{ 'full_name' => full_name ,
|
303
|
+
'seed' => random_generator.seed ,
|
304
|
+
'modes' => modes ,
|
305
|
+
'append_arguments' => BaseChip.options. append_arguments ,
|
306
|
+
'replace_arguments' => BaseChip.options.replace_arguments }
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'reporting'
|
18
|
+
module BaseChip
|
19
|
+
module Base
|
20
|
+
def self.included mod
|
21
|
+
mod.extend Base::ClassMethods
|
22
|
+
mod.class_eval do
|
23
|
+
include Reporting
|
24
|
+
include Base::InstanceMethods
|
25
|
+
|
26
|
+
define_setting :directory, [ String ]
|
27
|
+
|
28
|
+
# chain together projects, blocks, and actions
|
29
|
+
attr_reader :project
|
30
|
+
attr_reader :block
|
31
|
+
attr_reader :configuration
|
32
|
+
attr_reader :action
|
33
|
+
attr_reader :test_list
|
34
|
+
attr_reader :test
|
35
|
+
attr_reader :tool
|
36
|
+
attr_reader :version
|
37
|
+
attr_reader :source_type
|
38
|
+
attr_reader :source_language
|
39
|
+
end
|
40
|
+
end
|
41
|
+
module ClassMethods
|
42
|
+
end
|
43
|
+
module InstanceMethods
|
44
|
+
def parent=(parent); @parent = parent; update_chaining; end
|
45
|
+
def foster=(parent); @foster = parent; update_chaining; end
|
46
|
+
def update_chaining
|
47
|
+
# chain blocks, projects, and actions together
|
48
|
+
@project ||= (self.is_a? BaseChip::Project ) ? self : ((parent.project if parent) || (foster.project if foster))
|
49
|
+
@block ||= (self.is_a? BaseChip::Block ) ? self : ((parent.block if parent) || (foster.block if foster))
|
50
|
+
@configuration ||= (self.is_a? BaseChip::Configuration ) ? self : ((parent.configuration if parent) || (foster.configuration if foster))
|
51
|
+
@action ||= (self.is_a? BaseChip::Action ) ? self : ((parent.action if parent) || (foster.action if foster))
|
52
|
+
@test_list ||= (self.is_a? BaseChip::TestList ) ? self : ((parent.test_list if parent) || (foster.test_list if foster))
|
53
|
+
@test ||= (self.is_a? BaseChip::Test ) ? self : ((parent.test if parent) || (foster.test if foster))
|
54
|
+
@tool ||= (self.is_a? BaseChip::Tool ) ? self : ((parent.tool if parent) || (foster.tool if foster))
|
55
|
+
@tool_version ||= (self.is_a? BaseChip::ToolVersion ) ? self : ((parent.tool_version if parent) || (foster.tool_version if foster))
|
56
|
+
@source_type ||= (self.is_a? BaseChip::SourceType ) ? self : ((parent.source_type if parent) || (foster.source_type if foster))
|
57
|
+
@source_language ||= (self.is_a? BaseChip::SourceLanguage) ? self : ((parent.source_language if parent) || (foster.source_language if foster))
|
58
|
+
end
|
59
|
+
|
60
|
+
def configure
|
61
|
+
return if @configured
|
62
|
+
super
|
63
|
+
# if self.class.children_types.keys.include?(:tool) && self.tools
|
64
|
+
# self.tools.each_value do |t|
|
65
|
+
# t.configure
|
66
|
+
# t.selected_version.configure
|
67
|
+
# t.selected_version.actions.each do |n,a|
|
68
|
+
# self.actions ||= {}
|
69
|
+
# if self.actions[n]
|
70
|
+
# self.actions[n].blks = a.blks + self.actions[n].blks
|
71
|
+
# self.actions[n].foster ||= a.parent
|
72
|
+
# else
|
73
|
+
# self.actions[n] = a.clone
|
74
|
+
# self.actions[n].blks = self.actions[n].blks.dup
|
75
|
+
# self.actions[n].foster = a.parent
|
76
|
+
# self.actions[n].parent = self
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
end
|
82
|
+
|
83
|
+
def discover_configurations
|
84
|
+
Dir.glob("#{BaseChip.root}/*/base_chip/configuration.rb").each do |f|
|
85
|
+
if f =~ /(\w+)\/base_chip\/configuration\.rb$/
|
86
|
+
self.block($1.to_sym) {|b| b.file f}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
def file_glob(glob, regex = nil, type = nil)
|
91
|
+
Dir.glob(glob).each do |f|
|
92
|
+
if regex
|
93
|
+
if f =~ regex
|
94
|
+
self.send(type, $1.to_sym) { |t| t.file(f) }
|
95
|
+
else
|
96
|
+
fault "fileglob '#{glob}' did not match regex /#{regex}/ in #{self.name}"
|
97
|
+
end
|
98
|
+
else
|
99
|
+
self.file(f)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'base_chip/configuration'
|
18
|
+
|
19
|
+
module BaseChip
|
20
|
+
class Block
|
21
|
+
include Dsl
|
22
|
+
include Base
|
23
|
+
include Hierarchy
|
24
|
+
define_children({:configuration => Configuration})
|
25
|
+
|
26
|
+
def configuration_dereference(name,names,passive)
|
27
|
+
if configuration = @configurations[name]
|
28
|
+
configuration.configure
|
29
|
+
configuration.dereference_workload(names,passive)
|
30
|
+
elsif passive
|
31
|
+
[]
|
32
|
+
else
|
33
|
+
fault "Could not find configuration #{name} in block #{@name}" # FIXME say who wanted it, and if shortcut occurred
|
34
|
+
end
|
35
|
+
end
|
36
|
+
def dereference_workload(names = nil,passive=false)
|
37
|
+
configure
|
38
|
+
fault "No configurations specified for block #{@name}" unless @configurations # || passive || names.nil?
|
39
|
+
names ||= ['all']
|
40
|
+
out = Array.new
|
41
|
+
names.each do |n|
|
42
|
+
n = n.to_s
|
43
|
+
case n
|
44
|
+
when 'all', 'gate', 'upgate', 'downgate', 'diffgate' # FIXME , 'alltests', 'allactions'
|
45
|
+
next unless @configurations
|
46
|
+
@configurations.keys.each { |k| out += configuration_dereference(k,[n],true) }
|
47
|
+
when /^all:(.*)$/
|
48
|
+
next unless @configurations
|
49
|
+
tmp = $1
|
50
|
+
@configurations.keys.each { |k| out += configuration_dereference(k,[tmp],true) }
|
51
|
+
when /^([^:]*?):(.*)$/
|
52
|
+
out += configuration_dereference($1.to_sym,[$2],passive)
|
53
|
+
else
|
54
|
+
fault "No configurations specified for block #{@name}" unless @configurations || passive
|
55
|
+
if @configurations[:default]
|
56
|
+
out += configuration_dereference(:default,[n],passive)
|
57
|
+
elsif @configurations.size == 1
|
58
|
+
out += configuration_dereference(@configurations.keys[0],[n],passive)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
out.uniq!
|
63
|
+
out
|
64
|
+
end
|
65
|
+
|
66
|
+
def shortcut(name, array)
|
67
|
+
@shortcuts ||= {}
|
68
|
+
@shortcuts[name] = array
|
69
|
+
end
|
70
|
+
|
71
|
+
def discover_configurations ; file_glob("#{@directory}/*/base_chip/configuration.rb" , /(\w+)\/base_chip\/configuration\.rb$/ , :configuration)
|
72
|
+
file_glob("#{@directory}/base_chip/configurations/*.rb", /base_chip\/configurations\/(\w+)\.rb$/, :configuration) end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'base_chip/bom_file'
|
18
|
+
|
19
|
+
class Hash
|
20
|
+
def deep_values
|
21
|
+
self.values.map do |v|
|
22
|
+
if v.respond_to? :values
|
23
|
+
v.values
|
24
|
+
else
|
25
|
+
v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module BaseChip
|
32
|
+
class Bom
|
33
|
+
attr_reader :hash
|
34
|
+
attr_reader :name1
|
35
|
+
attr_reader :name2
|
36
|
+
def initialize(hash)
|
37
|
+
@hash = hash.with_indifferent_access
|
38
|
+
@name1 = 'all'
|
39
|
+
@name2 = 'all'
|
40
|
+
end
|
41
|
+
def verilog ; @verilog ||= trim(2,:verilog ) end
|
42
|
+
def classes ; @classes ||= trim(2,:classes ) end
|
43
|
+
def vhdl ; @vhdl ||= trim(2,:vhdl ) end
|
44
|
+
def systemc ; @systemc ||= trim(2,:systemc ) end
|
45
|
+
def headers ; @headers ||= trim(2,:headers ) end
|
46
|
+
|
47
|
+
def rtl ; @rtl ||= trim(1,:rtl ) end
|
48
|
+
def gates ; @gates ||= trim(1,:gates ) end
|
49
|
+
def testbench ; @testbench ||= trim(1,:testbench) end
|
50
|
+
def stimulus ; @stimulus ||= trim(1,:stimulus ) end
|
51
|
+
|
52
|
+
def to_a ; @to_a ||= @hash.deep_values.flatten; end
|
53
|
+
def list ; @list ||= to_a.join(' ') ; end
|
54
|
+
def to_s ; @to_s ||= list ; end
|
55
|
+
|
56
|
+
def +(bom)
|
57
|
+
Bom.new(@hash.merge bom.hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def trim(depth,key)
|
62
|
+
hash = HashWithIndifferentAccess.new
|
63
|
+
@hash.each do |k1,l1|
|
64
|
+
case depth
|
65
|
+
when 1; hash[k1] = l1 if k1.to_s == key.to_s
|
66
|
+
when 2; hash[k1] = tmp = HashWithIndifferentAccess.new
|
67
|
+
l1.each do |k2,l2|
|
68
|
+
tmp[k2] = l2 if k2.to_s == key.to_s
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
Bom.new(hash)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright 2011 Tommy Poulter
|
2
|
+
#
|
3
|
+
# This file is part of basechip.
|
4
|
+
#
|
5
|
+
# basechip is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License version 3 as
|
7
|
+
# published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# basechip is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with basechip. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module BaseChip
|
18
|
+
class BomType
|
19
|
+
def initialize(bom,type)
|
20
|
+
@bom = bom
|
21
|
+
@type = type
|
22
|
+
end
|
23
|
+
def to_s
|
24
|
+
"#{@bom.name1}.#{@bom.name2}.#{@type}"
|
25
|
+
end
|
26
|
+
def make
|
27
|
+
f = File.open(to_s,'w')
|
28
|
+
case @type
|
29
|
+
when :text ; f.puts @bom.to_a.join("\n")
|
30
|
+
when :tcl ; fault "TCL formatted bom files not yet implemented"
|
31
|
+
else ; fault "#{@type.inspect} was not understood by #{self.class}"
|
32
|
+
end
|
33
|
+
f.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Bom
|
38
|
+
def text
|
39
|
+
@text ||= BomType.new(self,:text)
|
40
|
+
end
|
41
|
+
def tcl
|
42
|
+
@tcl ||= BomType.new(self,:tcl )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|