origen 0.2.6 → 0.3.0

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.
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