origen 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/bin/origen +3 -1
  3. data/config/boot.rb +1 -7
  4. data/config/commands.rb +0 -1
  5. data/config/version.rb +2 -2
  6. data/lib/c99/{j750_interface.rb → ate_interface.rb} +3 -11
  7. data/lib/c99/doc_interface.rb +1 -1
  8. data/lib/origen.rb +9 -30
  9. data/lib/origen/application.rb +10 -8
  10. data/lib/origen/application/configuration.rb +13 -26
  11. data/lib/origen/application/plugins.rb +122 -0
  12. data/lib/origen/application/plugins_manager.rb +16 -254
  13. data/lib/origen/application/release.rb +2 -2
  14. data/lib/origen/application/runner.rb +2 -4
  15. data/lib/origen/chips.rb +0 -0
  16. data/lib/origen/chips/chip.rb +0 -0
  17. data/lib/origen/chips/design_entry.rb +0 -0
  18. data/lib/origen/chips/doc_entry.rb +0 -0
  19. data/lib/origen/chips/note.rb +0 -0
  20. data/lib/origen/commands.rb +4 -44
  21. data/lib/origen/commands/compile.rb +1 -2
  22. data/lib/origen/commands/generate.rb +1 -1
  23. data/lib/origen/commands/interactive.rb +1 -2
  24. data/lib/origen/commands/plugin.rb +49 -56
  25. data/lib/origen/commands/program.rb +1 -1
  26. data/lib/origen/commands/rc.rb +2 -2
  27. data/lib/origen/commands/version.rb +2 -17
  28. data/lib/origen/commands_global.rb +3 -0
  29. data/lib/origen/file_handler.rb +10 -10
  30. data/lib/origen/generator.rb +1 -1
  31. data/lib/origen/generator/job.rb +1 -1
  32. data/lib/origen/generator/pattern.rb +2 -2
  33. data/lib/origen/generator/pattern_finder.rb +10 -9
  34. data/lib/origen/pins/pin.rb +0 -0
  35. data/lib/origen/regression_manager.rb +0 -0
  36. data/lib/origen/remote_manager.rb +2 -8
  37. data/lib/origen/revision_control/design_sync.rb +0 -0
  38. data/lib/origen/revision_control/git.rb +0 -0
  39. data/lib/origen/specs.rb +0 -0
  40. data/lib/origen/specs/checkers.rb +0 -0
  41. data/lib/origen/specs/creation_info.rb +0 -0
  42. data/lib/origen/specs/exhibit.rb +0 -0
  43. data/lib/origen/specs/spec.rb +0 -0
  44. data/lib/origen/utility.rb +0 -1
  45. data/lib/origen/utility/diff.rb +0 -0
  46. metadata +42 -119
  47. data/lib/origen/import_manager.rb +0 -596
  48. data/lib/origen/nvm.rb +0 -6
  49. data/lib/origen/nvm/block_array.rb +0 -72
  50. data/lib/origen/tester.rb +0 -56
  51. data/lib/origen/tester/api.rb +0 -277
  52. data/lib/origen/tester/bdm/bdm.rb +0 -25
  53. data/lib/origen/tester/doc/doc.rb +0 -226
  54. data/lib/origen/tester/doc/generator.rb +0 -126
  55. data/lib/origen/tester/doc/generator/flow.rb +0 -71
  56. data/lib/origen/tester/doc/generator/flow_line.rb +0 -203
  57. data/lib/origen/tester/doc/generator/test.rb +0 -68
  58. data/lib/origen/tester/doc/generator/test_group.rb +0 -66
  59. data/lib/origen/tester/doc/generator/tests.rb +0 -47
  60. data/lib/origen/tester/doc/model.rb +0 -162
  61. data/lib/origen/tester/generator.rb +0 -271
  62. data/lib/origen/tester/generator/flow_control_api.rb +0 -606
  63. data/lib/origen/tester/generator/identity_map.rb +0 -25
  64. data/lib/origen/tester/generator/placeholder.rb +0 -13
  65. data/lib/origen/tester/generator/test_numberer.rb +0 -25
  66. data/lib/origen/tester/interface.rb +0 -154
  67. data/lib/origen/tester/j750/files.rb +0 -45
  68. data/lib/origen/tester/j750/generator.rb +0 -203
  69. data/lib/origen/tester/j750/generator/flow.rb +0 -123
  70. data/lib/origen/tester/j750/generator/flow_line.rb +0 -288
  71. data/lib/origen/tester/j750/generator/patgroup.rb +0 -111
  72. data/lib/origen/tester/j750/generator/patgroups.rb +0 -41
  73. data/lib/origen/tester/j750/generator/patset.rb +0 -111
  74. data/lib/origen/tester/j750/generator/patsets.rb +0 -41
  75. data/lib/origen/tester/j750/generator/templates/flow.txt.erb +0 -9
  76. data/lib/origen/tester/j750/generator/templates/instances.txt.erb +0 -16
  77. data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +0 -8
  78. data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +0 -10
  79. data/lib/origen/tester/j750/generator/test_instance.rb +0 -846
  80. data/lib/origen/tester/j750/generator/test_instance_group.rb +0 -60
  81. data/lib/origen/tester/j750/generator/test_instances.rb +0 -182
  82. data/lib/origen/tester/j750/j750.rb +0 -845
  83. data/lib/origen/tester/j750/j750_hpt.rb +0 -35
  84. data/lib/origen/tester/j750/parser.rb +0 -104
  85. data/lib/origen/tester/j750/parser/ac_spec.rb +0 -11
  86. data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
  87. data/lib/origen/tester/j750/parser/dc_spec.rb +0 -36
  88. data/lib/origen/tester/j750/parser/dc_specs.rb +0 -50
  89. data/lib/origen/tester/j750/parser/descriptions.rb +0 -340
  90. data/lib/origen/tester/j750/parser/flow.rb +0 -111
  91. data/lib/origen/tester/j750/parser/flow_line.rb +0 -207
  92. data/lib/origen/tester/j750/parser/flows.rb +0 -23
  93. data/lib/origen/tester/j750/parser/pattern_set.rb +0 -94
  94. data/lib/origen/tester/j750/parser/pattern_sets.rb +0 -33
  95. data/lib/origen/tester/j750/parser/test_instance.rb +0 -322
  96. data/lib/origen/tester/j750/parser/test_instances.rb +0 -26
  97. data/lib/origen/tester/j750/parser/timeset.rb +0 -15
  98. data/lib/origen/tester/j750/parser/timesets.rb +0 -0
  99. data/lib/origen/tester/jlink/jlink.rb +0 -33
  100. data/lib/origen/tester/parser.rb +0 -24
  101. data/lib/origen/tester/parser/description_lookup.rb +0 -64
  102. data/lib/origen/tester/parser/searchable_array.rb +0 -32
  103. data/lib/origen/tester/parser/searchable_hash.rb +0 -32
  104. data/lib/origen/tester/time.rb +0 -338
  105. data/lib/origen/tester/timing.rb +0 -253
  106. data/lib/origen/tester/ultraflex/files.rb +0 -45
  107. data/lib/origen/tester/ultraflex/generator.rb +0 -200
  108. data/lib/origen/tester/ultraflex/generator/flow.rb +0 -119
  109. data/lib/origen/tester/ultraflex/generator/flow_line.rb +0 -269
  110. data/lib/origen/tester/ultraflex/generator/patgroup.rb +0 -111
  111. data/lib/origen/tester/ultraflex/generator/patgroups.rb +0 -41
  112. data/lib/origen/tester/ultraflex/generator/patset.rb +0 -111
  113. data/lib/origen/tester/ultraflex/generator/patsets.rb +0 -41
  114. data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +0 -9
  115. data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +0 -16
  116. data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +0 -8
  117. data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +0 -10
  118. data/lib/origen/tester/ultraflex/generator/test_instance.rb +0 -622
  119. data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +0 -60
  120. data/lib/origen/tester/ultraflex/generator/test_instances.rb +0 -174
  121. data/lib/origen/tester/ultraflex/parser.rb +0 -104
  122. data/lib/origen/tester/ultraflex/parser/ac_spec.rb +0 -11
  123. data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
  124. data/lib/origen/tester/ultraflex/parser/dc_spec.rb +0 -36
  125. data/lib/origen/tester/ultraflex/parser/dc_specs.rb +0 -50
  126. data/lib/origen/tester/ultraflex/parser/descriptions.rb +0 -342
  127. data/lib/origen/tester/ultraflex/parser/flow.rb +0 -111
  128. data/lib/origen/tester/ultraflex/parser/flow_line.rb +0 -207
  129. data/lib/origen/tester/ultraflex/parser/flows.rb +0 -23
  130. data/lib/origen/tester/ultraflex/parser/pattern_set.rb +0 -94
  131. data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +0 -33
  132. data/lib/origen/tester/ultraflex/parser/test_instance.rb +0 -262
  133. data/lib/origen/tester/ultraflex/parser/test_instances.rb +0 -26
  134. data/lib/origen/tester/ultraflex/parser/timeset.rb +0 -15
  135. data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
  136. data/lib/origen/tester/ultraflex/ultraflex.rb +0 -759
  137. data/lib/origen/tester/v93k/generator.rb +0 -80
  138. data/lib/origen/tester/v93k/generator/flow.rb +0 -63
  139. data/lib/origen/tester/v93k/generator/flow_node.rb +0 -17
  140. data/lib/origen/tester/v93k/generator/flow_node/print.rb +0 -10
  141. data/lib/origen/tester/v93k/generator/pattern.rb +0 -16
  142. data/lib/origen/tester/v93k/generator/pattern_master.rb +0 -54
  143. data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +0 -6
  144. data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +0 -11
  145. data/lib/origen/tester/v93k/generator/templates/template.flow.erb +0 -121
  146. data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +0 -9
  147. data/lib/origen/tester/v93k/generator/test_function.rb +0 -103
  148. data/lib/origen/tester/v93k/generator/test_functions.rb +0 -79
  149. data/lib/origen/tester/v93k/generator/test_method.rb +0 -46
  150. data/lib/origen/tester/v93k/generator/test_methods.rb +0 -75
  151. data/lib/origen/tester/v93k/generator/test_suite.rb +0 -54
  152. data/lib/origen/tester/v93k/generator/test_suites.rb +0 -65
  153. data/lib/origen/tester/v93k/v93k.rb +0 -420
  154. data/lib/origen/tester/vector.rb +0 -86
  155. data/lib/origen/tester/vector_generator.rb +0 -637
  156. data/lib/origen/tester/vector_pipeline.rb +0 -150
  157. data/lib/origen/utility/design_sync.rb +0 -494
  158. data/lib/origen/version_checker.rb +0 -117
