openc3 5.0.6
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 +7 -0
- data/Gemfile +18 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +727 -0
- data/README.md +37 -0
- data/Rakefile +131 -0
- data/bin/cstol_converter +1178 -0
- data/bin/openc3cli +531 -0
- data/bin/rubysloc +139 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +214 -0
- data/data/config/_interfaces.yaml.err +1017 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +60 -0
- data/data/config/cmd_tlm_server.yaml +136 -0
- data/data/config/command.yaml +44 -0
- data/data/config/command_modifiers.yaml +160 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/interface_modifiers.yaml +104 -0
- data/data/config/item_modifiers.yaml +221 -0
- data/data/config/microservice.yaml +78 -0
- data/data/config/param_item_modifiers.yaml +52 -0
- data/data/config/parameter_modifiers.yaml +200 -0
- data/data/config/plugins.yaml +80 -0
- data/data/config/protocols.yaml +290 -0
- data/data/config/screen.yaml +147 -0
- data/data/config/table_manager.yaml +89 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +142 -0
- data/data/config/target_config.yaml +94 -0
- data/data/config/telemetry.yaml +87 -0
- data/data/config/telemetry_modifiers.yaml +159 -0
- data/data/config/tool.yaml +63 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1505 -0
- data/ext/mkrf_conf.rb +49 -0
- data/ext/openc3/ext/array/array.c +122 -0
- data/ext/openc3/ext/array/extconf.rb +13 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
- data/ext/openc3/ext/config_parser/config_parser.c +280 -0
- data/ext/openc3/ext/config_parser/extconf.rb +13 -0
- data/ext/openc3/ext/crc/crc.c +351 -0
- data/ext/openc3/ext/crc/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
- data/ext/openc3/ext/packet/extconf.rb +13 -0
- data/ext/openc3/ext/packet/packet.c +318 -0
- data/ext/openc3/ext/platform/extconf.rb +13 -0
- data/ext/openc3/ext/platform/platform.c +134 -0
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
- data/ext/openc3/ext/string/extconf.rb +13 -0
- data/ext/openc3/ext/string/string.c +63 -0
- data/ext/openc3/ext/structure/structure.c +1719 -0
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
- data/ext/openc3/ext/telemetry/extconf.rb +13 -0
- data/ext/openc3/ext/telemetry/telemetry.c +336 -0
- data/lib/cosmos.rb +20 -0
- data/lib/cosmosc2.rb +20 -0
- data/lib/openc3/api/api.rb +39 -0
- data/lib/openc3/api/authorized_api.rb +30 -0
- data/lib/openc3/api/cmd_api.rb +451 -0
- data/lib/openc3/api/config_api.rb +58 -0
- data/lib/openc3/api/interface_api.rb +117 -0
- data/lib/openc3/api/limits_api.rb +375 -0
- data/lib/openc3/api/router_api.rb +117 -0
- data/lib/openc3/api/settings_api.rb +70 -0
- data/lib/openc3/api/target_api.rb +78 -0
- data/lib/openc3/api/tlm_api.rb +455 -0
- data/lib/openc3/bridge/bridge.rb +54 -0
- data/lib/openc3/bridge/bridge_config.rb +167 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
- data/lib/openc3/config/config_parser.rb +549 -0
- data/lib/openc3/config/meta_config_parser.rb +74 -0
- data/lib/openc3/conversions/conversion.rb +70 -0
- data/lib/openc3/conversions/generic_conversion.rb +83 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
- data/lib/openc3/conversions/processor_conversion.rb +70 -0
- data/lib/openc3/conversions/received_count_conversion.rb +38 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
- data/lib/openc3/conversions.rb +34 -0
- data/lib/openc3/core_ext/array.rb +416 -0
- data/lib/openc3/core_ext/binding.rb +29 -0
- data/lib/openc3/core_ext/class.rb +72 -0
- data/lib/openc3/core_ext/exception.rb +61 -0
- data/lib/openc3/core_ext/file.rb +83 -0
- data/lib/openc3/core_ext/hash.rb +37 -0
- data/lib/openc3/core_ext/io.rb +134 -0
- data/lib/openc3/core_ext/kernel.rb +42 -0
- data/lib/openc3/core_ext/math.rb +128 -0
- data/lib/openc3/core_ext/matrix.rb +156 -0
- data/lib/openc3/core_ext/objectspace.rb +36 -0
- data/lib/openc3/core_ext/openc3_io.rb +57 -0
- data/lib/openc3/core_ext/range.rb +27 -0
- data/lib/openc3/core_ext/socket.rb +38 -0
- data/lib/openc3/core_ext/string.rb +389 -0
- data/lib/openc3/core_ext/stringio.rb +33 -0
- data/lib/openc3/core_ext/time.rb +508 -0
- data/lib/openc3/core_ext.rb +36 -0
- data/lib/openc3/interfaces/interface.rb +498 -0
- data/lib/openc3/interfaces/linc_interface.rb +475 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
- data/lib/openc3/interfaces/serial_interface.rb +94 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
- data/lib/openc3/interfaces/stream_interface.rb +81 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
- data/lib/openc3/interfaces/udp_interface.rb +169 -0
- data/lib/openc3/interfaces.rb +44 -0
- data/lib/openc3/io/buffered_file.rb +109 -0
- data/lib/openc3/io/io_multiplexer.rb +80 -0
- data/lib/openc3/io/json_api_object.rb +208 -0
- data/lib/openc3/io/json_drb.rb +335 -0
- data/lib/openc3/io/json_drb_object.rb +114 -0
- data/lib/openc3/io/json_drb_rack.rb +84 -0
- data/lib/openc3/io/json_rpc.rb +420 -0
- data/lib/openc3/io/openc3_snmp.rb +58 -0
- data/lib/openc3/io/posix_serial_driver.rb +156 -0
- data/lib/openc3/io/raw_logger.rb +167 -0
- data/lib/openc3/io/raw_logger_pair.rb +77 -0
- data/lib/openc3/io/serial_driver.rb +105 -0
- data/lib/openc3/io/stderr.rb +43 -0
- data/lib/openc3/io/stdout.rb +43 -0
- data/lib/openc3/io/udp_sockets.rb +194 -0
- data/lib/openc3/io/win32_serial_driver.rb +196 -0
- data/lib/openc3/logs/log_writer.rb +302 -0
- data/lib/openc3/logs/packet_log_constants.rb +62 -0
- data/lib/openc3/logs/packet_log_reader.rb +345 -0
- data/lib/openc3/logs/packet_log_writer.rb +299 -0
- data/lib/openc3/logs/text_log_writer.rb +68 -0
- data/lib/openc3/logs.rb +25 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
- data/lib/openc3/microservices/decom_microservice.rb +136 -0
- data/lib/openc3/microservices/interface_microservice.rb +532 -0
- data/lib/openc3/microservices/log_microservice.rb +108 -0
- data/lib/openc3/microservices/microservice.rb +204 -0
- data/lib/openc3/microservices/plugin_microservice.rb +43 -0
- data/lib/openc3/microservices/reaction_microservice.rb +541 -0
- data/lib/openc3/microservices/reducer_microservice.rb +313 -0
- data/lib/openc3/microservices/router_microservice.rb +44 -0
- data/lib/openc3/microservices/text_log_microservice.rb +84 -0
- data/lib/openc3/microservices/timeline_microservice.rb +363 -0
- data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
- data/lib/openc3/models/activity_model.rb +319 -0
- data/lib/openc3/models/auth_model.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +185 -0
- data/lib/openc3/models/environment_model.rb +58 -0
- data/lib/openc3/models/gem_model.rb +137 -0
- data/lib/openc3/models/info_model.rb +31 -0
- data/lib/openc3/models/interface_model.rb +281 -0
- data/lib/openc3/models/interface_status_model.rb +117 -0
- data/lib/openc3/models/metadata_model.rb +139 -0
- data/lib/openc3/models/metric_model.rb +59 -0
- data/lib/openc3/models/microservice_model.rb +206 -0
- data/lib/openc3/models/microservice_status_model.rb +74 -0
- data/lib/openc3/models/model.rb +204 -0
- data/lib/openc3/models/note_model.rb +122 -0
- data/lib/openc3/models/notification_model.rb +40 -0
- data/lib/openc3/models/ping_model.rb +35 -0
- data/lib/openc3/models/plugin_model.rb +292 -0
- data/lib/openc3/models/process_status_model.rb +76 -0
- data/lib/openc3/models/reaction_model.rb +322 -0
- data/lib/openc3/models/reducer_model.rb +65 -0
- data/lib/openc3/models/router_model.rb +35 -0
- data/lib/openc3/models/router_status_model.rb +27 -0
- data/lib/openc3/models/scope_model.rb +153 -0
- data/lib/openc3/models/settings_model.rb +55 -0
- data/lib/openc3/models/sorted_model.rb +167 -0
- data/lib/openc3/models/target_model.rb +759 -0
- data/lib/openc3/models/timeline_model.rb +154 -0
- data/lib/openc3/models/tool_config_model.rb +38 -0
- data/lib/openc3/models/tool_model.rb +262 -0
- data/lib/openc3/models/trigger_group_model.rb +186 -0
- data/lib/openc3/models/trigger_model.rb +330 -0
- data/lib/openc3/models/widget_model.rb +138 -0
- data/lib/openc3/operators/microservice_operator.rb +128 -0
- data/lib/openc3/operators/operator.rb +277 -0
- data/lib/openc3/packets/binary_accessor.rb +1207 -0
- data/lib/openc3/packets/commands.rb +373 -0
- data/lib/openc3/packets/json_packet.rb +134 -0
- data/lib/openc3/packets/limits.rb +271 -0
- data/lib/openc3/packets/limits_response.rb +53 -0
- data/lib/openc3/packets/packet.rb +1168 -0
- data/lib/openc3/packets/packet_config.rb +625 -0
- data/lib/openc3/packets/packet_item.rb +586 -0
- data/lib/openc3/packets/packet_item_limits.rb +162 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
- data/lib/openc3/packets/parsers/state_parser.rb +127 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
- data/lib/openc3/packets/structure.rb +553 -0
- data/lib/openc3/packets/structure_item.rb +365 -0
- data/lib/openc3/packets/telemetry.rb +487 -0
- data/lib/openc3/processors/processor.rb +86 -0
- data/lib/openc3/processors/statistics_processor.rb +82 -0
- data/lib/openc3/processors/watermark_processor.rb +58 -0
- data/lib/openc3/processors.rb +24 -0
- data/lib/openc3/script/api_shared.rb +828 -0
- data/lib/openc3/script/calendar.rb +89 -0
- data/lib/openc3/script/commands.rb +227 -0
- data/lib/openc3/script/exceptions.rb +29 -0
- data/lib/openc3/script/extract.rb +161 -0
- data/lib/openc3/script/limits.rb +60 -0
- data/lib/openc3/script/script.rb +299 -0
- data/lib/openc3/script/script_runner.rb +238 -0
- data/lib/openc3/script/storage.rb +146 -0
- data/lib/openc3/script/suite.rb +542 -0
- data/lib/openc3/script/suite_results.rb +196 -0
- data/lib/openc3/script/suite_runner.rb +217 -0
- data/lib/openc3/script.rb +21 -0
- data/lib/openc3/streams/serial_stream.rb +167 -0
- data/lib/openc3/streams/stream.rb +63 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
- data/lib/openc3/system/system.rb +127 -0
- data/lib/openc3/system/system_config.rb +411 -0
- data/lib/openc3/system/target.rb +269 -0
- data/lib/openc3/system.rb +24 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
- data/lib/openc3/tools/table_manager/table.rb +77 -0
- data/lib/openc3/tools/table_manager/table_config.rb +273 -0
- data/lib/openc3/tools/table_manager/table_item.rb +90 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
- data/lib/openc3/tools/test_runner/test.rb +67 -0
- data/lib/openc3/top_level.rb +595 -0
- data/lib/openc3/topics/autonomic_topic.rb +52 -0
- data/lib/openc3/topics/calendar_topic.rb +44 -0
- data/lib/openc3/topics/command_decom_topic.rb +76 -0
- data/lib/openc3/topics/command_topic.rb +83 -0
- data/lib/openc3/topics/config_topic.rb +68 -0
- data/lib/openc3/topics/interface_topic.rb +73 -0
- data/lib/openc3/topics/limits_event_topic.rb +109 -0
- data/lib/openc3/topics/notifications_topic.rb +28 -0
- data/lib/openc3/topics/router_topic.rb +85 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
- data/lib/openc3/topics/telemetry_topic.rb +36 -0
- data/lib/openc3/topics/timeline_topic.rb +45 -0
- data/lib/openc3/topics/topic.rb +53 -0
- data/lib/openc3/utilities/authentication.rb +141 -0
- data/lib/openc3/utilities/authorization.rb +51 -0
- data/lib/openc3/utilities/crc.rb +278 -0
- data/lib/openc3/utilities/csv.rb +153 -0
- data/lib/openc3/utilities/logger.rb +187 -0
- data/lib/openc3/utilities/message_log.rb +91 -0
- data/lib/openc3/utilities/metric.rb +141 -0
- data/lib/openc3/utilities/process_manager.rb +139 -0
- data/lib/openc3/utilities/quaternion.rb +257 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
- data/lib/openc3/utilities/s3.rb +202 -0
- data/lib/openc3/utilities/s3_autoload.rb +9 -0
- data/lib/openc3/utilities/s3_file_cache.rb +274 -0
- data/lib/openc3/utilities/simulated_target.rb +117 -0
- data/lib/openc3/utilities/sleeper.rb +51 -0
- data/lib/openc3/utilities/store.rb +23 -0
- data/lib/openc3/utilities/store_autoload.rb +237 -0
- data/lib/openc3/utilities/zip.rb +21 -0
- data/lib/openc3/utilities.rb +35 -0
- data/lib/openc3/version.rb +14 -0
- data/lib/openc3/win32/excel.rb +132 -0
- data/lib/openc3/win32/win32.rb +402 -0
- data/lib/openc3/win32/win32_main.rb +333 -0
- data/lib/openc3.rb +49 -0
- data/tasks/gemfile_stats.rake +113 -0
- data/tasks/spec.rake +30 -0
- data/templates/plugin-template/README.md +15 -0
- data/templates/plugin-template/Rakefile +12 -0
- data/templates/plugin-template/plugin.gemspec +23 -0
- data/templates/plugin-template/plugin.txt +9 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
- data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
- data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
- data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
- data/templates/plugin-template/targets/TARGET/target.txt +5 -0
- metadata +849 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
require 'openc3/top_level'
|
|
21
|
+
require 'openc3/ext/config_parser' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
|
|
22
|
+
require 'erb'
|
|
23
|
+
|
|
24
|
+
module OpenC3
|
|
25
|
+
# Reads OpenC3 style configuration data which consists of keywords followed
|
|
26
|
+
# by 0 or more comma delimited parameters. Parameters with spaces must be
|
|
27
|
+
# enclosed in quotes. Quotes should also be used to indicate a parameter is a
|
|
28
|
+
# string. Keywords are case-insensitive and will be returned in uppercase.
|
|
29
|
+
class ConfigParser
|
|
30
|
+
# @return [String] The current keyword being parsed
|
|
31
|
+
attr_accessor :keyword
|
|
32
|
+
|
|
33
|
+
# @return [Array<String>] The parameters found after the keyword
|
|
34
|
+
attr_accessor :parameters
|
|
35
|
+
|
|
36
|
+
# @return [String] The name of the configuration file being parsed. This
|
|
37
|
+
# will be an empty string if the parse_string class method is used.
|
|
38
|
+
attr_accessor :filename
|
|
39
|
+
|
|
40
|
+
# @return [String] The current line being parsed. This is the raw string
|
|
41
|
+
# which is useful when printing errors.
|
|
42
|
+
attr_accessor :line
|
|
43
|
+
|
|
44
|
+
# @return [Integer] The current line number being parsed.
|
|
45
|
+
# This will still be populated when using parse_string because lines
|
|
46
|
+
# still must be delimited by newline characters.
|
|
47
|
+
attr_accessor :line_number
|
|
48
|
+
|
|
49
|
+
# @return [String] The default URL to use in errors. The URL can still be
|
|
50
|
+
# overridden by directly passing it to the error method.
|
|
51
|
+
attr_accessor :url
|
|
52
|
+
|
|
53
|
+
# @see message_callback=
|
|
54
|
+
@@message_callback = nil
|
|
55
|
+
|
|
56
|
+
# @param message_callback [#call(String)] Callback method called with a
|
|
57
|
+
# String when various parsing events occur.
|
|
58
|
+
def self.message_callback=(message_callback)
|
|
59
|
+
@@message_callback = message_callback
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @see progress_callback=
|
|
63
|
+
@@progress_callback = nil
|
|
64
|
+
|
|
65
|
+
# @param progress_callback [#call(Float)] Callback method called with a
|
|
66
|
+
# Float (0.0 to 100.0) based on the amount of the io param that has
|
|
67
|
+
# currently been processed.
|
|
68
|
+
def self.progress_callback=(progress_callback)
|
|
69
|
+
@@progress_callback = progress_callback
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Holds the current splash screen
|
|
73
|
+
@@splash = nil
|
|
74
|
+
|
|
75
|
+
# @param splash [Splash::SplashDialogBox] Set the splash dialog box which
|
|
76
|
+
# will be updated with messages and progress.
|
|
77
|
+
def self.splash=(splash)
|
|
78
|
+
if splash
|
|
79
|
+
@@splash = splash
|
|
80
|
+
@@progress_callback = splash.progress_callback
|
|
81
|
+
@@message_callback = splash.message_callback
|
|
82
|
+
else
|
|
83
|
+
@@splash = nil
|
|
84
|
+
@@progress_callback = nil
|
|
85
|
+
@@message_callback = nil
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Returns the current splash screen if present
|
|
90
|
+
def self.splash
|
|
91
|
+
@@splash
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Regular expression used to break up an individual line into a keyword and
|
|
95
|
+
# comma delimited parameters. Handles parameters in single or double quotes.
|
|
96
|
+
PARSING_REGEX = %r{ (?:"(?:[^\\"]|\\.)*") | (?:'(?:[^\\']|\\.)*') | \S+ }x # "
|
|
97
|
+
|
|
98
|
+
# Error which gets raised by ConfigParser in #verify_num_parameters. This
|
|
99
|
+
# is also the error that classes using ConfigParser should raise when they
|
|
100
|
+
# encounter a configuration error.
|
|
101
|
+
class Error < StandardError
|
|
102
|
+
attr_reader :keyword, :parameters, :filename, :line, :line_number
|
|
103
|
+
|
|
104
|
+
# @return [String] The usage string representing how this keyword should
|
|
105
|
+
# be formatted.
|
|
106
|
+
attr_reader :usage
|
|
107
|
+
|
|
108
|
+
# @return [String] URL which points to usage documentation on the OpenC3
|
|
109
|
+
# Wiki.
|
|
110
|
+
attr_reader :url
|
|
111
|
+
|
|
112
|
+
# Create an Error with the specified Config data
|
|
113
|
+
#
|
|
114
|
+
# @param config_parser [ConfigParser] Instance of ConfigParser so Error
|
|
115
|
+
# has access to the ConfigParser attributes
|
|
116
|
+
# @param message [String] The error message which gets passed to the
|
|
117
|
+
# StandardError constructor
|
|
118
|
+
# @param usage [String] The usage string representing how this keyword should
|
|
119
|
+
# be formatted.
|
|
120
|
+
# @param url [String] URL which should point to usage information. By
|
|
121
|
+
# default this gets constructed to point to the generic configuration
|
|
122
|
+
# Guide on the OpenC3 Wiki.
|
|
123
|
+
def initialize(config_parser, message = "Configuration Error", usage = "", url = "")
|
|
124
|
+
if Error == message
|
|
125
|
+
super(message.message)
|
|
126
|
+
elsif Exception == message
|
|
127
|
+
super("#{message.class}:#{message.message}")
|
|
128
|
+
else
|
|
129
|
+
super(message)
|
|
130
|
+
end
|
|
131
|
+
@keyword = config_parser.keyword
|
|
132
|
+
@parameters = config_parser.parameters
|
|
133
|
+
@filename = config_parser.filename
|
|
134
|
+
@line = config_parser.line
|
|
135
|
+
@line_number = config_parser.line_number
|
|
136
|
+
@usage = usage
|
|
137
|
+
@url = url
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# @param url [String] The url to link to in error messages
|
|
142
|
+
def initialize(url = "https:/openc3.com/docs/v5")
|
|
143
|
+
@url = url
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Creates an Error
|
|
147
|
+
#
|
|
148
|
+
# @param message [String] The string to set the Exception message to
|
|
149
|
+
# @param usage [String] The usage message
|
|
150
|
+
# @param url [String] Where to get help about this error
|
|
151
|
+
# @return [Error] The constructed error
|
|
152
|
+
def error(message, usage = "", url = @url)
|
|
153
|
+
return Error.new(self, message, usage, url)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Called by the ERB template to render a partial
|
|
157
|
+
def render(template_name, options = {})
|
|
158
|
+
raise Error.new(self, "Partial name '#{template_name}' must begin with an underscore.") if File.basename(template_name)[0] != '_'
|
|
159
|
+
|
|
160
|
+
b = binding
|
|
161
|
+
if options[:locals]
|
|
162
|
+
options[:locals].each { |key, value| b.local_variable_set(key, value) }
|
|
163
|
+
end
|
|
164
|
+
# Assume the file is there. If not we raise a pretty obvious error
|
|
165
|
+
if File.expand_path(template_name) == template_name # absolute path
|
|
166
|
+
path = template_name
|
|
167
|
+
else # relative to the current @filename
|
|
168
|
+
path = File.join(File.dirname(@filename), template_name)
|
|
169
|
+
end
|
|
170
|
+
OpenC3.set_working_dir(File.dirname(path)) do
|
|
171
|
+
return ERB.new(File.read(path), trim_mode: "-").result(b)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Processes a file and yields |config| to the given block
|
|
176
|
+
#
|
|
177
|
+
# @param filename [String] The full name and path of the configuration file
|
|
178
|
+
# @param yield_non_keyword_lines [Boolean] Whether to yield all lines including blank
|
|
179
|
+
# lines or comment lines.
|
|
180
|
+
# @param remove_quotes [Boolean] Whether to remove beginning and ending single
|
|
181
|
+
# or double quote characters from parameters.
|
|
182
|
+
# @param run_erb [Boolean] Whether or not to run ERB on the file
|
|
183
|
+
# @param variables [Hash] variables to pash to ERB context
|
|
184
|
+
# @param block [Block] The block to yield to
|
|
185
|
+
# @yieldparam keyword [String] The keyword in the current parsed line
|
|
186
|
+
# @yieldparam parameters [Array<String>] The parameters in the current parsed line
|
|
187
|
+
def parse_file(filename,
|
|
188
|
+
yield_non_keyword_lines = false,
|
|
189
|
+
remove_quotes = true,
|
|
190
|
+
run_erb = true,
|
|
191
|
+
variables = {},
|
|
192
|
+
&block)
|
|
193
|
+
raise Error.new(self, "Configuration file #{filename} does not exist.") unless filename && File.exist?(filename)
|
|
194
|
+
|
|
195
|
+
@filename = filename
|
|
196
|
+
|
|
197
|
+
# Create a temp file where we write the ERB parsed output
|
|
198
|
+
file = create_parsed_output_file(filename, run_erb, variables)
|
|
199
|
+
size = file.stat.size.to_f
|
|
200
|
+
|
|
201
|
+
# Callbacks for beginning of parsing
|
|
202
|
+
@@message_callback.call("Parsing #{size} bytes of #{filename}") if @@message_callback
|
|
203
|
+
@@progress_callback.call(0.0) if @@progress_callback
|
|
204
|
+
|
|
205
|
+
begin
|
|
206
|
+
# Loop through each line of the data
|
|
207
|
+
parse_loop(file,
|
|
208
|
+
yield_non_keyword_lines,
|
|
209
|
+
remove_quotes,
|
|
210
|
+
size,
|
|
211
|
+
PARSING_REGEX,
|
|
212
|
+
&block)
|
|
213
|
+
rescue Exception => e # Catch EVERYTHING so we can re-raise with additional info
|
|
214
|
+
raise e, "#{e}\n\nParsed output in #{file.path}", e.backtrace
|
|
215
|
+
ensure
|
|
216
|
+
file.close unless file.closed?
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Verifies the parameters in the config parameter have the specified
|
|
221
|
+
# number of parameter and raises an Error if not.
|
|
222
|
+
#
|
|
223
|
+
# @param [Integer] min_num_params The minimum number of parameters
|
|
224
|
+
# @param [Integer] max_num_params The maximum number of parameters. Pass
|
|
225
|
+
# nil to indicate there is no maximum number of parameters.
|
|
226
|
+
def verify_num_parameters(min_num_params, max_num_params, usage = "")
|
|
227
|
+
# This syntax works with 0 because each doesn't return any values
|
|
228
|
+
# for a backwards range
|
|
229
|
+
(1..min_num_params).each do |index|
|
|
230
|
+
# If the parameter is nil (0 based) then we have a problem
|
|
231
|
+
if @parameters[index - 1].nil?
|
|
232
|
+
raise Error.new(self, "Not enough parameters for #{@keyword}.", usage, @url)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
# If they pass nil for max_params we don't check for a maximum number
|
|
236
|
+
if max_num_params && !@parameters[max_num_params].nil?
|
|
237
|
+
raise Error.new(self, "Too many parameters for #{@keyword}.", usage, @url)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Verifies the indicated parameter in the config doesn't start or end
|
|
242
|
+
# with an underscore, doesn't contain a double underscore, doesn't contain
|
|
243
|
+
# spaces and doesn't start with a close bracket.
|
|
244
|
+
#
|
|
245
|
+
# @param [Integer] index The index of the parameter to check
|
|
246
|
+
def verify_parameter_naming(index, usage = "")
|
|
247
|
+
param = @parameters[index - 1]
|
|
248
|
+
if param.end_with? '_'
|
|
249
|
+
raise Error.new(self, "Parameter #{index} (#{param}) for #{@keyword} cannot end with an underscore ('_').", usage, @url)
|
|
250
|
+
end
|
|
251
|
+
if param.include? '__'
|
|
252
|
+
raise Error.new(self, "Parameter #{index} (#{param}) for #{@keyword} cannot contain a double underscore ('__').", usage, @url)
|
|
253
|
+
end
|
|
254
|
+
if param.include? ' '
|
|
255
|
+
raise Error.new(self, "Parameter #{index} (#{param}) for #{@keyword} cannot contain a space (' ').", usage, @url)
|
|
256
|
+
end
|
|
257
|
+
if param.start_with?('}')
|
|
258
|
+
raise Error.new(self, "Parameter #{index} (#{param}) for #{@keyword} cannot start with a close bracket ('}').", usage, @url)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Converts a String containing '', 'NIL' or 'NULL' to nil Ruby primitive.
|
|
263
|
+
# All other arguments are simply returned.
|
|
264
|
+
#
|
|
265
|
+
# @param value [Object]
|
|
266
|
+
# @return [nil|Object]
|
|
267
|
+
def self.handle_nil(value)
|
|
268
|
+
if String === value
|
|
269
|
+
case value.upcase
|
|
270
|
+
when '', 'NIL', 'NULL'
|
|
271
|
+
return nil
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
return value
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Converts a String containing 'TRUE' or 'FALSE' to true or false Ruby
|
|
278
|
+
# primitive. All other values are simply returned.
|
|
279
|
+
#
|
|
280
|
+
# @param value [Object]
|
|
281
|
+
# @return [true|false|Object]
|
|
282
|
+
def self.handle_true_false(value)
|
|
283
|
+
if String === value
|
|
284
|
+
case value.upcase
|
|
285
|
+
when 'TRUE'
|
|
286
|
+
return true
|
|
287
|
+
when 'FALSE'
|
|
288
|
+
return false
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
return value
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Converts a String containing '', 'NIL', 'NULL', 'TRUE' or 'FALSE' to nil,
|
|
295
|
+
# true or false Ruby primitives. All other values are simply returned.
|
|
296
|
+
#
|
|
297
|
+
# @param value [Object]
|
|
298
|
+
# @return [true|false|nil|Object]
|
|
299
|
+
def self.handle_true_false_nil(value)
|
|
300
|
+
if String === value
|
|
301
|
+
case value.upcase
|
|
302
|
+
when 'TRUE'
|
|
303
|
+
return true
|
|
304
|
+
when 'FALSE'
|
|
305
|
+
return false
|
|
306
|
+
when '', 'NIL', 'NULL'
|
|
307
|
+
return nil
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
return value
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Converts a string representing a defined constant into its value. The
|
|
314
|
+
# defined constants are the minimum and maximum values for all the
|
|
315
|
+
# allowable data types. [MIN/MAX]_[U]INT[8/16/32] and
|
|
316
|
+
# [MIN/MAX]_FLOAT[32/64]. Thus MIN_UINT8, MAX_INT32, and MIN_FLOAT64 are
|
|
317
|
+
# all allowable values. Any other strings raise ArgumentError but all other
|
|
318
|
+
# types are simply returned.
|
|
319
|
+
#
|
|
320
|
+
# @param value [Object] Can be anything
|
|
321
|
+
# @return [Numeric] The converted value. Either a Fixnum or Float.
|
|
322
|
+
def self.handle_defined_constants(value, data_type = nil, bit_size = nil)
|
|
323
|
+
if value.class == String
|
|
324
|
+
case value.upcase
|
|
325
|
+
when 'MIN', 'MAX'
|
|
326
|
+
return self.calculate_range_value(value.upcase, data_type, bit_size)
|
|
327
|
+
when 'MIN_INT8'
|
|
328
|
+
return -128
|
|
329
|
+
when 'MAX_INT8'
|
|
330
|
+
return 127
|
|
331
|
+
when 'MIN_INT16'
|
|
332
|
+
return -32768
|
|
333
|
+
when 'MAX_INT16'
|
|
334
|
+
return 32767
|
|
335
|
+
when 'MIN_INT32'
|
|
336
|
+
return -2147483648
|
|
337
|
+
when 'MAX_INT32'
|
|
338
|
+
return 2147483647
|
|
339
|
+
when 'MIN_INT64'
|
|
340
|
+
return -9223372036854775808
|
|
341
|
+
when 'MAX_INT64'
|
|
342
|
+
return 9223372036854775807
|
|
343
|
+
when 'MIN_UINT8', 'MIN_UINT16', 'MIN_UINT32', 'MIN_UINT64'
|
|
344
|
+
return 0
|
|
345
|
+
when 'MAX_UINT8'
|
|
346
|
+
return 255
|
|
347
|
+
when 'MAX_UINT16'
|
|
348
|
+
return 65535
|
|
349
|
+
when 'MAX_UINT32'
|
|
350
|
+
return 4294967295
|
|
351
|
+
when 'MAX_UINT64'
|
|
352
|
+
return 18446744073709551615
|
|
353
|
+
when 'MIN_FLOAT64'
|
|
354
|
+
return -Float::MAX
|
|
355
|
+
when 'MAX_FLOAT64'
|
|
356
|
+
return Float::MAX
|
|
357
|
+
when 'MIN_FLOAT32'
|
|
358
|
+
return -3.402823e38
|
|
359
|
+
when 'MAX_FLOAT32'
|
|
360
|
+
return 3.402823e38
|
|
361
|
+
when 'POS_INFINITY'
|
|
362
|
+
return Float::INFINITY
|
|
363
|
+
when 'NEG_INFINITY'
|
|
364
|
+
return -Float::INFINITY
|
|
365
|
+
else
|
|
366
|
+
raise ArgumentError, "Could not convert constant: #{value}"
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
return value
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
protected
|
|
373
|
+
|
|
374
|
+
# Writes the ERB parsed results
|
|
375
|
+
def create_parsed_output_file(filename, run_erb, variables)
|
|
376
|
+
begin
|
|
377
|
+
output = nil
|
|
378
|
+
if run_erb
|
|
379
|
+
OpenC3.set_working_dir(File.dirname(filename)) do
|
|
380
|
+
output = ERB.new(File.read(filename), trim_mode: "-").result(binding.set_variables(variables))
|
|
381
|
+
end
|
|
382
|
+
else
|
|
383
|
+
output = File.read(filename)
|
|
384
|
+
end
|
|
385
|
+
rescue => e
|
|
386
|
+
# The first line of the backtrace indicates the line where the ERB
|
|
387
|
+
# parse failed. Grab the line number for the error message.
|
|
388
|
+
match = /:(.*):/.match(e.backtrace[0])
|
|
389
|
+
line_number = match.captures[0] if match
|
|
390
|
+
raise e, "ERB error at #{filename}:#{line_number}\n#{e}", e.backtrace
|
|
391
|
+
end
|
|
392
|
+
# Make a copy of the filename since we're calling slice! which modifies it directly
|
|
393
|
+
copy = filename.dup
|
|
394
|
+
config_index = copy.index('config')
|
|
395
|
+
if config_index
|
|
396
|
+
copy = copy[config_index..-1]
|
|
397
|
+
elsif copy.include?(':') # Check for Windows drive letter
|
|
398
|
+
copy = copy.split(':')[1]
|
|
399
|
+
end
|
|
400
|
+
parsed_filename = File.join(Dir.tmpdir, 'openc3', 'tmp', copy)
|
|
401
|
+
FileUtils.mkdir_p(File.dirname(parsed_filename)) # Create the path
|
|
402
|
+
file = File.open(parsed_filename, 'w+')
|
|
403
|
+
file.puts output
|
|
404
|
+
file.rewind # Rewind so the file is ready to read
|
|
405
|
+
file
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def self.calculate_range_value(type, data_type, bit_size)
|
|
409
|
+
value = 0 # Default for UINT minimum
|
|
410
|
+
|
|
411
|
+
case data_type
|
|
412
|
+
when :INT
|
|
413
|
+
if type == 'MIN'
|
|
414
|
+
value = -2**(bit_size - 1)
|
|
415
|
+
else # 'MAX'
|
|
416
|
+
value = 2**(bit_size - 1) - 1
|
|
417
|
+
end
|
|
418
|
+
when :UINT
|
|
419
|
+
# Default is 0 for 'MIN'
|
|
420
|
+
if type == 'MAX'
|
|
421
|
+
value = 2**bit_size - 1
|
|
422
|
+
end
|
|
423
|
+
when :FLOAT
|
|
424
|
+
case bit_size
|
|
425
|
+
when 32
|
|
426
|
+
value = 3.402823e38
|
|
427
|
+
value *= -1 if type == 'MIN'
|
|
428
|
+
when 64
|
|
429
|
+
value = Float::MAX
|
|
430
|
+
value *= -1 if type == 'MIN'
|
|
431
|
+
else
|
|
432
|
+
raise ArgumentError, "Invalid bit size #{bit_size} for FLOAT type."
|
|
433
|
+
end
|
|
434
|
+
else
|
|
435
|
+
raise ArgumentError, "Invalid data type #{data_type} when calculating range."
|
|
436
|
+
end
|
|
437
|
+
value
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
|
441
|
+
# Iterates over each line of the io object and yields the keyword and parameters
|
|
442
|
+
def parse_loop(io, yield_non_keyword_lines, remove_quotes, size, rx)
|
|
443
|
+
line_continuation = false
|
|
444
|
+
|
|
445
|
+
@line_number = 0
|
|
446
|
+
@keyword = nil
|
|
447
|
+
@parameters = []
|
|
448
|
+
@line = nil
|
|
449
|
+
|
|
450
|
+
while true
|
|
451
|
+
@line_number += 1
|
|
452
|
+
|
|
453
|
+
if @@progress_callback && ((@line_number % 10) == 0)
|
|
454
|
+
@@progress_callback.call(io.pos / size) if size > 0.0
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
begin
|
|
458
|
+
line = io.readline
|
|
459
|
+
rescue Exception
|
|
460
|
+
break
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
line.strip!
|
|
464
|
+
data = line.scan(rx)
|
|
465
|
+
first_item = data[0].to_s
|
|
466
|
+
|
|
467
|
+
if line_continuation
|
|
468
|
+
@line << line
|
|
469
|
+
# Carry over keyword and parameters
|
|
470
|
+
else
|
|
471
|
+
@line = line
|
|
472
|
+
if (first_item.length == 0) || (first_item[0] == '#')
|
|
473
|
+
@keyword = nil
|
|
474
|
+
else
|
|
475
|
+
@keyword = first_item.upcase
|
|
476
|
+
end
|
|
477
|
+
@parameters = []
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# Ignore comments and blank lines
|
|
481
|
+
if @keyword.nil?
|
|
482
|
+
if (yield_non_keyword_lines) && (!line_continuation)
|
|
483
|
+
yield(@keyword, @parameters)
|
|
484
|
+
end
|
|
485
|
+
next
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
if line_continuation
|
|
489
|
+
if remove_quotes
|
|
490
|
+
@parameters << first_item.remove_quotes
|
|
491
|
+
else
|
|
492
|
+
@parameters << first_item
|
|
493
|
+
end
|
|
494
|
+
line_continuation = false
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
length = data.length
|
|
498
|
+
if length > 1
|
|
499
|
+
(1..(length - 1)).each do |index|
|
|
500
|
+
string = data[index]
|
|
501
|
+
|
|
502
|
+
# Don't process trailing comments such as:
|
|
503
|
+
# KEYWORD PARAM #This is a comment
|
|
504
|
+
# But still process Ruby string interpolations such as:
|
|
505
|
+
# KEYWORD PARAM #{var}
|
|
506
|
+
if (string.length > 0) && (string[0] == '#')
|
|
507
|
+
if !((string.length > 1) && (string[1] == '{'))
|
|
508
|
+
break
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
# If the string is simply '&' and its the last string then its a line continuation so break the loop
|
|
513
|
+
if (string.length == 1) && (string[0] == '&') && (index == (length - 1))
|
|
514
|
+
line_continuation = true
|
|
515
|
+
next
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
line_continuation = false
|
|
519
|
+
if remove_quotes
|
|
520
|
+
@parameters << string.remove_quotes
|
|
521
|
+
else
|
|
522
|
+
@parameters << string
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# If we detected a line continuation while going through all the
|
|
528
|
+
# strings on the line then we strip off the continuation character and
|
|
529
|
+
# return to the top of the loop to continue processing the line.
|
|
530
|
+
if line_continuation
|
|
531
|
+
# Strip the continuation character
|
|
532
|
+
if @line.length >= 1
|
|
533
|
+
@line = @line[0..-2]
|
|
534
|
+
else
|
|
535
|
+
@line = ""
|
|
536
|
+
end
|
|
537
|
+
next
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
yield(@keyword, @parameters)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
@@progress_callback.call(1.0) if @@progress_callback
|
|
544
|
+
|
|
545
|
+
return nil
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
require 'erb'
|
|
21
|
+
require 'psych'
|
|
22
|
+
require 'tempfile'
|
|
23
|
+
require 'openc3/top_level'
|
|
24
|
+
|
|
25
|
+
class Array
|
|
26
|
+
def to_meta_config_yaml(indentation = 0)
|
|
27
|
+
Psych.dump(self).split("\n")[1..-1].join("\n#{' ' * indentation}")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Hash
|
|
32
|
+
def to_meta_config_yaml(indentation = 0)
|
|
33
|
+
Psych.dump(self).split("\n")[1..-1].join("\n#{' ' * indentation}")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module OpenC3
|
|
38
|
+
# Reads YAML formatted files describing a configuration file
|
|
39
|
+
class MetaConfigParser
|
|
40
|
+
@basedir = ''
|
|
41
|
+
def self.load(filename)
|
|
42
|
+
data = nil
|
|
43
|
+
if File.exist?(filename)
|
|
44
|
+
path = filename
|
|
45
|
+
@basedir = File.dirname(filename)
|
|
46
|
+
else
|
|
47
|
+
path = File.join(@basedir, filename)
|
|
48
|
+
end
|
|
49
|
+
tf = Tempfile.new("temp.yaml")
|
|
50
|
+
|
|
51
|
+
output = nil
|
|
52
|
+
OpenC3.set_working_dir(File.dirname(path)) do
|
|
53
|
+
output = ERB.new(File.read(path), trim_mode: "-").result(binding)
|
|
54
|
+
end
|
|
55
|
+
tf.write(output)
|
|
56
|
+
tf.close
|
|
57
|
+
begin
|
|
58
|
+
data = Psych.safe_load(File.read(tf.path), aliases: true)
|
|
59
|
+
rescue => error
|
|
60
|
+
error_file = "#{filename}.err"
|
|
61
|
+
File.open(error_file, 'w') { |file| file.puts output }
|
|
62
|
+
raise error.exception("#{error.message}\n\nParsed output written to #{File.expand_path(error_file)}\n")
|
|
63
|
+
end
|
|
64
|
+
tf.unlink
|
|
65
|
+
data
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.dump(object, filename)
|
|
69
|
+
File.open(filename, 'w') do |file|
|
|
70
|
+
file.write Psych.dump(object)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
module OpenC3
|
|
21
|
+
# Performs a general conversion via the implementation of the call method
|
|
22
|
+
class Conversion
|
|
23
|
+
# @return [Symbol] The converted data type. Must be one of
|
|
24
|
+
# {OpenC3::StructureItem#data_type}
|
|
25
|
+
attr_reader :converted_type
|
|
26
|
+
# @return [Integer] The size in bits of the converted value
|
|
27
|
+
attr_reader :converted_bit_size
|
|
28
|
+
# @return [Integer] The size in bits of the converted array value
|
|
29
|
+
attr_reader :converted_array_size
|
|
30
|
+
|
|
31
|
+
# Create a new conversion
|
|
32
|
+
def initialize
|
|
33
|
+
@converted_type = nil
|
|
34
|
+
@converted_bit_size = nil
|
|
35
|
+
@converted_array_size = nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Perform the conversion on the value.
|
|
39
|
+
#
|
|
40
|
+
# @param value [Object] The value to convert
|
|
41
|
+
# @param packet [Packet] The packet which contains the value. This can
|
|
42
|
+
# be useful to reach into the packet and use other values in the
|
|
43
|
+
# conversion.
|
|
44
|
+
# @param buffer [String] The packet buffer
|
|
45
|
+
# @return The converted value
|
|
46
|
+
def call(value, packet, buffer)
|
|
47
|
+
raise "call method must be defined by subclass"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [String] The conversion class
|
|
51
|
+
def to_s
|
|
52
|
+
self.class.to_s.split('::')[-1]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param read_or_write [String] Either 'READ' or 'WRITE'
|
|
56
|
+
# @return [String] Config fragment for this conversion
|
|
57
|
+
def to_config(read_or_write)
|
|
58
|
+
" #{read_or_write}_CONVERSION #{self.class.name.class_name_to_filename}\n"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def as_json(*a)
|
|
62
|
+
result = {}
|
|
63
|
+
result['class'] = self.class.name.to_s
|
|
64
|
+
result['converted_type'] = @converted_type if @converted_type
|
|
65
|
+
result['converted_bit_size'] = @converted_bit_size if @converted_bit_size
|
|
66
|
+
result['converted_array_size'] = @converted_array_size if @converted_array_size
|
|
67
|
+
result
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|