origen_testers 0.46.1 → 0.48.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/application.rb +1 -0
- data/config/version.rb +2 -2
- data/lib/origen_testers.rb +1 -0
- data/lib/origen_testers/atp/flow.rb +4 -0
- data/lib/origen_testers/charz.rb +434 -0
- data/lib/origen_testers/charz/profile.rb +120 -0
- data/lib/origen_testers/charz/routine.rb +38 -0
- data/lib/origen_testers/charz/routines/search_routine.rb +42 -0
- data/lib/origen_testers/charz/routines/shmoo_routine.rb +62 -0
- data/lib/origen_testers/charz/session.rb +100 -0
- data/lib/origen_testers/igxl_based_tester/base/flow.rb +2 -1
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +7 -1
- data/lib/origen_testers/labview_based_tester/pxie6570.rb +1 -1
- data/lib/origen_testers/origen_ext/generator/flow.rb +1 -0
- data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +7 -3
- data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +14 -10
- data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +10 -6
- data/lib/origen_testers/test/interface.rb +105 -0
- data/program/charz.rb +48 -0
- data/program/flow_control_flag_bug.rb +25 -0
- data/program/prb1.rb +1 -1
- data/program/test.rb +2 -0
- data/templates/origen_guides/pattern/ultraflex.md.erb~ +30 -0
- data/templates/origen_guides/program/charz.md.erb +221 -0
- metadata +43 -5
@@ -0,0 +1,120 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module Charz
|
3
|
+
# A Charz Profile
|
4
|
+
# Used to store characterization routines as well as flow control, conditional execution, and test placement meta data
|
5
|
+
class Profile
|
6
|
+
# @!attribute id
|
7
|
+
# @return [Symbol] the id of the current profile, used as a key in OrigenTesters::Charz#charz_profiles hash
|
8
|
+
# @!attribute name
|
9
|
+
# @return [Symbol] the value used (if the user decides) to generate the name of the created charz test. defaults to the value of @id
|
10
|
+
# @!attribute placement
|
11
|
+
# @return [Symbol] placement of the to be created charz tests, defaults to inline, accepts :eof as well. Other placements can be used as well if @valid_placements is altered
|
12
|
+
# @!attribute on_result
|
13
|
+
# @return [Symbol] indicates if the resulting charz tests are depending on the point tests result, valid values include :on_fail, and :on_pass
|
14
|
+
# @!attribute enables
|
15
|
+
# @return [Symbol, String, Array, Hash] enable gates to be wrapped around the resulting charz tests
|
16
|
+
# @!attribute flags
|
17
|
+
# @return [Symbol, String, Array, Hash] flag gates to be wrapped around the resulting charz tests
|
18
|
+
# @!attribute routines
|
19
|
+
# @return [Array] list of charz routines to be called under this profile
|
20
|
+
# @!attribute charz_only
|
21
|
+
# @return [Boolean] indicates if the point tests should or shouldn't be added to the flow
|
22
|
+
attr_accessor :id, :name, :placement, :on_result, :enables, :flags, :routines, :charz_only
|
23
|
+
|
24
|
+
def initialize(id, options, &block)
|
25
|
+
@id = id
|
26
|
+
@id = @id.symbolize unless id.is_a? Symbol
|
27
|
+
options.each { |k, v| instance_variable_set("@#{k}", v) }
|
28
|
+
(block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
|
29
|
+
@name ||= id
|
30
|
+
@placement ||= :inline
|
31
|
+
@defined_routines = options.delete(:defined_routines)
|
32
|
+
attrs_ok?
|
33
|
+
end
|
34
|
+
|
35
|
+
def attrs_ok?
|
36
|
+
return if @quality_check == false
|
37
|
+
|
38
|
+
unknown_routines = @routines - @defined_routines
|
39
|
+
unless unknown_routines.empty?
|
40
|
+
Origen.log.error "Profile #{id}: unknown routines: #{unknown_routines}"
|
41
|
+
fail
|
42
|
+
end
|
43
|
+
|
44
|
+
@valid_placements ||= [:inline, :eof]
|
45
|
+
unless @valid_placements.include? @placement
|
46
|
+
Origen.log.error "Profile #{id}: invalid placement value, must be one of: #{@valid_placements}"
|
47
|
+
fail
|
48
|
+
end
|
49
|
+
|
50
|
+
if @on_result
|
51
|
+
@valid_on_results ||= [:on_fail, :fail, :failed, :on_pass, :pass, :passed]
|
52
|
+
unless @valid_on_results.include?(@on_result)
|
53
|
+
Origen.log.error "Profile #{id}: invalid on_result value, must be one of: #{@valid_on_results}"
|
54
|
+
fail
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if @charz_only && @on_result
|
59
|
+
Origen.log.error "Profile #{id}: @charz_only is set, but @on_result (#{@on_result}) requires the parent test to exist in the flow"
|
60
|
+
fail
|
61
|
+
end
|
62
|
+
|
63
|
+
unless @gate_checks == false
|
64
|
+
gate_check(@enables, :enables) if @enables
|
65
|
+
gate_check(@flags, :flags) if @flags
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def gate_check(gates, gate_type)
|
70
|
+
case gates
|
71
|
+
when Symbol, String
|
72
|
+
return
|
73
|
+
when Array
|
74
|
+
unknown_gates = gates.reject { |gate| [String, Symbol].include? gate.class }
|
75
|
+
if unknown_gates.empty?
|
76
|
+
return
|
77
|
+
else
|
78
|
+
Origen.log.error "Profile #{id}: Unknown #{gate_type} type(s) in #{gate_type} array."
|
79
|
+
Origen.log.error "Arrays must contain Strings and/or Symbols, but #{unknown_gates.map(&:class).uniq } were found in #{gates}"
|
80
|
+
fail
|
81
|
+
end
|
82
|
+
when Hash
|
83
|
+
gates.each do |gate, gated_routines|
|
84
|
+
if gate.is_a? Hash
|
85
|
+
Origen.log.error "Profile #{id}: #{gate_type} Hash keys cannot be of type Hash, but only Symbol, String, or Array"
|
86
|
+
fail
|
87
|
+
end
|
88
|
+
gate_check(gate, gate_type)
|
89
|
+
gated_routines = [gated_routines] unless gated_routines.is_a? Array
|
90
|
+
unknown_routines = gated_routines - @defined_routines
|
91
|
+
unless unknown_routines.empty?
|
92
|
+
Origen.log.error "Profile #{id}: unknown routines found in @#{gate_type}[#{gate.is_a?(Symbol) ? ':' : ''}#{gate}]: #{unknown_routines}"
|
93
|
+
fail
|
94
|
+
end
|
95
|
+
end
|
96
|
+
else
|
97
|
+
Origen.log.error "Profile #{id}: Unknown #{gate_type} type: #{gates.class}. #{gate_type} must be of type Symbol, String, Array, or Hash"
|
98
|
+
fail
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def method_missing(m, *args, &block)
|
103
|
+
ivar = "@#{m.to_s.gsub('=', '')}"
|
104
|
+
ivar_sym = ":#{ivar}"
|
105
|
+
if m.to_s =~ /=$/
|
106
|
+
define_singleton_method(m) do |val|
|
107
|
+
instance_variable_set(ivar, val)
|
108
|
+
end
|
109
|
+
elsif instance_variables.include? ivar_sym
|
110
|
+
instance_variable_get(ivar)
|
111
|
+
else
|
112
|
+
define_singleton_method(m) do
|
113
|
+
instance_variable_get(ivar)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
send(m, *args, &block)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module Charz
|
3
|
+
# A Generic charz routine
|
4
|
+
# Used to store characterization test specific meta data, values of which are used by the user to determine test parameter values
|
5
|
+
class Routine
|
6
|
+
# @!attribute id
|
7
|
+
# @return [Symbol] charz routine symbol, used as a key in OrigenTesters::Charz#charz_routines
|
8
|
+
# @!attribute name
|
9
|
+
# @return [Symbol] the value used (if the user decides) to generate the name of the created charz test. defaults to the value of @id
|
10
|
+
attr_accessor :id, :name
|
11
|
+
|
12
|
+
def initialize(id, options = {}, &block)
|
13
|
+
@id = id
|
14
|
+
@id = @id.symbolize unless id.is_a? Symbol
|
15
|
+
options.each { |k, v| instance_variable_set("@#{k}", v) }
|
16
|
+
(block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
|
17
|
+
@name ||= @id
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(m, *args, &block)
|
21
|
+
ivar = "@#{m.to_s.gsub('=', '')}"
|
22
|
+
ivar_sym = ":#{ivar}"
|
23
|
+
if m.to_s =~ /=$/
|
24
|
+
define_singleton_method(m) do |val|
|
25
|
+
instance_variable_set(ivar, val)
|
26
|
+
end
|
27
|
+
elsif instance_variables.include? ivar_sym
|
28
|
+
instance_variable_get(ivar)
|
29
|
+
else
|
30
|
+
define_singleton_method(m) do
|
31
|
+
instance_variable_get(ivar)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
send(m, *args, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module Charz
|
3
|
+
# a 1D search routine
|
4
|
+
class SearchRoutine < Routine
|
5
|
+
# @!attribute start
|
6
|
+
# @return [Numeric] search start value
|
7
|
+
# @!attribute stop
|
8
|
+
# @return [Numeric] search stop value
|
9
|
+
# @!attribute res
|
10
|
+
# @return [Numeric] search resolution
|
11
|
+
# @!attribute spec
|
12
|
+
# @return [Numeric] spec parameter to be searched
|
13
|
+
attr_accessor :start, :stop, :res, :spec
|
14
|
+
|
15
|
+
# Runs the same initialization as Routine
|
16
|
+
# performs some rudimentary quality checks, which can be disabled by setting @quality_check = false
|
17
|
+
def initialize(id, options = {}, &block)
|
18
|
+
super
|
19
|
+
attrs_ok?
|
20
|
+
end
|
21
|
+
|
22
|
+
def attrs_ok?
|
23
|
+
return if @quality_check == false
|
24
|
+
|
25
|
+
@required_attrs ||= [:start, :stop, :res, :spec]
|
26
|
+
attrs = @required_attrs.map { |attr| instance_variable_get("@#{attr}") }
|
27
|
+
if attrs.compact.size != @required_attrs.size
|
28
|
+
Origen.log.error "SearchRoutine #{@id}: unspecified attributes, each of #{@required_attrs} must have a value"
|
29
|
+
fail
|
30
|
+
end
|
31
|
+
|
32
|
+
return if @attr_value_check == false
|
33
|
+
if [@start, @stop, @res].all? { |attr| attr.is_a? Numeric }
|
34
|
+
unless @res <= (@start - @stop).abs
|
35
|
+
Origen.log.error "SearchRoutine #{@id}: Search resolution (#{@res}) is larger than the search range: #{(@start - @stop).abs}"
|
36
|
+
fail
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module Charz
|
3
|
+
# A 2D search or "Shmoo" routine
|
4
|
+
class ShmooRoutine < Routine
|
5
|
+
# @!attribute x_start
|
6
|
+
# @return [Numeric] the starting search value for the x dimension's spec search
|
7
|
+
# @!attribute x_stop
|
8
|
+
# @return [Numeric] the stopping search value for the x dimension's spec search
|
9
|
+
# @!attribute x_res
|
10
|
+
# @return the search resolution value for the x dimension's spec search
|
11
|
+
# @!attribute x_spec
|
12
|
+
# @return [Symbol, String] the spec parameter of interest for the x dimension
|
13
|
+
attr_accessor :x_start, :x_stop, :x_res, :x_spec
|
14
|
+
# @!attribute y_start
|
15
|
+
# @return [Numeric] the starting search value for the x dimension's spec search
|
16
|
+
# @!attribute y_stop
|
17
|
+
# @return [Numeric] the stopping search value for the x dimension's spec search
|
18
|
+
# @!attribute y_res
|
19
|
+
# @return the search resolution value for the x dimension's spec search
|
20
|
+
# @!attribute y_spec
|
21
|
+
# @return [Symbol, String] the spec parameter of interest for the x dimension
|
22
|
+
attr_accessor :y_start, :y_stop, :y_res, :y_spec
|
23
|
+
|
24
|
+
def initialize(id, options = {}, &block)
|
25
|
+
super
|
26
|
+
attrs_ok?
|
27
|
+
end
|
28
|
+
|
29
|
+
def attrs_ok?
|
30
|
+
return if @quality_check == false
|
31
|
+
|
32
|
+
@required_attrs ||= [:x_start, :x_stop, :x_res, :x_spec, :y_start, :y_stop, :y_res, :y_spec]
|
33
|
+
attrs = @required_attrs.map { |attr| instance_variable_get("@#{attr}") }
|
34
|
+
if attrs.compact.size != @required_attrs.size
|
35
|
+
Origen.log.error "ShmooRoutine #{@id}: unspecified attributes, each of #{@required_attrs} must have a value"
|
36
|
+
fail
|
37
|
+
end
|
38
|
+
|
39
|
+
return if @attr_value_check == false
|
40
|
+
|
41
|
+
# not sure if I want this check, if so need to scope out if step count is common
|
42
|
+
|
43
|
+
# if [@x_start, @x_stop, @x_res].all? { |attr| attr.is_a? Numeric }
|
44
|
+
# unless @x_res <= (@x_start - @x_stop).abs
|
45
|
+
# Origen.log.error "ShmooRoutine #{@id}: Search x_resolution (#{@x_res} is larger than the search x_range (#{@x_start - @x_stop).abs})"
|
46
|
+
# fail
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
# if [@y_start, @y_stop, @y_res].all? { |attr| attr.is_a? Numeric }
|
50
|
+
# unless @y_res <= (@y_start - @y_stop).abs
|
51
|
+
# Origen.log.error "ShmooRoutine #{@id}: Search y_resolution (#{@y_res} is larger than the search y_range (#{@y_start - @y_stop).abs})"
|
52
|
+
# fail
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
unless @x_spec != @y_spec
|
56
|
+
Origen.log.error "ShmooRoutine #{@id}: Search x_spec is identical to y_spec"
|
57
|
+
fail
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module Charz
|
3
|
+
# A charz session
|
4
|
+
# contains the final combination of charz object (routines/profiles) and user options to determine how and what charz tests should be created
|
5
|
+
# the session should be checked in your interface to determine the current status and can be queried to make charz generation decisions
|
6
|
+
class Session < Profile
|
7
|
+
# @!attribute defaults
|
8
|
+
# @return [Hash] list of values to instantiate the inherited attributes from Profile with if not altered by the session update
|
9
|
+
attr_accessor :defaults
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@id = :current_charz_session
|
13
|
+
@active = false
|
14
|
+
@valid = false
|
15
|
+
if options[:defaults]
|
16
|
+
@defaults = options[:defaults]
|
17
|
+
else
|
18
|
+
@defaults = {
|
19
|
+
placement: :inline,
|
20
|
+
on_result: nil,
|
21
|
+
enables: nil,
|
22
|
+
flags: nil,
|
23
|
+
name: 'charz',
|
24
|
+
charz_only: false
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Pauses the current session's activity while maintaining everthing else about the sessions state
|
30
|
+
def pause
|
31
|
+
@active = false
|
32
|
+
end
|
33
|
+
|
34
|
+
# Resume activity, if the session is valid
|
35
|
+
def resume
|
36
|
+
if @valid
|
37
|
+
@active = true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Takes a Routine or Profile, and queries it to setup the session's attributes
|
42
|
+
# the attributes values can be set from 3 different sources, in order of priority (first is most important):
|
43
|
+
# - options
|
44
|
+
# - charz object
|
45
|
+
# - defaults
|
46
|
+
#
|
47
|
+
# If the resulting session is invalid, @valid will turn false. Otherwise, the session becomes active
|
48
|
+
def update(charz_obj, options)
|
49
|
+
@valid = false
|
50
|
+
if charz_obj.nil?
|
51
|
+
@active = false
|
52
|
+
@valid = false
|
53
|
+
return @valid
|
54
|
+
end
|
55
|
+
@defined_routines = options.delete(:defined_routines)
|
56
|
+
assign_by_priority(:placement, charz_obj, options)
|
57
|
+
assign_by_priority(:on_result, charz_obj, options)
|
58
|
+
assign_by_priority(:enables, charz_obj, options)
|
59
|
+
assign_by_priority(:flags, charz_obj, options)
|
60
|
+
assign_by_priority(:routines, charz_obj, options)
|
61
|
+
assign_by_priority(:name, charz_obj, options)
|
62
|
+
assign_by_priority(:charz_only, charz_obj, options)
|
63
|
+
attrs_ok?
|
64
|
+
massage_gates
|
65
|
+
@active = true
|
66
|
+
@valid = true
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# convert hash gates to set convert their routines to type array if not already
|
72
|
+
def massage_gates
|
73
|
+
if @enables.is_a?(Hash)
|
74
|
+
@enables = {}.tap do |new_h|
|
75
|
+
@enables.each { |gates, routines| new_h[gates] = [routines].flatten }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if @flags.is_a?(Hash)
|
79
|
+
@flags = {}.tap do |new_h|
|
80
|
+
@flags.each { |gates, routines| new_h[gates] = [routines].flatten }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# see initialize
|
86
|
+
def assign_by_priority(ivar, charz_obj, options)
|
87
|
+
if options.keys.include?(ivar)
|
88
|
+
instance_variable_set("@#{ivar}", options[ivar])
|
89
|
+
elsif charz_obj.send(ivar)
|
90
|
+
instance_variable_set("@#{ivar}", charz_obj.send(ivar))
|
91
|
+
elsif @defaults.keys.include?(ivar)
|
92
|
+
instance_variable_set("@#{ivar}", @defaults[ivar])
|
93
|
+
else
|
94
|
+
Origen.log.error "Charz Session: No value could be determined for #{ivar}"
|
95
|
+
fail
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -10,14 +10,20 @@ module OrigenTesters
|
|
10
10
|
def on_test(node)
|
11
11
|
super
|
12
12
|
ins = node.find(:object).value
|
13
|
-
|
13
|
+
|
14
|
+
# allow defer limits when limits are only given in sub tests
|
15
|
+
if ins.respond_to?(:defer_limits)
|
14
16
|
if ins.defer_limits
|
15
17
|
completed_lines.last.opcode = 'Test-defer-limits'
|
16
18
|
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if ins.respond_to?(:lo_limit) && (ins.lo_limit || ins.hi_limit) || ins.respond_to?(:lo) && (ins.lo || ins.hi)
|
17
22
|
limit = completed_lines.last.dup
|
18
23
|
limit.type = :use_limit
|
19
24
|
limit.opcode = 'Use-Limit'
|
20
25
|
limit.parameter = nil
|
26
|
+
limit.tnum = nil # Don't duplate test numbers, allow auto-increment by leaving blank
|
21
27
|
if ins.respond_to?(:lo_limit)
|
22
28
|
lo = ins.lo_limit
|
23
29
|
hi = ins.hi_limit
|
@@ -36,7 +36,7 @@ module OrigenTesters
|
|
36
36
|
unless options[:subroutine_pat]
|
37
37
|
stage.with_bank(:body) do
|
38
38
|
# find the first vector
|
39
|
-
stage.bank.delete_at(0) until stage.bank[0].is_a?(OrigenTesters::Vector)
|
39
|
+
stage.bank.delete_at(0) until stage.bank[0].is_a?(OrigenTesters::Vector) || stage.bank.empty?
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -138,6 +138,7 @@ module Origen
|
|
138
138
|
end
|
139
139
|
Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
|
140
140
|
interface.instance_eval(&block)
|
141
|
+
Origen.interface.generate_eof_charz_tests if Origen.interface.respond_to?(:generate_eof_charz_tests)
|
141
142
|
Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
|
142
143
|
interface.at_flow_end if interface.respond_to?(:at_flow_end)
|
143
144
|
Origen.app.listeners_for(:on_flow_end).each do |listener|
|
@@ -119,6 +119,7 @@ module OrigenTesters
|
|
119
119
|
o[:test_name] = extract_test_name(node, o)
|
120
120
|
o[:test_number] = extract_test_number(node, o)
|
121
121
|
o[:limits] = extract_limits(node, o)
|
122
|
+
o[:test_text] = node.find(:test_text).try(:value)
|
122
123
|
if on_fail = node.find(:on_fail)
|
123
124
|
if set_result = on_fail.find(:set_result)
|
124
125
|
if bin = set_result.find(:bin)
|
@@ -252,9 +253,12 @@ module OrigenTesters
|
|
252
253
|
# "Test Number"
|
253
254
|
l << f(options[:test_number])
|
254
255
|
# "Test Text"
|
255
|
-
|
256
|
-
|
257
|
-
|
256
|
+
if options[:test_text]
|
257
|
+
l << f(options[:test_text])
|
258
|
+
else
|
259
|
+
names = ["#{options[:suite_name]}", "#{options[:test_name]}"]
|
260
|
+
l << f(names.uniq.join('.'))
|
261
|
+
end
|
258
262
|
if test_modes.empty?
|
259
263
|
# "Low Limit"
|
260
264
|
l << f((options[:limits][nil] || {})[:lsl])
|
@@ -35,21 +35,25 @@ module OrigenTesters
|
|
35
35
|
|
36
36
|
# What SMT7 calls a flag
|
37
37
|
def flags
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
if variables
|
39
|
+
(variables[:all][:referenced_enables] + variables[:all][:set_enables]).uniq.sort do |x, y|
|
40
|
+
x = x[0] if x.is_a?(Array)
|
41
|
+
y = y[0] if y.is_a?(Array)
|
42
|
+
# Need to use strings for the comparison as some flags can be a string and some a symbol
|
43
|
+
x.to_s <=> y.to_s
|
44
|
+
end
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
48
|
# What SMT7 calls a declaration
|
47
49
|
def declarations
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
if variables
|
51
|
+
(variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags]).uniq.sort do |x, y|
|
52
|
+
x = x[0] if x.is_a?(Array)
|
53
|
+
y = y[0] if y.is_a?(Array)
|
54
|
+
# Need to use strings for the comparison as some declarations can be a string and some a symbol
|
55
|
+
x.to_s <=> y.to_s
|
56
|
+
end
|
53
57
|
end
|
54
58
|
end
|
55
59
|
|