@@ -1,60 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- module Generator
5
- class TestInstanceGroup
6
- attr_accessor :name, :version, :append_version
7
-
8
- include Enumerable
9
-
10
- def initialize(name, _options = {})
11
- @name = name
12
- @store = []
13
- @append_version = true
14
- end
15
-
16
- def name
17
- if unversioned_name
18
- if version && @append_version
19
- "#{unversioned_name}_v#{version}"
20
- else
21
- unversioned_name.to_s
22
- end
23
- end
24
- end
25
-
26
- def unversioned_name
27
- if @name
28
- if @name =~ /grp$/
29
- @name
30
- else
31
- "#{@name}_grp"
32
- end
33
- end
34
- end
35
-
36
- def <<(instance)
37
- @store << instance
38
- end
39
-
40
- def size
41
- @store.size
42
- end
43
-
44
- def each
45
- @store.each { |ins| yield ins }
46
- end
47
-
48
- def ==(other_instance_group)
49
- self.class == other_instance_group.class &&
50
- unversioned_name.to_s == other_instance_group.unversioned_name.to_s &&
51
- size == other_instance_group.size &&
52
- self.all? do |ins|
53
- other_instance_group.any? { |other_ins| ins == other_ins }
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,174 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- module Generator
5
- class TestInstances
6
- include Origen::Tester::Generator
7
-
8
- TEMPLATE = "#{Origen.top}/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb"
9
- OUTPUT_POSTFIX = 'instances'
10
-
11
- class IndexedString < ::String
12
- attr_accessor :index
13
-
14
- def name
15
- self
16
- end
17
- end
18
-
19
- def add(name, type, options = {})
20
- options = {
21
- test_instance_class: TestInstance
22
- }.merge(options)
23
- ins = options.delete(:test_instance_class).new(name, type, options)
24
- if @current_group
25
- @current_group << ins
26
- else
27
- collection << ins
28
- end
29
- c = Origen.interface.consume_comments
30
- Origen.interface.descriptions.add_for_test_definition(name, c)
31
- ins
32
- end
33
-
34
- # IG-XL doesn't have a formal instance group type and instead declares them anonymously
35
- # whenever test instances of the same name appear consecutively in the test instance sheet.
36
- # However when it comes to generating a test program life becomes much easier if we have
37
- # a way to explicitly declare instances as part of a group - this makes duplicate tracking
38
- # and sorting of the test instance sheet much easier.
39
- #
40
- # Use this method to generate instance groups via a block. Within the the block you should
41
- # generate instances as normal and they will automatically be assigned to the current group.
42
- # Note that the name of the instances generated within the group is discarded and replaced
43
- # with the name of the group. Origen automatically appends "grp" to this name to highlight
44
- # instances that were generated as part of the group.
45
- #
46
- # test_instances.group("erase_all_blocks") do |group|
47
- # # Generate instances here as normal
48
- # test_instances.functional("erase_blk0")
49
- # test_instances.functional("erase_blk1")
50
- # end
51
- #
52
- # The group object is passed into the block but usually you should not need to interact
53
- # with this directly except maybe to set the name if it is not yet established at the point
54
- # where the group is initiated:
55
- #
56
- # test_instances.group do |group|
57
- # # Generate instances here as normal
58
- # group.name = "group_blah"
59
- # end
60
- #
61
- # A common way to generate groups is to create a helper method in your application which
62
- # is responsible for creating groups as required:
63
- #
64
- # def group_wrapper(name, options)
65
- # if options[:by_block]
66
- # test_instances.group(name) do |group|
67
- # yield group
68
- # end
69
- # else
70
- # yield
71
- # end
72
- # end
73
- #
74
- # In that case the group argument becomes quite useful for branching based on whether you
75
- # are generating a group or standalone instances:
76
- #
77
- # group_wrapper(name, options) do |group|
78
- # if group
79
- # # Generate group instances
80
- # else
81
- # # Generate standalone instances
82
- # end
83
- # end
84
- def group(name = nil, options = {})
85
- name, options = nil, name if name.is_a?(Hash)
86
- @current_group = TestInstanceGroup.new(name, options)
87
- collection << @current_group
88
- yield @current_group
89
- @current_group = nil
90
- end
91
- alias_method :add_group, :group
92
-
93
- def finalize(_options = {}) # :nodoc:
94
- uniq!
95
- sort!
96
- end
97
-
98
- def uniq! # :nodoc:
99
- uniques = []
100
- versions = {}
101
- multi_version_tests = {}
102
- collection.each do |instance|
103
- # If a uniquely named instance is found add it, otherwise update the version
104
- # of the current instance to match that of the existing instance that it duplicates
105
- unless uniques.any? do |i|
106
- if i == instance
107
- instance.version = i.version
108
- true
109
- else
110
- false
111
- end
112
- end
113
- if instance.respond_to?(:version=)
114
- versions[instance.unversioned_name] ||= 0
115
- versions[instance.unversioned_name] += 1
116
- if versions[instance.unversioned_name] > 1
117
- multi_version_tests[instance.unversioned_name] = true
118
- end
119
- instance.version = versions[instance.unversioned_name]
120
- end
121
- uniques << instance
122
- end
123
- end
124
- # This final loop disables the version identifier for tests that have only a single version,
125
- # this makes it clearer when multiple versions exist - whenever you see a v1 you know there
126
- # is at least a v2 also.
127
- collection.map! do |instance|
128
- if instance.respond_to?(:version=)
129
- unless multi_version_tests[instance.unversioned_name]
130
- instance.append_version = false
131
- end
132
- end
133
- instance
134
- end
135
- self.collection = uniques
136
- end
137
-
138
- def sort! # :nodoc:
139
- # Present the instances in the final sheet in alphabetical order
140
- collection.map!.with_index do |ins, _i|
141
- if ins.is_a?(String) # Can happen if content has been rendered in from a template
142
- ins = IndexedString.new(ins)
143
- end
144
- ins
145
- end
146
- collection.sort! { |a, b| [a.name.to_s] <=> [b.name.to_s] }
147
- end
148
-
149
- def bpmu(name, options = {})
150
- add(name, :board_pmu, options)
151
- end
152
- alias_method :board_pmu, :bpmu
153
-
154
- def ppmu(name, options = {})
155
- add(name, :pin_pmu, options)
156
- end
157
- alias_method :pin_pmu, :ppmu
158
-
159
- def functional(name, options = {})
160
- add(name, :functional, options)
161
- end
162
-
163
- def empty(name, options = {})
164
- add(name, :empty, options)
165
- end
166
-
167
- def other(name, options = {})
168
- add(name, :other, options)
169
- end
170
- end
171
- end
172
- end
173
- end
174
- end
@@ -1,104 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- class Parser
5
- autoload :Flows, 'origen/tester/ultraflex/parser/flows'
6
- autoload :Flow, 'origen/tester/ultraflex/parser/flow'
7
- autoload :FlowLine, 'origen/tester/ultraflex/parser/flow_line'
8
- autoload :TestInstances, 'origen/tester/ultraflex/parser/test_instances'
9
- autoload :TestInstance, 'origen/tester/ultraflex/parser/test_instance'
10
- autoload :PatternSets, 'origen/tester/ultraflex/parser/pattern_sets'
11
- autoload :PatternSet, 'origen/tester/ultraflex/parser/pattern_set'
12
- autoload :DCSpecs, 'origen/tester/ultraflex/parser/dc_specs'
13
- autoload :DCSpec, 'origen/tester/ultraflex/parser/dc_spec'
14
- autoload :ACSpecs, 'origen/tester/ultraflex/parser/ac_specs'
15
- autoload :ACSpec, 'origen/tester/ultraflex/parser/ac_spec'
16
- autoload :Descriptions, 'origen/tester/ultraflex/parser/descriptions'
17
-
18
- def reset
19
- @flows = nil
20
- @test_instances = nil
21
- @pattern_sets = nil
22
- @dc_specs = nil
23
- @ac_specs = nil
24
- end
25
-
26
- def descriptions
27
- @descriptions ||= Descriptions.new(parser: self)
28
- end
29
-
30
- # Returns an array of test flows
31
- def flows
32
- @flows ||= Flows.new(parser: self)
33
- end
34
-
35
- def test_instances
36
- @test_instances ||= TestInstances.new(parser: self)
37
- end
38
- alias_method :instances, :test_instances
39
-
40
- def pattern_sets
41
- @pattern_sets ||= PatternSets.new(parser: self)
42
- end
43
- alias_method :patsets, :pattern_sets
44
- alias_method :pat_sets, :pattern_sets
45
-
46
- def dc_specs
47
- @dc_specs ||= DCSpecs.new(parser: self)
48
- end
49
-
50
- def ac_specs
51
- @ac_specs ||= ACSpecs.new(parser: self)
52
- end
53
-
54
- def inspect
55
- "<Parsed Program: Flows: #{flows.size}>"
56
- end
57
-
58
- # Parse a file, array of files, or a directory.
59
- #
60
- # This can be called multiple times to add new files to the
61
- # program model.
62
- def parse(file)
63
- Origen.log.info ''
64
- Origen.log.info "Parsing Ultraflex test program from: #{file}"
65
- Origen.log.info ''
66
- reset
67
- # Note use of local file handler here, this should be how it is
68
- # done globally, otherwise we can run into hard to debug problems
69
- # due to state/reference dir changes in the single Origen.file_handler
70
- Origen::FileHandler.new.resolve_files(file) do |f|
71
- parse_file(f)
72
- end
73
- Origen.log.info ''
74
- self
75
- end
76
-
77
- def parse_file(file)
78
- line = File.readlines(file).first
79
- begin
80
- if line =~ /Flow Table/
81
- flows.import(file)
82
- elsif line =~ /Instances/
83
- test_instances.import(file)
84
- elsif line =~ /Pattern Sets/
85
- patsets.import(file)
86
- elsif line =~ /DC Spec/
87
- dc_specs.import(file)
88
- else
89
- puts "Skipped (un-supported file type): #{file}"
90
- end
91
- rescue Exception => e
92
- if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
93
- puts "Skipped (not ASCII): #{file}"
94
- else
95
- puts e.message
96
- puts e.backtrace
97
- exit 1
98
- end
99
- end
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,11 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- class Parser
5
- class ACSpec
6
- attr_accessor :collection
7
- end
8
- end
9
- end
10
- end
11
- end
File without changes
@@ -1,36 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- class Parser
5
- class DCSpec
6
- attr_accessor :parser
7
- attr_accessor :name, :categories
8
- alias_method :symbol, :name
9
-
10
- def initialize(name, categories, options = {})
11
- @parser = options[:parser]
12
- @name = name
13
- @categories = categories
14
- @values = {}
15
- end
16
-
17
- def add_values(components)
18
- @categories.each_with_index do |category, i|
19
- @values[category] ||= {}
20
- @values[category]['Typ'] ||= components[5 + (i * 3) + 0]
21
- @values[category]['Min'] ||= components[5 + (i * 3) + 1]
22
- @values[category]['Max'] ||= components[5 + (i * 3) + 2]
23
- end
24
- end
25
-
26
- def lookup(category, selector)
27
- v = @values[category]
28
- if v
29
- v[selector]
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,50 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- class Parser
5
- class DCSpecs < Origen::Tester::Parser::SearchableHash
6
- attr_accessor :parser
7
-
8
- def initialize(options = {})
9
- @parser = options[:parser]
10
- end
11
-
12
- def import(file)
13
- @categories = []
14
- File.readlines(file).each do |line|
15
- unless line.strip.empty?
16
- components = line.split("\t")
17
- if components[3] == 'Selector'
18
- extract_categories(components)
19
- else
20
- unless components[1] == 'DC Specs' || components[1] == 'Symbol'
21
- extract_spec(components)
22
- end
23
- end
24
- end
25
- end
26
- end
27
-
28
- def inspect
29
- "<DCSpecs: #{size}>"
30
- end
31
-
32
- def extract_categories(components)
33
- components.each_with_index do |val, i|
34
- if i > 4
35
- @categories << val unless val.strip.empty?
36
- end
37
- end
38
- @categories.uniq!
39
- end
40
-
41
- def extract_spec(components)
42
- name = components[1]
43
- self[name] ||= DCSpec.new(name, @categories, parser: parser)
44
- self[name].add_values(components)
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,342 +0,0 @@
1
- module Origen
2
- module Tester
3
- class Ultraflex
4
- class Parser
5
- # Extracts embedded test and flow descriptions (comments) from test
6
- # program source files
7
- class Descriptions
8
- require 'fileutils'
9
-
10
- attr_accessor :source_directories, :template_directories, :parser
11
-
12
- SCRATCH_DIR = "#{Origen.root}/.j750_scratch"
13
-
14
- # All descriptions are stored in this lookup table
15
- def lookup
16
- return @lookup if @lookup
17
- # Use the one from the interface if present, program generation will
18
- # automatically push descriptions in here
19
- if Origen.interface_present?
20
- @lookup = Origen.interface.descriptions
21
- else
22
- @lookup = Origen::Tester::Parser::DescriptionLookup.new
23
- end
24
- end
25
-
26
- def initialize(options = {})
27
- @parser = options[:parser]
28
- FileUtils.rm_rf(SCRATCH_DIR) if File.exist?(SCRATCH_DIR)
29
- parse_program
30
- true
31
- end
32
-
33
- # Returns the description for the given flow
34
- def flow_summary(options = {})
35
- lookup.for_flow(options[:file])
36
- end
37
-
38
- # Returns the description of the given test from the test
39
- # instance sheet declaration
40
- def test_instance(options = {})
41
- lookup.for_test_definition(options[:name])
42
- end
43
-
44
- # Returns the description of the given test from the test
45
- # flow
46
- def flow_line(options = {})
47
- lookup.for_test_usage(options[:name], options[:flow])
48
- end
49
-
50
- def parse_program
51
- Origen.file_handler.preserve_state do
52
- generate_program_files
53
- # Comments must be extracted manually for any compiled files, for
54
- # generated files the comments will already be in the lookup
55
- extract_flow_summaries
56
- extract_test_instance_descriptions
57
- extract_flow_line_descriptions
58
- end
59
- end
60
-
61
- def source_directories
62
- [@source_directories, Origen.config.test_program_source_directory].compact.flatten
63
- end
64
-
65
- def template_directories
66
- [@template_directories, Origen.config.test_program_template_directory].compact.flatten
67
- end
68
-
69
- def extract_flow_summaries
70
- Origen.file_handler.resolve_files(compiled_dir) do |file|
71
- if flow_file?(file)
72
- lookup.add_for_flow(file, parse_flow_summary(file))
73
- end
74
- end
75
- end
76
-
77
- # Parses a compiled template for marked up comments
78
- def extract_test_instance_descriptions
79
- Origen.file_handler.resolve_files(compiled_dir) do |file|
80
- if instance_file?(file)
81
- comments = []
82
- File.readlines(file).each do |line|
83
- if line =~ /^<comment>(.*)/
84
- comments << Regexp.last_match[1].gsub("\r", '')
85
- else
86
- fields = line.split("\t")
87
- unless ['Test Instances', '', 'Test Name'].include? fields[1]
88
- lookup.add_for_test_definition(fields[1], comments)
89
- end
90
- comments = []
91
- end
92
- end
93
- end
94
- end
95
- end
96
-
97
- def extract_flow_line_descriptions
98
- Origen.file_handler.resolve_files(compiled_dir) do |file|
99
- if flow_file?(file)
100
- f = file.basename('.txt').to_s
101
- comments = []
102
- header_line = true
103
- File.readlines(file).each do |line|
104
- if header_line
105
- header_line = false if line =~ /^\s*Label/
106
- else
107
- if line =~ /^<comment>(.*)/
108
- comments << Regexp.last_match[1].gsub("\r", '')
109
- else
110
- t = FlowLine.extract_test(line)
111
- if t
112
- lookup.add_for_test_usage(t, file, comments)
113
- end
114
- comments = []
115
- end
116
- end
117
- end
118
- end
119
- end
120
- end
121
-
122
- def generate_program_files
123
- a = generate_program
124
- b = compile_program
125
- unless a || b
126
- fail 'No source or template files declared from which to parse descriptions!'
127
- end
128
- end
129
-
130
- # Parses the given flow file for summary text and returns it, summary
131
- # text must be the very first thing in the file.
132
- # Returns an array of strings each representing a line of text.
133
- def parse_flow_summary(file)
134
- desc = []
135
- File.readlines(file).each do |line|
136
- if line =~ /%?\s*<comment>(.*)/
137
- desc << Regexp.last_match[1].gsub("\r", '')
138
- else
139
- break
140
- end
141
- end
142
- desc
143
- end
144
-
145
- # Generate a scratch version of the program for parsing
146
- def generate_program
147
- if source_directories.size > 0
148
- unless @program_generated
149
- Origen.log.info ''
150
- Origen.log.info 'Extracting embedded comments:'
151
- Origen.log.info ''
152
- copy_source_files_to_scratch
153
- markup_source_file_comments
154
- # Compile the flow file, with Ruby comments now preserved and marked up
155
- desc = Origen.app.runner.generate(program: true, patterns: ungenerated_dir, output: generated_dir,
156
- check_for_changes: false, collect_stats: false, quiet: true,
157
- collect_descriptions: true)
158
- Origen.log.info ''
159
- end
160
- @program_generated = true
161
- else
162
- false
163
- end
164
- end
165
-
166
- # Compile a scratch version of the program for parsing
167
- def compile_program
168
- if template_directories.size > 0
169
- unless @program_compiled
170
- Origen.log.info ''
171
- Origen.log.info 'Extracting embedded comments:'
172
- Origen.log.info ''
173
- copy_templates_to_scratch
174
- markup_template_comments
175
- # Compile the flow file, with Ruby comments now preserved and marked up
176
- Origen.app.runner.generate(compile: true, patterns: uncompiled_dir, output: compiled_dir,
177
- check_for_changes: false, collect_stats: false, quiet: true)
178
- Origen.log.info ''
179
- end
180
- @program_compiled = true
181
- else
182
- false
183
- end
184
- end
185
-
186
- # Copy all flow and instance template files to the scratch dir
187
- def copy_templates_to_scratch
188
- uncompiled_dir(true)
189
- template_directories.each do |dir|
190
- Origen.file_handler.resolve_files(dir) do |file|
191
- subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
192
- cpydir = "#{uncompiled_dir}/#{subdir}"
193
- FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
194
- FileUtils.copy(file, cpydir) if flow_or_instance_file?(file)
195
- end
196
- end
197
- `chmod -R 777 #{uncompiled_dir}/*` unless Dir["#{uncompiled_dir}/*"].empty?
198
- end
199
-
200
- # Copy all flow and instance source files to the scratch dir
201
- def copy_source_files_to_scratch
202
- source_directories.each do |dir|
203
- Origen.file_handler.resolve_files(dir) do |file|
204
- subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
205
- cpydir = "#{ungenerated_dir}/#{subdir}"
206
- FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
207
- FileUtils.copy(file, cpydir)
208
- end
209
- end
210
- end
211
-
212
- def uncompiled_dir(force_make = false)
213
- @uncompiled_dir ||= "#{SCRATCH_DIR}/uncompiled"
214
- if force_make
215
- FileUtils.rm_rf(@uncompiled_dir) if File.exist?(@uncompiled_dir)
216
- @uncompiled_dir_created = false
217
- end
218
- unless @uncompiled_dir_created
219
- FileUtils.mkdir_p(@uncompiled_dir) unless File.exist?(@uncompiled_dir)
220
- @uncompiled_dir_created = true
221
- end
222
- @uncompiled_dir
223
- end
224
-
225
- def ungenerated_dir
226
- @ungenerated_dir ||= "#{SCRATCH_DIR}/ungenerated"
227
- unless @ungenerated_dir_created
228
- FileUtils.mkdir_p(@ungenerated_dir) unless File.exist?(@ungenerated_dir)
229
- @ungenerated_dir_created = true
230
- end
231
- @ungenerated_dir
232
- end
233
-
234
- def compiled_dir
235
- @compiled_dir ||= "#{SCRATCH_DIR}/compiled"
236
- unless @compiled_dir_created
237
- FileUtils.mkdir_p(@compiled_dir) unless File.exist?(@compiled_dir)
238
- @compiled_dir_created = true
239
- end
240
- @compiled_dir
241
- end
242
-
243
- def generated_dir
244
- @generated_dir ||= "#{SCRATCH_DIR}/generated"
245
- unless @generated_dir_created
246
- FileUtils.mkdir_p(@generated_dir) unless File.exist?(@generated_dir)
247
- @generated_dir_created = true
248
- end
249
- @generated_dir
250
- end
251
-
252
- # Returns true if the given file looks like a Ultraflex flow file, works for
253
- # templates to
254
- def flow_or_instance_file?(file, options = {})
255
- options = { flow: true,
256
- instance: true
257
- }.merge(options)
258
- if options[:flow] && options[:instance]
259
- match = 'Flow|Instances'
260
- elsif options[:flow]
261
- match = 'Flow'
262
- else
263
- match = 'Instances'
264
- end
265
- # Not sure the best way to determine the file type of a partial, just
266
- # return true for now to play it safe
267
- return true if file.basename.to_s =~ /^_/
268
- File.readlines(file).each do |line|
269
- begin
270
- unless line =~ /^%/ || line =~ /^\s*<comment>/
271
- return !!(line =~ /#{match}/)
272
- end
273
- rescue Exception => e
274
- if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
275
- return false
276
- else
277
- puts e.message
278
- puts e.backtrace
279
- exit 1
280
- end
281
- end
282
- end
283
- end
284
-
285
- def flow_file?(file)
286
- flow_or_instance_file?(file, instance: false)
287
- end
288
-
289
- def instance_file?(file)
290
- flow_or_instance_file?(file, flow: false)
291
- end
292
-
293
- # Substitute Ruby line comments so they are preserved by compilation
294
- def markup_template_comments
295
- Origen.file_handler.resolve_files(uncompiled_dir) do |file|
296
- lines = File.readlines(file)
297
- File.open(file, 'w') do |f|
298
- lines.each do |line|
299
- if line =~ /^%\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
300
- comment = Regexp.last_match[1]
301
- # If comment starts with a '#-' it should be removed by compilation
302
- if line =~ /^%\s*#-.*/
303
- f.write line
304
- # Otherwise preserve it
305
- else
306
- f.write "<comment>#{comment}\n"
307
- end
308
- else
309
- f.write line
310
- end
311
- end
312
- end
313
- end
314
- end
315
-
316
- # Substitute Ruby line comments so they are preserved by generation
317
- def markup_source_file_comments
318
- Origen.file_handler.resolve_files(ungenerated_dir) do |file|
319
- lines = File.readlines(file)
320
- File.open(file, 'w') do |f|
321
- lines.each do |line|
322
- if line =~ /^\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
323
- comment = Regexp.last_match[1]
324
- # If comment starts with a '#-' it should be removed by generation
325
- if line =~ /^\s*#-.*/
326
- f.write line
327
- # Otherwise preserve it
328
- else
329
- f.write "Origen.interface.comment '#{comment}'\n"
330
- end
331
- else
332
- f.write line
333
- end
334
- end
335
- end
336
- end
337
- end
338
- end
339
- end
340
- end
341
- end
342
- end