origen 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/bin/ctags +0 -0
- data/bin/origen +165 -1
- data/bin/rgen +2 -0
- data/config/application.rb +141 -0
- data/config/commands.rb +72 -0
- data/config/development.rb +7 -0
- data/config/environment.rb +0 -0
- data/config/rgen.policy +7 -0
- data/config/rubocop/easy.yml +620 -0
- data/config/rubocop/easy_disabled.yml +271 -0
- data/config/rubocop/easy_enabled.yml +731 -0
- data/config/rubocop/strict.yml +620 -0
- data/config/rubocop/strict_disabled.yml +247 -0
- data/config/rubocop/strict_enabled.yml +755 -0
- data/config/users.rb +20 -0
- data/config/version.rb +1 -1
- data/helpers/url.rb +68 -0
- data/lib/c99/doc_interface.rb +56 -0
- data/lib/c99/j750_interface.rb +85 -0
- data/lib/c99/nvm.rb +89 -0
- data/lib/c99/target/mock2.rb +1 -0
- data/lib/c99/target/subdir/mock3.rb +1 -0
- data/lib/option_parser/optparse.rb +12 -0
- data/lib/origen/acronyms.rb +60 -0
- data/lib/origen/application/command_dispatcher.rb +12 -0
- data/lib/origen/application/configuration.rb +206 -0
- data/lib/origen/application/configuration_manager.rb +78 -0
- data/lib/origen/application/deployer.rb +367 -0
- data/lib/origen/application/environment.rb +186 -0
- data/lib/origen/application/lsf.rb +145 -0
- data/lib/origen/application/lsf_manager.rb +657 -0
- data/lib/origen/application/plugins_manager.rb +280 -0
- data/lib/origen/application/release.rb +359 -0
- data/lib/origen/application/runner.rb +246 -0
- data/lib/origen/application/statistics.rb +191 -0
- data/lib/origen/application/target.rb +374 -0
- data/lib/origen/application/version_tracker.rb +59 -0
- data/lib/origen/application/workspace_manager.rb +151 -0
- data/lib/origen/application.rb +746 -0
- data/lib/origen/bugs/bug.rb +36 -0
- data/lib/origen/bugs.rb +45 -0
- data/lib/origen/callbacks.rb +35 -0
- data/lib/origen/chip_mode.rb +118 -0
- data/lib/origen/chip_package.rb +461 -0
- data/lib/origen/client.rb +87 -0
- data/lib/origen/code_generators/actions.rb +258 -0
- data/lib/origen/code_generators/base.rb +57 -0
- data/lib/origen/code_generators/bundler.rb +17 -0
- data/lib/origen/code_generators/gem_setup.rb +49 -0
- data/lib/origen/code_generators/rake.rb +13 -0
- data/lib/origen/code_generators/rspec.rb +12 -0
- data/lib/origen/code_generators/semver.rb +39 -0
- data/lib/origen/code_generators/timever.rb +37 -0
- data/lib/origen/code_generators.rb +111 -0
- data/lib/origen/commands/add.rb +12 -0
- data/lib/origen/commands/compile.rb +62 -0
- data/lib/origen/commands/ctags.rb +9 -0
- data/lib/origen/commands/dispatch.rb +22 -0
- data/lib/origen/commands/environment.rb +11 -0
- data/lib/origen/commands/fetch.rb +63 -0
- data/lib/origen/commands/generate.rb +130 -0
- data/lib/origen/commands/interactive.rb +73 -0
- data/lib/origen/commands/lint.rb +82 -0
- data/lib/origen/commands/lsf.rb +93 -0
- data/lib/origen/commands/merge.rb +55 -0
- data/lib/origen/commands/modifications.rb +12 -0
- data/lib/origen/commands/new.rb +113 -0
- data/lib/origen/commands/plugin.rb +105 -0
- data/lib/origen/commands/program.rb +70 -0
- data/lib/origen/commands/rc.rb +442 -0
- data/lib/origen/commands/save.rb +56 -0
- data/lib/origen/commands/target.rb +27 -0
- data/lib/origen/commands/time.rb +127 -0
- data/lib/origen/commands/version.rb +17 -0
- data/lib/origen/commands/web.rb +221 -0
- data/lib/origen/commands.rb +272 -0
- data/lib/origen/commands_global.rb +76 -0
- data/lib/origen/controller.rb +94 -0
- data/lib/origen/core_ext/array.rb +23 -0
- data/lib/origen/core_ext/bignum.rb +36 -0
- data/lib/origen/core_ext/enumerable.rb +76 -0
- data/lib/origen/core_ext/fixnum.rb +46 -0
- data/lib/origen/core_ext/hash.rb +52 -0
- data/lib/origen/core_ext/module.rb +14 -0
- data/lib/origen/core_ext/numeric.rb +126 -0
- data/lib/origen/core_ext/object.rb +13 -0
- data/lib/origen/core_ext/range.rb +7 -0
- data/lib/origen/core_ext/string.rb +124 -0
- data/lib/origen/core_ext.rb +10 -0
- data/lib/origen/database/key_value_store.rb +111 -0
- data/lib/origen/database/key_value_stores.rb +108 -0
- data/lib/origen/database.rb +6 -0
- data/lib/origen/encodings.rb +102 -0
- data/lib/origen/features/feature.rb +22 -0
- data/lib/origen/features.rb +104 -0
- data/lib/origen/file_handler.rb +429 -0
- data/lib/origen/generator/comparator.rb +56 -0
- data/lib/origen/generator/compiler.rb +277 -0
- data/lib/origen/generator/flow.rb +49 -0
- data/lib/origen/generator/job.rb +131 -0
- data/lib/origen/generator/pattern.rb +356 -0
- data/lib/origen/generator/pattern_finder.rb +155 -0
- data/lib/origen/generator/pattern_iterator.rb +55 -0
- data/lib/origen/generator/renderer.rb +113 -0
- data/lib/origen/generator/resources.rb +40 -0
- data/lib/origen/generator/stage.rb +89 -0
- data/lib/origen/generator.rb +85 -0
- data/lib/origen/global_methods.rb +205 -0
- data/lib/origen/import_manager.rb +596 -0
- data/lib/origen/location/base.rb +116 -0
- data/lib/origen/location/map.rb +83 -0
- data/lib/origen/location.rb +6 -0
- data/lib/origen/log.rb +217 -0
- data/lib/origen/logger_methods.rb +56 -0
- data/lib/origen/mode.rb +61 -0
- data/lib/origen/model.rb +267 -0
- data/lib/origen/model_initializer.rb +45 -0
- data/lib/origen/nvm/block_array.rb +72 -0
- data/lib/origen/nvm.rb +6 -0
- data/lib/origen/parameters/live.rb +22 -0
- data/lib/origen/parameters/missing.rb +28 -0
- data/lib/origen/parameters/set.rb +144 -0
- data/lib/origen/parameters.rb +107 -0
- data/lib/origen/pdm.rb +218 -0
- data/lib/origen/pins/function_proxy.rb +36 -0
- data/lib/origen/pins/ground_pin.rb +6 -0
- data/lib/origen/pins/pin.rb +860 -0
- data/lib/origen/pins/pin_bank.rb +349 -0
- data/lib/origen/pins/pin_clock.rb +124 -0
- data/lib/origen/pins/pin_collection.rb +492 -0
- data/lib/origen/pins/pin_common.rb +206 -0
- data/lib/origen/pins/port.rb +268 -0
- data/lib/origen/pins/power_pin.rb +30 -0
- data/lib/origen/pins.rb +696 -0
- data/lib/origen/registers/bit.rb +562 -0
- data/lib/origen/registers/bit_collection.rb +787 -0
- data/lib/origen/registers/container.rb +288 -0
- data/lib/origen/registers/domain.rb +16 -0
- data/lib/origen/registers/reg.rb +1406 -0
- data/lib/origen/registers/reg_collection.rb +24 -0
- data/lib/origen/registers.rb +652 -0
- data/lib/origen/regression_manager.rb +251 -0
- data/lib/origen/remote_manager.rb +340 -0
- data/lib/origen/revision_control/base.rb +257 -0
- data/lib/origen/revision_control/design_sync.rb +276 -0
- data/lib/origen/revision_control/git.rb +243 -0
- data/lib/origen/revision_control/subversion.rb +6 -0
- data/lib/origen/revision_control.rb +44 -0
- data/lib/origen/ruby_version_check.rb +131 -0
- data/lib/origen/site_config.rb +61 -0
- data/lib/origen/specs/checkers.rb +103 -0
- data/lib/origen/specs/creation_info.rb +17 -0
- data/lib/origen/specs/doc_resource.rb +91 -0
- data/lib/origen/specs/exhibit.rb +17 -0
- data/lib/origen/specs/mode_select.rb +16 -0
- data/lib/origen/specs/note.rb +17 -0
- data/lib/origen/specs/override.rb +21 -0
- data/lib/origen/specs/power_supply.rb +13 -0
- data/lib/origen/specs/spec.rb +226 -0
- data/lib/origen/specs/version_history.rb +14 -0
- data/lib/origen/specs.rb +552 -0
- data/lib/origen/sub_blocks.rb +298 -0
- data/lib/origen/tester/api.rb +277 -0
- data/lib/origen/tester/bdm/bdm.rb +25 -0
- data/lib/origen/tester/command_based_tester.rb +46 -0
- data/lib/origen/tester/doc/doc.rb +226 -0
- data/lib/origen/tester/doc/generator/flow.rb +71 -0
- data/lib/origen/tester/doc/generator/flow_line.rb +203 -0
- data/lib/origen/tester/doc/generator/test.rb +68 -0
- data/lib/origen/tester/doc/generator/test_group.rb +66 -0
- data/lib/origen/tester/doc/generator/tests.rb +47 -0
- data/lib/origen/tester/doc/generator.rb +126 -0
- data/lib/origen/tester/doc/model.rb +162 -0
- data/lib/origen/tester/generator/flow_control_api.rb +606 -0
- data/lib/origen/tester/generator/identity_map.rb +25 -0
- data/lib/origen/tester/generator/placeholder.rb +13 -0
- data/lib/origen/tester/generator/test_numberer.rb +25 -0
- data/lib/origen/tester/generator.rb +271 -0
- data/lib/origen/tester/interface.rb +154 -0
- data/lib/origen/tester/j750/files.rb +45 -0
- data/lib/origen/tester/j750/generator/flow.rb +123 -0
- data/lib/origen/tester/j750/generator/flow_line.rb +288 -0
- data/lib/origen/tester/j750/generator/patgroup.rb +111 -0
- data/lib/origen/tester/j750/generator/patgroups.rb +41 -0
- data/lib/origen/tester/j750/generator/patset.rb +111 -0
- data/lib/origen/tester/j750/generator/patsets.rb +41 -0
- data/lib/origen/tester/j750/generator/templates/flow.txt.erb +9 -0
- data/lib/origen/tester/j750/generator/templates/instances.txt.erb +16 -0
- data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +8 -0
- data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +10 -0
- data/lib/origen/tester/j750/generator/test_instance.rb +846 -0
- data/lib/origen/tester/j750/generator/test_instance_group.rb +60 -0
- data/lib/origen/tester/j750/generator/test_instances.rb +182 -0
- data/lib/origen/tester/j750/generator.rb +203 -0
- data/lib/origen/tester/j750/j750.rb +845 -0
- data/lib/origen/tester/j750/j750_hpt.rb +35 -0
- data/lib/origen/tester/j750/parser/ac_spec.rb +11 -0
- data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
- data/lib/origen/tester/j750/parser/dc_spec.rb +36 -0
- data/lib/origen/tester/j750/parser/dc_specs.rb +50 -0
- data/lib/origen/tester/j750/parser/descriptions.rb +340 -0
- data/lib/origen/tester/j750/parser/flow.rb +111 -0
- data/lib/origen/tester/j750/parser/flow_line.rb +207 -0
- data/lib/origen/tester/j750/parser/flows.rb +23 -0
- data/lib/origen/tester/j750/parser/pattern_set.rb +94 -0
- data/lib/origen/tester/j750/parser/pattern_sets.rb +33 -0
- data/lib/origen/tester/j750/parser/test_instance.rb +322 -0
- data/lib/origen/tester/j750/parser/test_instances.rb +26 -0
- data/lib/origen/tester/j750/parser/timeset.rb +15 -0
- data/lib/origen/tester/j750/parser/timesets.rb +0 -0
- data/lib/origen/tester/j750/parser.rb +104 -0
- data/lib/origen/tester/jlink/jlink.rb +33 -0
- data/lib/origen/tester/parser/description_lookup.rb +64 -0
- data/lib/origen/tester/parser/searchable_array.rb +32 -0
- data/lib/origen/tester/parser/searchable_hash.rb +32 -0
- data/lib/origen/tester/parser.rb +24 -0
- data/lib/origen/tester/time.rb +338 -0
- data/lib/origen/tester/timing.rb +253 -0
- data/lib/origen/tester/ultraflex/files.rb +45 -0
- data/lib/origen/tester/ultraflex/generator/flow.rb +119 -0
- data/lib/origen/tester/ultraflex/generator/flow_line.rb +269 -0
- data/lib/origen/tester/ultraflex/generator/patgroup.rb +111 -0
- data/lib/origen/tester/ultraflex/generator/patgroups.rb +41 -0
- data/lib/origen/tester/ultraflex/generator/patset.rb +111 -0
- data/lib/origen/tester/ultraflex/generator/patsets.rb +41 -0
- data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +9 -0
- data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +16 -0
- data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +8 -0
- data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +10 -0
- data/lib/origen/tester/ultraflex/generator/test_instance.rb +622 -0
- data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +60 -0
- data/lib/origen/tester/ultraflex/generator/test_instances.rb +174 -0
- data/lib/origen/tester/ultraflex/generator.rb +200 -0
- data/lib/origen/tester/ultraflex/parser/ac_spec.rb +11 -0
- data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
- data/lib/origen/tester/ultraflex/parser/dc_spec.rb +36 -0
- data/lib/origen/tester/ultraflex/parser/dc_specs.rb +50 -0
- data/lib/origen/tester/ultraflex/parser/descriptions.rb +342 -0
- data/lib/origen/tester/ultraflex/parser/flow.rb +111 -0
- data/lib/origen/tester/ultraflex/parser/flow_line.rb +207 -0
- data/lib/origen/tester/ultraflex/parser/flows.rb +23 -0
- data/lib/origen/tester/ultraflex/parser/pattern_set.rb +94 -0
- data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +33 -0
- data/lib/origen/tester/ultraflex/parser/test_instance.rb +262 -0
- data/lib/origen/tester/ultraflex/parser/test_instances.rb +26 -0
- data/lib/origen/tester/ultraflex/parser/timeset.rb +15 -0
- data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
- data/lib/origen/tester/ultraflex/parser.rb +104 -0
- data/lib/origen/tester/ultraflex/ultraflex.rb +759 -0
- data/lib/origen/tester/v93k/generator/flow.rb +63 -0
- data/lib/origen/tester/v93k/generator/flow_node/print.rb +10 -0
- data/lib/origen/tester/v93k/generator/flow_node.rb +17 -0
- data/lib/origen/tester/v93k/generator/pattern.rb +16 -0
- data/lib/origen/tester/v93k/generator/pattern_master.rb +54 -0
- data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +6 -0
- data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +11 -0
- data/lib/origen/tester/v93k/generator/templates/template.flow.erb +121 -0
- data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +9 -0
- data/lib/origen/tester/v93k/generator/test_function.rb +103 -0
- data/lib/origen/tester/v93k/generator/test_functions.rb +79 -0
- data/lib/origen/tester/v93k/generator/test_method.rb +46 -0
- data/lib/origen/tester/v93k/generator/test_methods.rb +75 -0
- data/lib/origen/tester/v93k/generator/test_suite.rb +54 -0
- data/lib/origen/tester/v93k/generator/test_suites.rb +65 -0
- data/lib/origen/tester/v93k/generator.rb +80 -0
- data/lib/origen/tester/v93k/v93k.rb +420 -0
- data/lib/origen/tester/vector.rb +86 -0
- data/lib/origen/tester/vector_generator.rb +633 -0
- data/lib/origen/tester/vector_pipeline.rb +150 -0
- data/lib/origen/tester.rb +56 -0
- data/lib/origen/top_level.rb +134 -0
- data/lib/origen/users/ldap.rb +65 -0
- data/lib/origen/users/user.rb +149 -0
- data/lib/origen/users.rb +30 -0
- data/lib/origen/utility/block_args.rb +93 -0
- data/lib/origen/utility/csv_data.rb +110 -0
- data/lib/origen/utility/design_sync.rb +494 -0
- data/lib/origen/utility/diff.rb +158 -0
- data/lib/origen/utility/input_capture.rb +121 -0
- data/lib/origen/utility/mailer.rb +143 -0
- data/lib/origen/utility/s_record.rb +205 -0
- data/lib/origen/utility/time_and_date.rb +30 -0
- data/lib/origen/utility.rb +12 -0
- data/lib/origen/version_checker.rb +117 -0
- data/lib/origen/version_string.rb +356 -0
- data/lib/origen.rb +648 -0
- data/lib/tasks/gem.rake +27 -22
- data/origen_site_config.yml +36 -0
- data/source_setup +17 -0
- data/spec/format/rgen_formatter.rb +14 -0
- data/templates/api_doc/README.txt.erb +24 -0
- data/templates/code_generators/gemfile_app.rb +4 -0
- data/templates/code_generators/gemfile_plugin.rb +6 -0
- data/templates/code_generators/gemspec.rb +33 -0
- data/templates/code_generators/rakefile.rb +10 -0
- data/templates/code_generators/spec_helper.rb +49 -0
- data/templates/code_generators/version.rb +8 -0
- data/templates/code_generators/version_time.rb +3 -0
- data/templates/git/gitignore.erb +33 -0
- data/templates/j750/_vt_flow.txt.erb +8 -0
- data/templates/j750/_vt_instances.txt.erb +4 -0
- data/templates/j750/program_sheet.txt.erb +9 -0
- data/templates/nanoc/Rules +74 -0
- data/templates/nanoc/config.yaml +77 -0
- data/templates/nanoc/content/favicon.ico +0 -0
- data/templates/nanoc/layouts/bootstrap.html.erb +63 -0
- data/templates/nanoc/layouts/bootstrap3.html.erb +71 -0
- data/templates/nanoc/layouts/freescale.html.erb +79 -0
- data/templates/nanoc/lib/bootstrap_filter.rb +49 -0
- data/templates/nanoc/lib/codeblocks_filter.rb +41 -0
- data/templates/nanoc/lib/default.rb +2 -0
- data/templates/nanoc/lib/gzip_filter.rb +16 -0
- data/templates/nanoc/lib/haml_code_filter.rb +41 -0
- data/templates/nanoc/lib/helpers.rb +1 -0
- data/templates/nanoc/lib/search_filter.rb +62 -0
- data/templates/nanoc_dynamic/content/search.js.erb +92 -0
- data/templates/shared/web/_logo.html +10 -0
- data/templates/test/_inline_sub.txt.erb +2 -0
- data/templates/test/environment.txt.erb +1 -0
- data/templates/test/inline.txt.erb +11 -0
- data/templates/test/inspections.txt.erb +19 -0
- data/templates/test/set1/_sub1.txt.erb +12 -0
- data/templates/test/set1/_sub4.txt.erb +1 -0
- data/templates/test/set1/_sub5.txt.erb +1 -0
- data/templates/test/set1/main.txt.erb +53 -0
- data/templates/test/set1/sub_dir/_sub2.txt.erb +20 -0
- data/templates/test/set1/sub_dir/_sub3.txt.erb +12 -0
- data/templates/test/set1/sub_dir/main2.txt.erb +4 -0
- data/templates/test/set2/template_with_no_erb_1.txt +9 -0
- data/templates/test/set2/template_with_no_erb_2.txt +9 -0
- data/templates/test/set3/_layout.html.erb +4 -0
- data/templates/test/set3/content.html.erb +6 -0
- data/templates/time/filter.rb.erb +15 -0
- data/templates/time/rules.rb.erb +45 -0
- metadata +639 -5
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
module Origen
|
|
2
|
+
class Generator
|
|
3
|
+
class Pattern
|
|
4
|
+
include Comparator
|
|
5
|
+
|
|
6
|
+
class DummyIterator
|
|
7
|
+
def invoke(*_args)
|
|
8
|
+
yield
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def enabled?(_options)
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def log
|
|
17
|
+
Origen.log
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the options passed to the current create block
|
|
21
|
+
def create_options
|
|
22
|
+
@create_options || {}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The recommended way to create a pattern is to wrap it within a Pattern.create
|
|
26
|
+
# block, however occasionally the need may arise to manually open and close
|
|
27
|
+
# a pattern, this method can be used in that case in association with the close
|
|
28
|
+
# method.
|
|
29
|
+
#
|
|
30
|
+
# Pattern iterators are not supported when creating a pattern in this way.
|
|
31
|
+
def open(options = {})
|
|
32
|
+
if block_given?
|
|
33
|
+
create(options) do |*args|
|
|
34
|
+
yield(*args)
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
job.output_file_body = options.delete(:name).to_s if options[:name]
|
|
38
|
+
|
|
39
|
+
# Refresh the target to start all settings from scratch each time
|
|
40
|
+
# This is an easy way to reset all registered values
|
|
41
|
+
Origen.app.reload_target!(skip_first_time: true)
|
|
42
|
+
|
|
43
|
+
# Final call back to the project to allow it to make any pattern name specific
|
|
44
|
+
# configuration changes
|
|
45
|
+
Origen.app.listeners_for(:before_pattern).each do |listener|
|
|
46
|
+
listener.before_pattern(job.output_pattern_filename)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Allow custom pattern postfix
|
|
50
|
+
unless options[:pat_postfix].to_s.empty?
|
|
51
|
+
job.output_pattern_filename = job.output_pattern_filename.sub(job.output_postfix + job.output_extension, "_#{options[:pat_postfix]}" + job.output_postfix + job.output_extension)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
pattern_open(options)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def close(options = {})
|
|
59
|
+
pattern_close(options)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def create(options = {})
|
|
63
|
+
@create_options = options
|
|
64
|
+
unless Origen.tester
|
|
65
|
+
puts 'The current target has not instantiated a tester and pattern generation cannot run.'
|
|
66
|
+
puts 'Add something like this to your target file:'
|
|
67
|
+
puts ''
|
|
68
|
+
puts ' $tester = Origen::Tester::J750.new'
|
|
69
|
+
puts ''
|
|
70
|
+
exit 1
|
|
71
|
+
end
|
|
72
|
+
Origen.tester.generating = :pattern
|
|
73
|
+
|
|
74
|
+
job.output_file_body = options.delete(:name).to_s if options[:name]
|
|
75
|
+
|
|
76
|
+
# Order the iterators by the order that their enable keys appear in the options, pad
|
|
77
|
+
# any missing iterators with a dummy function...
|
|
78
|
+
iterators = options.map do |key, _val|
|
|
79
|
+
Origen.app.pattern_iterators.find { |iterator| iterator.key == key }
|
|
80
|
+
end.compact
|
|
81
|
+
iterators << DummyIterator.new while iterators.size < 10
|
|
82
|
+
|
|
83
|
+
args = []
|
|
84
|
+
|
|
85
|
+
# Couldn't get this to work fully dynamically, so hard-coded for 10 custom
|
|
86
|
+
# iterators for now, should be plenty for any application in the meantime.
|
|
87
|
+
# Should revisit this when time allows and remove this limitation by changing
|
|
88
|
+
# this to a recursive structure.
|
|
89
|
+
iterators[0].invoke(options) do |arg0|
|
|
90
|
+
args[0] = arg0
|
|
91
|
+
iterators[1].invoke(options) do |arg1|
|
|
92
|
+
args[1] = arg1
|
|
93
|
+
iterators[2].invoke(options) do |arg2|
|
|
94
|
+
args[2] = arg2
|
|
95
|
+
iterators[3].invoke(options) do |arg3|
|
|
96
|
+
args[3] = arg3
|
|
97
|
+
iterators[4].invoke(options) do |arg4|
|
|
98
|
+
args[4] = arg4
|
|
99
|
+
iterators[5].invoke(options) do |arg5|
|
|
100
|
+
args[5] = arg5
|
|
101
|
+
iterators[6].invoke(options) do |arg6|
|
|
102
|
+
args[6] = arg6
|
|
103
|
+
iterators[7].invoke(options) do |arg7|
|
|
104
|
+
args[7] = arg7
|
|
105
|
+
iterators[8].invoke(options) do |arg8|
|
|
106
|
+
args[8] = arg8
|
|
107
|
+
iterators[9].invoke(options) do |arg9|
|
|
108
|
+
args[9] = arg9
|
|
109
|
+
# Refresh the target to start all settings from scratch each time
|
|
110
|
+
# This is an easy way to reset all registered values
|
|
111
|
+
Origen.app.reload_target!(skip_first_time: true)
|
|
112
|
+
|
|
113
|
+
# Final call back to the project to allow it to make any pattern name specific
|
|
114
|
+
# configuration changes
|
|
115
|
+
Origen.app.listeners_for(:before_pattern).each do |listener|
|
|
116
|
+
listener.before_pattern(job.output_pattern_filename)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Work out the final pattern name based on the current iteration
|
|
120
|
+
job.reset_output_pattern_filename
|
|
121
|
+
iterators.each_with_index do |iterator, i|
|
|
122
|
+
if iterator.enabled?(options)
|
|
123
|
+
job.output_pattern_filename =
|
|
124
|
+
iterator.pattern_name.call(job.output_pattern_filename, args[i])
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Allow custom pattern postfix
|
|
129
|
+
unless options[:pat_postfix].to_s.empty?
|
|
130
|
+
job.output_pattern_filename = job.output_pattern_filename.sub(job.output_postfix + job.output_extension, "_#{options[:pat_postfix]}" + job.output_postfix + job.output_extension)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
pattern_wrapper(iterators, args, options) do
|
|
134
|
+
# Call iterator setups, whatever these return are passed to the pattern
|
|
135
|
+
yield_items = []
|
|
136
|
+
iterators.each_with_index do |iterator, i|
|
|
137
|
+
if iterator.enabled?(options)
|
|
138
|
+
yield_items << iterator.setup.call(args[i])
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
yield(*yield_items)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
@create_options = nil
|
|
155
|
+
end # create
|
|
156
|
+
|
|
157
|
+
# Split a running Pattern.create block into multiple patterns.
|
|
158
|
+
#
|
|
159
|
+
# The output that has been generated up until the point where
|
|
160
|
+
# this is called will be written and a new pattern will be
|
|
161
|
+
# opened to contain the remainder of the pattern content
|
|
162
|
+
# generated by the block.
|
|
163
|
+
#
|
|
164
|
+
# Each additional pattern section created by calling this method
|
|
165
|
+
# will have '_partN' appended to the original pattern name.
|
|
166
|
+
def split(options = {})
|
|
167
|
+
@split_counter ||= 0
|
|
168
|
+
@split_counter += 1
|
|
169
|
+
name = job.output_file_body
|
|
170
|
+
pattern_close(options.merge(call_shutdown_callbacks: false))
|
|
171
|
+
if name =~ /part\d+/
|
|
172
|
+
name.gsub!(/part\d+/, "part#{@split_counter}")
|
|
173
|
+
else
|
|
174
|
+
name = "#{name}_part#{@split_counter}"
|
|
175
|
+
end
|
|
176
|
+
job.output_file_body = name
|
|
177
|
+
pattern_open(options.merge(call_startup_callbacks: false))
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# This is called before each new pattern source is executed
|
|
181
|
+
#
|
|
182
|
+
# @api private
|
|
183
|
+
def reset
|
|
184
|
+
$desc = nil # Clear the description
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
|
|
189
|
+
def job
|
|
190
|
+
# The only time the job is not present should be in a test situation, e.g.
|
|
191
|
+
# when calling Pattern.create within a spec test
|
|
192
|
+
Origen.app.current_job || Origen::Generator::Job.new('anonymous', testing: true)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def stage
|
|
196
|
+
Origen.generator.stage
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def stats
|
|
200
|
+
Origen.app.stats
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Creates a header and footer for the pattern based on the current tester and any supplied options
|
|
204
|
+
def pattern_wrapper(iterators, args, options = {})
|
|
205
|
+
options[:iterators] = iterators
|
|
206
|
+
options[:args] = args
|
|
207
|
+
pattern_open(options)
|
|
208
|
+
yield # Pass control back to the pattern source
|
|
209
|
+
pattern_close(options)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def header
|
|
213
|
+
Origen.tester.pre_header if Origen.tester.doc?
|
|
214
|
+
c2 '*' * 75
|
|
215
|
+
if $desc
|
|
216
|
+
c2 'DESCRIPTION:'
|
|
217
|
+
$desc.split(/\n/).each { |line| cc line }
|
|
218
|
+
c2 '*' * 75
|
|
219
|
+
end
|
|
220
|
+
c2 'GENERATED:'
|
|
221
|
+
c2 " Time: #{Origen.launch_time}"
|
|
222
|
+
c2 " By: #{Origen.current_user.name}"
|
|
223
|
+
c2 " Command: origen g #{job.requested_pattern} -t #{Origen.target.file.basename}"
|
|
224
|
+
c2 '*' * 75
|
|
225
|
+
c2 'ENVIRONMENT:'
|
|
226
|
+
c2 ' Application'
|
|
227
|
+
c2 " Vault: #{Origen.config.vault}"
|
|
228
|
+
c2 " Version: #{Origen.app.version}"
|
|
229
|
+
c2 " Workspace: #{Origen.root}"
|
|
230
|
+
c2 ' Origen'
|
|
231
|
+
c2 " Vault: #{Origen.vault}"
|
|
232
|
+
c2 " Version: #{Origen.version}"
|
|
233
|
+
c2 " Workspace: #{Origen.top}"
|
|
234
|
+
c2 '*' * 75
|
|
235
|
+
if Origen.config.pattern_header
|
|
236
|
+
c2 '*' * 75
|
|
237
|
+
end
|
|
238
|
+
Origen.tester.close_text_block if Origen.tester.doc?
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def pattern_open(options = {})
|
|
242
|
+
options = {
|
|
243
|
+
call_startup_callbacks: true
|
|
244
|
+
}.merge(options)
|
|
245
|
+
|
|
246
|
+
iterators = options.delete(:iterators) || []
|
|
247
|
+
|
|
248
|
+
args = options.delete(:args)
|
|
249
|
+
|
|
250
|
+
if Origen.tester.generate?
|
|
251
|
+
# Now the pattern name is established delete any existing versions of this pattern
|
|
252
|
+
# to make it clearer that something has gone wrong if there is an error generating the new one
|
|
253
|
+
unless job.test?
|
|
254
|
+
File.delete(job.output_pattern) if File.exist?(job.output_pattern)
|
|
255
|
+
|
|
256
|
+
if options[:inhibit]
|
|
257
|
+
log.info "Generating... #{job.output_pattern_directory}/#{job.output_pattern_filename}".ljust(50)
|
|
258
|
+
else
|
|
259
|
+
log.info "Generating... #{job.output_pattern_directory}/#{job.output_pattern_filename}".ljust(50)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
Origen.tester.inhibit_comments = job.no_comments? if Origen.tester.respond_to?(:inhibit_comments=)
|
|
265
|
+
|
|
266
|
+
stage.reset!
|
|
267
|
+
|
|
268
|
+
stage.bank = options[:inhibit] ? :null : :body
|
|
269
|
+
|
|
270
|
+
if options.delete(:call_startup_callbacks)
|
|
271
|
+
|
|
272
|
+
skip_startup = false
|
|
273
|
+
|
|
274
|
+
# Call the iterator startup methods, if any of them return false/nil the standard
|
|
275
|
+
# startup callbacks will be skipped
|
|
276
|
+
iterators.each_with_index do |iterator, i|
|
|
277
|
+
if iterator.enabled?(options)
|
|
278
|
+
skip_startup = !iterator.startup.call(options, args[i]) || skip_startup
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
unless skip_startup || options[:skip_startup]
|
|
283
|
+
# Call startup callbacks
|
|
284
|
+
Origen.app.listeners_for(:startup).each do |listener|
|
|
285
|
+
listener.startup(options)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def pattern_close(options = {})
|
|
293
|
+
options = {
|
|
294
|
+
call_shutdown_callbacks: true
|
|
295
|
+
}.merge(options)
|
|
296
|
+
|
|
297
|
+
bank = options[:inhibit] ? :null : :body
|
|
298
|
+
stage.with_bank bank do
|
|
299
|
+
if options.delete(:call_shutdown_callbacks) && !options[:skip_shutdown]
|
|
300
|
+
# Call shutdown callbacks
|
|
301
|
+
Origen.app.listeners_for(:shutdown, top_level: :last).each do |listener|
|
|
302
|
+
listener.shutdown(options)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Now the pattern has run call the render method if the tester uses a template
|
|
307
|
+
Origen.tester.render_template
|
|
308
|
+
Origen.tester.render_body
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
bank = options[:inhibit] ? :null : :footer
|
|
312
|
+
stage.with_bank bank do
|
|
313
|
+
Origen.tester.pattern_footer(options)
|
|
314
|
+
Origen.tester.render_footer
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Generate the pattern header, do this at the very end so that it can
|
|
318
|
+
# dynamically pick up what import subs are required and things like that
|
|
319
|
+
if Origen.tester.generate?
|
|
320
|
+
bank = options[:inhibit] ? :null : :header
|
|
321
|
+
stage.with_bank bank do
|
|
322
|
+
header
|
|
323
|
+
options[:pattern] = job.output_pattern_filename.sub(job.output_extension, '') # remove output extension
|
|
324
|
+
Origen.tester.pattern_header(options)
|
|
325
|
+
Origen.tester.render_header
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
unless options[:inhibit] || !Origen.tester.generate? || job.test?
|
|
330
|
+
stats.collect_for_pattern(job.output_pattern) do
|
|
331
|
+
File.open(job.output_pattern, 'w') do |f|
|
|
332
|
+
[:header, :body, :footer].each do |section|
|
|
333
|
+
Origen.tester.format(stage.bank(section), section) do |line|
|
|
334
|
+
f.puts line
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
log.info ' '
|
|
341
|
+
log.info "Pattern vectors: #{stats.number_of_vectors_for(job.output_pattern).to_s.ljust(10)}"
|
|
342
|
+
log.info 'Execution time'.ljust(15) + ': %.6f' % stats.execution_time_for(job.output_pattern)
|
|
343
|
+
log.info '----------------------------------------------------------------------'
|
|
344
|
+
check_for_changes(job.output_pattern, job.reference_pattern)
|
|
345
|
+
stats.record_pattern_completion(job.output_pattern)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
if Origen.tester.generate?
|
|
349
|
+
Origen.app.listeners_for(:pattern_generated).each do |listener|
|
|
350
|
+
listener.pattern_generated(Pathname.new(job.output_pattern))
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
module Origen
|
|
2
|
+
class Generator
|
|
3
|
+
# The pattern finder is responsible for finding patterns in the pattern
|
|
4
|
+
# directory, allowing the user to create any number of pattern files
|
|
5
|
+
# in any number of sub directories without having to declare them.
|
|
6
|
+
class PatternFinder
|
|
7
|
+
def find(name, options)
|
|
8
|
+
# If the pattern is a fully qualified path to a Ruby file, then just run that:
|
|
9
|
+
if File.exist?(name) && name.strip =~ /\.rb$/
|
|
10
|
+
return check(name, options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
name = File.basename(name)
|
|
14
|
+
@requested_pattern = name # Remember what was originally asked for in case
|
|
15
|
+
# it needs to be output in an error message
|
|
16
|
+
|
|
17
|
+
# Strip the prefix if exists
|
|
18
|
+
if Origen.config.pattern_prefix && name =~ /^#{Origen.config.pattern_prefix}_/
|
|
19
|
+
name.gsub!(/^#{Origen.config.pattern_prefix}_/, '')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Strip the extension if present
|
|
23
|
+
name.gsub!(/\.\w+$/, '')
|
|
24
|
+
|
|
25
|
+
# Strip the postfix if exists
|
|
26
|
+
if Origen.config.pattern_postfix && name =~ /_#{Origen.config.pattern_postfix}$/
|
|
27
|
+
name.gsub!(/_#{Origen.config.pattern_postfix}$/, '')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Otherwise see what can be found...
|
|
31
|
+
return :skip unless proceed_with_pattern?(name) # The application has elected not to run this pattern
|
|
32
|
+
|
|
33
|
+
pats = matching_patterns(name)
|
|
34
|
+
# If the pattern is not found in current plugin and current app then look into other included plugins as well
|
|
35
|
+
if pats.size == 0
|
|
36
|
+
pats = all_matches(name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if pats.size == 0
|
|
40
|
+
# If a pattern can't be found see if it is because the real pattern name is actually
|
|
41
|
+
# a substituted value.
|
|
42
|
+
# Don't want to do this up front since it is possible that some patterns
|
|
43
|
+
# will actually have an explicit value in the name.
|
|
44
|
+
translation = Origen.config.pattern_name_translator(name)
|
|
45
|
+
if translation
|
|
46
|
+
if translation.is_a?(Hash)
|
|
47
|
+
name = translation[:source]
|
|
48
|
+
else
|
|
49
|
+
name = translation
|
|
50
|
+
translation = nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
return :skip unless proceed_with_pattern?(name) # The application has elected not to run this pattern
|
|
54
|
+
pats = matching_patterns(name)
|
|
55
|
+
if pats.size == 0
|
|
56
|
+
pats = all_matches(name)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Last chance see if the supplied name works, this could happen if the user normally
|
|
61
|
+
# substitutes the name in before_pattern but here they have a pattern that
|
|
62
|
+
# actually includes the bit that is normally sub'd out
|
|
63
|
+
if pats.size == 0
|
|
64
|
+
pats = matching_patterns(@requested_pattern)
|
|
65
|
+
if pats.size == 0
|
|
66
|
+
pats = all_matches(@requested_pattern)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if pats.size == 0
|
|
71
|
+
fail "Can't find: #{@requested_pattern}"
|
|
72
|
+
elsif pats.size > 1
|
|
73
|
+
ambiguous_error(pats)
|
|
74
|
+
else
|
|
75
|
+
|
|
76
|
+
if translation
|
|
77
|
+
translation.merge(pattern: check(pats.first, options))
|
|
78
|
+
else
|
|
79
|
+
check(pats.first, options)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def matching_patterns(name)
|
|
85
|
+
# Remove extension in case it is something else, e.g. .atp
|
|
86
|
+
name = name.gsub(/\..*$/, '')
|
|
87
|
+
matches = []
|
|
88
|
+
# First look into the current plugin
|
|
89
|
+
if current_plugin_pattern_path
|
|
90
|
+
matches = Dir.glob("#{current_plugin_pattern_path}/**/#{name}.rb").sort
|
|
91
|
+
# If the current plugin does not include the pattern then look into the current app
|
|
92
|
+
if matches.size == 0
|
|
93
|
+
matches = Dir.glob("#{pattern_directory}/**/#{name}.rb").sort # <= this does not include symlinks
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
matches = Dir.glob("#{pattern_directory}/**/#{name}.rb").sort # <= this does not include symlinks
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
matches
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def current_plugin_pattern_path
|
|
103
|
+
if Origen.current_plugin.name && Origen.current_plugin.instance.config.shared
|
|
104
|
+
File.join Origen.current_plugin.instance.root,
|
|
105
|
+
Origen.current_plugin.instance.config.shared[:patterns] || Origen.current_plugin.instance.config.shared[:pattern]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def all_matches(name)
|
|
110
|
+
name = name.gsub(/\..*$/, '')
|
|
111
|
+
matches = Dir.glob("#{pattern_directory}/**{,/*/**}/#{name}.rb").sort # Takes symlinks into consideration
|
|
112
|
+
matches.flatten.uniq
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def pattern_directory
|
|
116
|
+
Origen.config.pattern_directory
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Check with the application that it wishes to run the given pattern
|
|
120
|
+
def proceed_with_pattern?(name)
|
|
121
|
+
Origen.config.proceed_with_pattern(name)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def check(path, options = {})
|
|
125
|
+
file_plugin = Origen.import_manager.path_within_a_plugin(path)
|
|
126
|
+
if file_plugin
|
|
127
|
+
if Origen.current_plugin.name
|
|
128
|
+
if file_plugin == Origen.current_plugin.name
|
|
129
|
+
return proceed_with_pattern?(path) ? path : :skip
|
|
130
|
+
elsif !options[:current_plugin]
|
|
131
|
+
Origen.current_plugin.temporary = file_plugin
|
|
132
|
+
return proceed_with_pattern?(path) ? path : :skip
|
|
133
|
+
else
|
|
134
|
+
puts "The requested pattern is from plugin #{file_plugin} and current system plugin is set to plugin #{Origen.current_plugin.name}!"
|
|
135
|
+
fail 'Incorrect plugin error!'
|
|
136
|
+
end
|
|
137
|
+
else
|
|
138
|
+
Origen.current_plugin.temporary = file_plugin
|
|
139
|
+
return proceed_with_pattern?(path) ? path : :skip
|
|
140
|
+
end
|
|
141
|
+
else
|
|
142
|
+
return proceed_with_pattern?(path) ? path : :skip
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def ambiguous_error(pats)
|
|
147
|
+
if Origen.running_locally?
|
|
148
|
+
Origen.log.info 'The following patterns match:'
|
|
149
|
+
Origen.log.info pats
|
|
150
|
+
end
|
|
151
|
+
fail "Ambiguous name: #{@requested_pattern}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Origen
|
|
2
|
+
class Generator
|
|
3
|
+
class PatternIterator
|
|
4
|
+
attr_accessor :key
|
|
5
|
+
|
|
6
|
+
def invoke(options, &block)
|
|
7
|
+
if enabled?(options)
|
|
8
|
+
@loop.call(options[key], &block)
|
|
9
|
+
else
|
|
10
|
+
yield
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def loop(&block)
|
|
15
|
+
@loop = block
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup(&block)
|
|
19
|
+
if block
|
|
20
|
+
@setup = block
|
|
21
|
+
elsif @setup
|
|
22
|
+
@setup
|
|
23
|
+
# Setup is optional for an iterator, return something to keep the caller happy
|
|
24
|
+
else
|
|
25
|
+
->(arg) { arg }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def startup(&block)
|
|
30
|
+
if block
|
|
31
|
+
@startup = block
|
|
32
|
+
elsif @startup
|
|
33
|
+
@startup
|
|
34
|
+
# Startup is optional for an iterator, return something to keep the caller happy
|
|
35
|
+
else
|
|
36
|
+
->(_options, arg) { arg }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def pattern_name(&block)
|
|
41
|
+
if block
|
|
42
|
+
@pattern_name = block
|
|
43
|
+
elsif @pattern_name
|
|
44
|
+
@pattern_name
|
|
45
|
+
else
|
|
46
|
+
fail "pattern_name must be defined for iterator: #{key}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def enabled?(options)
|
|
51
|
+
options.keys.include?(key)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module Origen
|
|
2
|
+
class Generator
|
|
3
|
+
# Handles the recursive rendering and importing of sub templates
|
|
4
|
+
# and source files
|
|
5
|
+
module Renderer
|
|
6
|
+
def render(file, options = {}, &block)
|
|
7
|
+
file = Origen.file_handler.clean_path_to_sub_template(file)
|
|
8
|
+
current_pipeline << { file: file, options: options,
|
|
9
|
+
placeholder: placeholder, block: block,
|
|
10
|
+
indent: options[:indent] || 0
|
|
11
|
+
}
|
|
12
|
+
if block_given?
|
|
13
|
+
self.current_buffer += current_pipeline.last[:placeholder] + "\n"
|
|
14
|
+
end
|
|
15
|
+
current_pipeline.last[:placeholder]
|
|
16
|
+
end
|
|
17
|
+
alias_method :import, :render
|
|
18
|
+
|
|
19
|
+
def placeholder
|
|
20
|
+
@ix ||= 0
|
|
21
|
+
@ix += 1
|
|
22
|
+
"_origen_render_placeholder_#{@ix}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def options
|
|
26
|
+
@current_options ||= {}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def pipeline
|
|
30
|
+
@pipeline ||= []
|
|
31
|
+
@pipeline << [] if @pipeline.empty?
|
|
32
|
+
@pipeline
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def current_pipeline
|
|
36
|
+
pipeline.last
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Insert rendered content into any placeholders
|
|
40
|
+
def insert(content)
|
|
41
|
+
while current_pipeline.size > 0
|
|
42
|
+
current = current_pipeline.pop
|
|
43
|
+
pipeline << []
|
|
44
|
+
@current_options = current[:options]
|
|
45
|
+
self.current_buffer = ''
|
|
46
|
+
output = compile(current[:file],
|
|
47
|
+
sub_template: true,
|
|
48
|
+
block: current[:block]
|
|
49
|
+
)
|
|
50
|
+
if current[:indent] && current[:indent] > 0
|
|
51
|
+
indent = ' ' * current[:indent]
|
|
52
|
+
output = output.split("\n").map { |l| indent + l }.join("\n")
|
|
53
|
+
end
|
|
54
|
+
@current_options = nil
|
|
55
|
+
content = insert_content(content, current[:placeholder], output)
|
|
56
|
+
end
|
|
57
|
+
pipeline.pop
|
|
58
|
+
# Always give back a string, this is what existing callers expect
|
|
59
|
+
#
|
|
60
|
+
# Possible this could in future run into problems if the whole file cannot be read
|
|
61
|
+
# into memory, but we can cross that path when we come to it
|
|
62
|
+
if content.is_a?(Pathname)
|
|
63
|
+
c = content.read
|
|
64
|
+
content.delete
|
|
65
|
+
c
|
|
66
|
+
else
|
|
67
|
+
content
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def insert_content(current, placeholder, content)
|
|
72
|
+
# Start using the disk for storing the output rather than memory
|
|
73
|
+
# once it starts to exceed this length
|
|
74
|
+
max_length = 1_000_000
|
|
75
|
+
if current.is_a?(Pathname) || content.is_a?(Pathname) ||
|
|
76
|
+
((current.length + content.length) > max_length)
|
|
77
|
+
unless current.is_a?(Pathname)
|
|
78
|
+
t = temporary_file
|
|
79
|
+
t.open('w') { |f| f.puts current }
|
|
80
|
+
current = t
|
|
81
|
+
end
|
|
82
|
+
new = temporary_file
|
|
83
|
+
new.open('w') do |new_f|
|
|
84
|
+
current.each_line do |line|
|
|
85
|
+
if line.strip == placeholder
|
|
86
|
+
if content.is_a?(Pathname)
|
|
87
|
+
content.each_line do |line|
|
|
88
|
+
new_f.puts line
|
|
89
|
+
end
|
|
90
|
+
content.delete
|
|
91
|
+
else
|
|
92
|
+
new_f.puts content.chomp
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
new_f.puts line
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
current.delete
|
|
100
|
+
new
|
|
101
|
+
else
|
|
102
|
+
current.sub(/ *#{placeholder}/, content)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Returns a Pathname to a uniquely named temporary file
|
|
107
|
+
def temporary_file
|
|
108
|
+
# Ensure this is unique so that is doesn't clash with parallel compile processes
|
|
109
|
+
Pathname.new "#{Origen.root}/tmp/compiler_#{Process.pid}_#{Time.now.to_f}"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|