mirror of https://github.com/KLayout/klayout.git
Compatibility with ruby 1.8, force garbage cleanup for LVS/DRC and tests.
This commit is contained in:
parent
6e6e449eef
commit
df7195b81f
|
|
@ -1,5 +1,7 @@
|
||||||
# $autorun-early
|
# $autorun-early
|
||||||
|
|
||||||
|
require 'pathname'
|
||||||
|
|
||||||
module DRC
|
module DRC
|
||||||
|
|
||||||
# The DRC engine
|
# The DRC engine
|
||||||
|
|
@ -1335,126 +1337,135 @@ CODE
|
||||||
|
|
||||||
def _finish(final = true)
|
def _finish(final = true)
|
||||||
|
|
||||||
_flush
|
begin
|
||||||
|
|
||||||
view = RBA::LayoutView::current
|
_flush
|
||||||
|
|
||||||
# save the report database if requested
|
view = RBA::LayoutView::current
|
||||||
if @output_rdb_file
|
|
||||||
rdb_file = _make_path(@output_rdb_file)
|
|
||||||
info("Writing report database: #{rdb_file} ..")
|
|
||||||
@output_rdb.save(rdb_file)
|
|
||||||
end
|
|
||||||
if @output_rdb && final && view
|
|
||||||
view.show_rdb(@output_rdb_index, view.active_cellview_index)
|
|
||||||
end
|
|
||||||
|
|
||||||
# save the output file if requested
|
# save the report database if requested
|
||||||
if @output_layout && @output_layout_file
|
if @output_rdb_file
|
||||||
opt = RBA::SaveLayoutOptions::new
|
rdb_file = _make_path(@output_rdb_file)
|
||||||
gzip = opt.set_format_from_filename(@output_layout_file)
|
info("Writing report database: #{rdb_file} ..")
|
||||||
info("Writing layout file: #{@output_layout_file} ..")
|
@output_rdb.save(rdb_file)
|
||||||
@output_layout.write(@output_layout_file, gzip, opt)
|
end
|
||||||
end
|
if @output_rdb && final && view
|
||||||
|
view.show_rdb(@output_rdb_index, view.active_cellview_index)
|
||||||
# create the new layers as visual layers if necessary
|
|
||||||
if view
|
|
||||||
|
|
||||||
output = @output_layout || @def_layout
|
|
||||||
cv_index = nil
|
|
||||||
view.cellviews.times do |cvi|
|
|
||||||
view.cellview(cvi).layout == output && cv_index = cvi
|
|
||||||
end
|
end
|
||||||
if cv_index
|
|
||||||
|
|
||||||
view = RBA::LayoutView::current
|
# save the output file if requested
|
||||||
|
if @output_layout && @output_layout_file
|
||||||
|
opt = RBA::SaveLayoutOptions::new
|
||||||
|
gzip = opt.set_format_from_filename(@output_layout_file)
|
||||||
|
info("Writing layout file: #{@output_layout_file} ..")
|
||||||
|
@output_layout.write(@output_layout_file, gzip, opt)
|
||||||
|
end
|
||||||
|
|
||||||
# clear selection
|
# create the new layers as visual layers if necessary
|
||||||
view.cancel
|
if view
|
||||||
|
|
||||||
# create layer views for those layers which are not present yet
|
output = @output_layout || @def_layout
|
||||||
|
cv_index = nil
|
||||||
present_layers = {}
|
view.cellviews.times do |cvi|
|
||||||
l = view.begin_layers
|
view.cellview(cvi).layout == output && cv_index = cvi
|
||||||
while !l.at_end?
|
|
||||||
if l.current.cellview == cv_index
|
|
||||||
present_layers[l.current.layer_index] = true
|
|
||||||
end
|
|
||||||
l.next
|
|
||||||
end
|
end
|
||||||
|
if cv_index
|
||||||
|
|
||||||
@output_layers.each do |li|
|
view = RBA::LayoutView::current
|
||||||
if !present_layers[li]
|
|
||||||
info = @def_layout.get_info(li)
|
# clear selection
|
||||||
lp = RBA::LayerProperties::new
|
view.cancel
|
||||||
lp.source_layer = info.layer
|
|
||||||
lp.source_datatype = info.datatype
|
# create layer views for those layers which are not present yet
|
||||||
lp.source_name = info.name
|
|
||||||
lp.source_cellview = cv_index
|
present_layers = {}
|
||||||
view.init_layer_properties(lp)
|
l = view.begin_layers
|
||||||
view.insert_layer(view.end_layers, lp)
|
while !l.at_end?
|
||||||
|
if l.current.cellview == cv_index
|
||||||
|
present_layers[l.current.layer_index] = true
|
||||||
|
end
|
||||||
|
l.next
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
view.update_content
|
@output_layers.each do |li|
|
||||||
|
if !present_layers[li]
|
||||||
|
info = @def_layout.get_info(li)
|
||||||
|
lp = RBA::LayerProperties::new
|
||||||
|
lp.source_layer = info.layer
|
||||||
|
lp.source_datatype = info.datatype
|
||||||
|
lp.source_name = info.name
|
||||||
|
lp.source_cellview = cv_index
|
||||||
|
view.init_layer_properties(lp)
|
||||||
|
view.insert_layer(view.end_layers, lp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
view.update_content
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
# save the netlist if required
|
||||||
|
if @target_netlist_file && @netter && @netter.l2n_data
|
||||||
|
|
||||||
# save the netlist if required
|
writer = @target_netlist_format || RBA::NetlistSpiceWriter::new
|
||||||
if @target_netlist_file && @netter && @netter.l2n_data
|
|
||||||
|
|
||||||
writer = @target_netlist_format || RBA::NetlistSpiceWriter::new
|
netlist_file = _make_path(@target_netlist_file)
|
||||||
|
info("Writing netlist: #{netlist_file} ..")
|
||||||
|
self.netlist.write(netlist_file, writer, @target_netlist_comment || "")
|
||||||
|
|
||||||
netlist_file = _make_path(@target_netlist_file)
|
end
|
||||||
info("Writing netlist: #{netlist_file} ..")
|
|
||||||
self.netlist.write(netlist_file, writer, @target_netlist_comment || "")
|
|
||||||
|
|
||||||
end
|
# save the netlist database if requested
|
||||||
|
if @output_l2ndb_file && @netter && @netter.l2n_data
|
||||||
|
|
||||||
# save the netlist database if requested
|
l2ndb_file = _make_path(@output_l2ndb_file)
|
||||||
if @output_l2ndb_file && @netter && @netter.l2n_data
|
info("Writing netlist database: #{l2ndb_file} ..")
|
||||||
|
@netter.l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long)
|
||||||
|
|
||||||
l2ndb_file = _make_path(@output_l2ndb_file)
|
end
|
||||||
info("Writing netlist database: #{l2ndb_file} ..")
|
|
||||||
@netter.l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long)
|
|
||||||
|
|
||||||
end
|
# give derived classes to perform actions
|
||||||
|
_before_cleanup
|
||||||
|
|
||||||
# give derived classes to perform actions
|
# show the data in the browser
|
||||||
_before_cleanup
|
if view && @show_l2ndb && @netter && @netter.l2n_data
|
||||||
|
|
||||||
# show the data in the browser
|
# NOTE: to prevent the netter destroying the database, we need to take it
|
||||||
if view && @show_l2ndb && @netter && @netter.l2n_data
|
l2ndb = _take_data
|
||||||
|
l2ndb_index = view.add_l2ndb(l2ndb)
|
||||||
|
view.show_l2ndb(l2ndb_index, view.active_cellview_index)
|
||||||
|
|
||||||
# NOTE: to prevent the netter destroying the database, we need to take it
|
end
|
||||||
l2ndb = _take_data
|
|
||||||
l2ndb_index = view.add_l2ndb(l2ndb)
|
|
||||||
view.show_l2ndb(l2ndb_index, view.active_cellview_index)
|
|
||||||
|
|
||||||
end
|
ensure
|
||||||
|
|
||||||
@output_layout = nil
|
@output_layout = nil
|
||||||
@output_layout_file = nil
|
@output_layout_file = nil
|
||||||
@output_cell = nil
|
@output_cell = nil
|
||||||
@output_rdb_file = nil
|
@output_rdb_file = nil
|
||||||
@output_rdb_cell = nil
|
@output_rdb_cell = nil
|
||||||
@output_rdb = nil
|
@output_rdb = nil
|
||||||
@output_rdb_index = nil
|
@output_rdb_index = nil
|
||||||
@show_l2ndb = nil
|
@show_l2ndb = nil
|
||||||
@output_l2ndb_file = nil
|
@output_l2ndb_file = nil
|
||||||
|
|
||||||
# clean up temp data
|
# clean up temp data
|
||||||
@dss && @dss._destroy
|
@dss && @dss._destroy
|
||||||
@dss = nil
|
@dss = nil
|
||||||
@netter && @netter._finish
|
@netter && @netter._finish
|
||||||
@netter = nil
|
@netter = nil
|
||||||
@netter_data = nil
|
@netter_data = nil
|
||||||
|
|
||||||
|
if final && @log_file
|
||||||
|
@log_file.close
|
||||||
|
@log_file = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# force garbage collection
|
||||||
|
GC.start
|
||||||
|
|
||||||
if final && @log_file
|
|
||||||
@log_file.close
|
|
||||||
@log_file = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -1498,7 +1509,11 @@ CODE
|
||||||
# resolves the file path relative to the source's path
|
# resolves the file path relative to the source's path
|
||||||
sp = self.source.path
|
sp = self.source.path
|
||||||
if sp
|
if sp
|
||||||
return File::absolute_path(file, File::dirname(sp))
|
if File.respond_to?(:absolute_path)
|
||||||
|
return File::absolute_path(file, File::dirname(sp))
|
||||||
|
else
|
||||||
|
return (Pathname::new(File::dirname(sp)) + Pathname.new(file)).to_s
|
||||||
|
end
|
||||||
else
|
else
|
||||||
return file
|
return file
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ module DRC
|
||||||
|
|
||||||
ensure
|
ensure
|
||||||
|
|
||||||
# cleans up and creates layout views
|
# cleans up and creates layout and report views
|
||||||
_drc._finish
|
_drc._finish
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ module LVS
|
||||||
|
|
||||||
ensure
|
ensure
|
||||||
|
|
||||||
# cleans up and creates layout views
|
# cleans up and creates layout and report views
|
||||||
_lvs._finish
|
_lvs._finish
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,34 +3,40 @@
|
||||||
# environment is shut down. Therefore we must release all RBA objects by explicitly calling the GC
|
# environment is shut down. Therefore we must release all RBA objects by explicitly calling the GC
|
||||||
# and start the test suite manually.
|
# and start the test suite manually.
|
||||||
|
|
||||||
err = 0
|
begin
|
||||||
any = nil
|
|
||||||
repeat = (ENV["TESTREPEAT"] || "1").to_i
|
|
||||||
|
|
||||||
class MyTestRunner < Test::Unit::UI::Console::TestRunner
|
err = 0
|
||||||
def initialize(suite, *args)
|
any = nil
|
||||||
super(suite, *args)
|
repeat = (ENV["TESTREPEAT"] || "1").to_i
|
||||||
end
|
|
||||||
def test_started(name)
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Object.constants.each do |c|
|
class MyTestRunner < Test::Unit::UI::Console::TestRunner
|
||||||
if c.to_s =~ /_TestClass$/
|
def initialize(suite, *args)
|
||||||
repeat.times do
|
super(suite, *args)
|
||||||
r = MyTestRunner::new(Object.const_get(c)).start
|
end
|
||||||
err += r.error_count + r.failure_count
|
def test_started(name)
|
||||||
|
super
|
||||||
end
|
end
|
||||||
any = true
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
Object.constants.each do |c|
|
||||||
if !any
|
if c.to_s =~ /_TestClass$/
|
||||||
raise("No test class defined (any ending with _TestClass)")
|
repeat.times do
|
||||||
end
|
r = MyTestRunner::new(Object.const_get(c)).start
|
||||||
|
err += r.error_count + r.failure_count
|
||||||
if err > 0
|
end
|
||||||
raise("Tests failed (#{err} Errors + Failures)")
|
any = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !any
|
||||||
|
raise("No test class defined (any ending with _TestClass)")
|
||||||
|
end
|
||||||
|
|
||||||
|
if err > 0
|
||||||
|
raise("Tests failed (#{err} Errors + Failures)")
|
||||||
|
end
|
||||||
|
|
||||||
|
ensure
|
||||||
|
GC.start
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,6 @@ Object.constants.each do |c|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Some cleanup ahead
|
||||||
|
GC.start
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue