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
data/bin/cstol_converter
ADDED
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: ascii-8bit
|
|
3
|
+
|
|
4
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
5
|
+
# All Rights Reserved.
|
|
6
|
+
#
|
|
7
|
+
# This program is free software; you can modify and/or redistribute it
|
|
8
|
+
# under the terms of the GNU Affero General Public License
|
|
9
|
+
# as published by the Free Software Foundation; version 3 with
|
|
10
|
+
# attribution addendums as found in the LICENSE.txt
|
|
11
|
+
#
|
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Affero General Public License for more details.
|
|
16
|
+
|
|
17
|
+
# Modified by OpenC3, Inc.
|
|
18
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
19
|
+
# All Rights Reserved
|
|
20
|
+
|
|
21
|
+
# This file converts OASIS CSTOL files to OpenC3 scripts
|
|
22
|
+
|
|
23
|
+
require 'openc3'
|
|
24
|
+
require 'openc3/script'
|
|
25
|
+
require 'openc3/system'
|
|
26
|
+
|
|
27
|
+
# TODO: capitalized string from ask statement may not match expression (gmi.rb:70)
|
|
28
|
+
# TODO: handle V, C other units specifications...
|
|
29
|
+
# TODO: handle unary operators (-1, not - 1) => although Ruby handles this fine
|
|
30
|
+
|
|
31
|
+
def parse_cmd(words)
|
|
32
|
+
# Convert the part that's common to all commands
|
|
33
|
+
str = "cmd(\"" + words[1].upcase + " " + words[2].upcase
|
|
34
|
+
|
|
35
|
+
# If it has parameters
|
|
36
|
+
if words.length == 5
|
|
37
|
+
str = str + " " + parse_id(words[4], true, false, true, true)
|
|
38
|
+
|
|
39
|
+
elsif words.length > 5
|
|
40
|
+
str = str + " with"
|
|
41
|
+
|
|
42
|
+
# Join the rest of the list and remove the commas
|
|
43
|
+
args = words[4..-1].join(" ").split(",")
|
|
44
|
+
args.length.times do |i|
|
|
45
|
+
# Only prepend comma if it is not the first argument pair
|
|
46
|
+
if i != 0
|
|
47
|
+
str = str + ","
|
|
48
|
+
end
|
|
49
|
+
params = args[i].split(" ")
|
|
50
|
+
|
|
51
|
+
str = str + " " + params[0].upcase + " " + parse_id(params[1], true, false, true)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
str = str + "\")"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def parse_cond_operator(op, is_set_tlm = false)
|
|
58
|
+
str = ""
|
|
59
|
+
# Convert CSTOL operators into Ruby operators
|
|
60
|
+
if op.match?("/=")
|
|
61
|
+
str = " != "
|
|
62
|
+
elsif op.match?(">=")
|
|
63
|
+
str = " >= "
|
|
64
|
+
elsif op.match?("<=")
|
|
65
|
+
str = " <= "
|
|
66
|
+
elsif op.match?(">")
|
|
67
|
+
str = " > "
|
|
68
|
+
elsif op.match?("<")
|
|
69
|
+
str = " < "
|
|
70
|
+
elsif op.match?("=")
|
|
71
|
+
str = " == "
|
|
72
|
+
if is_set_tlm
|
|
73
|
+
str = " = "
|
|
74
|
+
end
|
|
75
|
+
elsif op.match?(/VS/i)
|
|
76
|
+
str = " == "
|
|
77
|
+
end
|
|
78
|
+
str
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_expression(vars, quoted = false, in_eval = false)
|
|
82
|
+
i = 0
|
|
83
|
+
str = ""
|
|
84
|
+
finished = false
|
|
85
|
+
# Make sure there are spaces around the operators
|
|
86
|
+
if vars.length > 1
|
|
87
|
+
vars = vars.join(" ")
|
|
88
|
+
else
|
|
89
|
+
vars = vars.to_s
|
|
90
|
+
end
|
|
91
|
+
vars = vars.gsub("(", " ( ")
|
|
92
|
+
vars = vars.gsub(")", " ) ")
|
|
93
|
+
vars = vars.gsub("+", " + ")
|
|
94
|
+
vars = vars.gsub("-", " - ")
|
|
95
|
+
vars = vars.gsub("*", " * ")
|
|
96
|
+
vars = vars.gsub("==", " == ")
|
|
97
|
+
vars = vars.gsub("/=", " /= ")
|
|
98
|
+
vars = vars.gsub("<=", " <= ")
|
|
99
|
+
vars = vars.gsub(">=", " >= ")
|
|
100
|
+
vars = vars.gsub(";", " ; ")
|
|
101
|
+
# Add spaces around single character operators (/ < >)
|
|
102
|
+
offset = 0
|
|
103
|
+
while (idx = vars.index(/[\/<>][^=]/, offset)) != nil
|
|
104
|
+
# Add space before and after operator and increment offset
|
|
105
|
+
vars = vars.insert(idx, " ")
|
|
106
|
+
vars = vars.insert(idx + 2, " ")
|
|
107
|
+
offset = idx + 2
|
|
108
|
+
end
|
|
109
|
+
# Add spaces around single = operator (not /=, ==, <=, or >=)
|
|
110
|
+
offset = 0
|
|
111
|
+
while (idx = vars.index(/[^\/=<>]=[^=]/, offset)) != nil
|
|
112
|
+
# Add space before and after operator and increment offset
|
|
113
|
+
vars = vars.insert(idx + 1, " ")
|
|
114
|
+
vars = vars.insert(idx + 3, " ")
|
|
115
|
+
offset = idx + 3
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Split the expression on spaces
|
|
119
|
+
vars = vars.split(" ")
|
|
120
|
+
|
|
121
|
+
last = nil
|
|
122
|
+
while vars[i] != nil and finished != true
|
|
123
|
+
case vars[i].tr('[]"', '')
|
|
124
|
+
when "("
|
|
125
|
+
if quoted == false
|
|
126
|
+
str = str + "("
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
when ")"
|
|
130
|
+
if quoted == false
|
|
131
|
+
str = str + ")"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
when /\bOR\b/i
|
|
135
|
+
str = str + " || "
|
|
136
|
+
|
|
137
|
+
when /\bAND\b/i
|
|
138
|
+
str = str + " && "
|
|
139
|
+
|
|
140
|
+
when /\b\$[0-9]\b/ # $0, $1, etc are function inputs
|
|
141
|
+
str = str + "inVar" + vars[0][1..-1]
|
|
142
|
+
|
|
143
|
+
when /\$/ # $varName
|
|
144
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted, in_eval)
|
|
145
|
+
|
|
146
|
+
when /RAW/i
|
|
147
|
+
if quoted
|
|
148
|
+
str = str + "tlm_raw('" + parse_tlm_item(vars[i + 1..i + 2]) + "')"
|
|
149
|
+
else
|
|
150
|
+
str = str + "tlm_raw(\"" + parse_tlm_item(vars[i + 1..i + 2]) + "\")"
|
|
151
|
+
end
|
|
152
|
+
i = i + 2
|
|
153
|
+
when /x#[0-9a-fA-F]+/i # Hex number
|
|
154
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted)
|
|
155
|
+
when /b#[0-1]+/i # Binary number
|
|
156
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted)
|
|
157
|
+
|
|
158
|
+
when /(\AVS\z|=|\/=|>|>=|<|<=)/ # Conditional operator
|
|
159
|
+
str = str + parse_cond_operator(vars[i])
|
|
160
|
+
when /(\+|-|\*|\/)/ # Arithmetic operator
|
|
161
|
+
str = str + " " + vars[i].tr('[]"', '') + " "
|
|
162
|
+
|
|
163
|
+
# Verfies Number followed immediately by units
|
|
164
|
+
when /\dDN\z|\ddn\z|\dDEG\z|\ddeg\z|\dRAD\z|\drad\z|\dV\z|\dA\z|\dv\z|\da\z|\dc\z|\dC\z|\df\z|\dF\z|\dDPS\z|\dM\z|\dMPS\z|\dm\z|\dmps\z/ # Checks for decimal/degrees/volts and amps
|
|
165
|
+
temp = vars[i].tr('[]"', '')
|
|
166
|
+
temp = temp.gsub(/DN\z|dn\z|DEG\z|deg\z|RAD\z|rad\z|V\z|A\z|v\z|a\z|c\z|C\z|f\z|F\z|DPS\z|M\z|MPS\z|m\z|mps\z/, '')
|
|
167
|
+
if temp.match?(/[a-zA-Z]/)
|
|
168
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted)
|
|
169
|
+
else
|
|
170
|
+
str = str + temp
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Verifies units are standalone
|
|
174
|
+
when last != '=' && /DN\z|dn\z|DEG\z|deg\z|RAD\z|rad\z|V\z|A\z|v\z|a\z|c\z|C\z|f\z|F\z|DPS\z|M\z|MPS\z|m\z|mps\z/ # Checks for decimal/degrees/volts and amps
|
|
175
|
+
# Verify it is not a target
|
|
176
|
+
if vars[i] != nil and $targetList.include?(vars[i].tr('[]"', '').upcase)
|
|
177
|
+
if quoted
|
|
178
|
+
str = str + "tlm('" + parse_tlm_item(vars[i..i + 1]) + "')"
|
|
179
|
+
else
|
|
180
|
+
str = str + "tlm(\"" + parse_tlm_item(vars[i..i + 1]) + "\")"
|
|
181
|
+
end
|
|
182
|
+
i = i + 1
|
|
183
|
+
else
|
|
184
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted)
|
|
185
|
+
end
|
|
186
|
+
when /[0-9]*:[0-9]*:[0-9]+/ # Timestamp
|
|
187
|
+
str = str + parse_time(vars[i].tr('[]"', ''))
|
|
188
|
+
|
|
189
|
+
when /\dE/ # Floating point
|
|
190
|
+
temp_number = vars[i].tr('E', '').to_f * 10**vars[i + 2].to_f
|
|
191
|
+
str = str + "#{temp_number}"
|
|
192
|
+
finished = true
|
|
193
|
+
when /\d/ # Decimal number
|
|
194
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted)
|
|
195
|
+
|
|
196
|
+
when /\w/ # Must stay low on the list to avoid matching other items
|
|
197
|
+
# Check this keyword against the list of targets
|
|
198
|
+
if vars[i] != nil and $targetList.include?(vars[i].tr('[]"', '').upcase)
|
|
199
|
+
if quoted
|
|
200
|
+
str = str + "tlm('" + parse_tlm_item(vars[i..i + 1]) + "')"
|
|
201
|
+
else
|
|
202
|
+
str = str + "tlm(\"" + parse_tlm_item(vars[i..i + 1]) + "\")"
|
|
203
|
+
end
|
|
204
|
+
i += 1
|
|
205
|
+
|
|
206
|
+
# If it is not a target, then it must be a string or other identifier
|
|
207
|
+
else
|
|
208
|
+
str = str + parse_id(vars[i].tr('[]"', ''), quoted, false, false, false, false)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Other cases not handled
|
|
212
|
+
# else
|
|
213
|
+
# str = str + " # TODO unsupported: " + vars[i].tr('[]"', '')
|
|
214
|
+
end # case
|
|
215
|
+
last = vars[i].tr('[]"', '')
|
|
216
|
+
i += 1
|
|
217
|
+
end # while
|
|
218
|
+
str
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def parse_id(id, quoted = false, in_eval = false, in_command = false, in_single_command = false, units = true)
|
|
222
|
+
str = ""
|
|
223
|
+
# Remove parentheses
|
|
224
|
+
if id.index("(") == 0
|
|
225
|
+
id = id[1..-1]
|
|
226
|
+
end
|
|
227
|
+
if id.index(")") == id.length - 1
|
|
228
|
+
id = id[0..-2]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
if id.match?(/\$\w/) # $varName
|
|
232
|
+
id[1, 1] = id[1, 1].downcase
|
|
233
|
+
if quoted and !in_eval
|
|
234
|
+
str = "'\#{" + id[1..-1] + "}'"
|
|
235
|
+
else
|
|
236
|
+
|
|
237
|
+
str = id[1..-1]
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
elsif id.match(/^"/) != nil and
|
|
241
|
+
id.match(/"$/) != nil # Starts and ends with a quote
|
|
242
|
+
if quoted
|
|
243
|
+
str = "'" + id.upcase[1..-2] + "'"
|
|
244
|
+
else
|
|
245
|
+
str = id.upcase
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
elsif id.match?(/x#[A-Fa-f0-9]+DN/i) # Hex number with DN
|
|
249
|
+
str = "0x" + id[2..-3]
|
|
250
|
+
|
|
251
|
+
elsif id.match?(/x#[0-9a-fA-F]+/i) # Hex number
|
|
252
|
+
str = "0x" + id[2..-1]
|
|
253
|
+
|
|
254
|
+
elsif id.match?(/b#[0-1]+DN/i) # Binary number with DN
|
|
255
|
+
str = "0b" + id[2..-3]
|
|
256
|
+
|
|
257
|
+
elsif id.match?(/b#[0-1]+/i) # Binary number
|
|
258
|
+
str = "0b" + id[2..-1]
|
|
259
|
+
|
|
260
|
+
elsif id.match(/\d+DN/i) or id.match(/-\d+DN/i) # Decimal number with DN
|
|
261
|
+
str = id[0..-3]
|
|
262
|
+
elsif id.match?(/\AVS\z|\Avs\z/)
|
|
263
|
+
str = str + " == "
|
|
264
|
+
|
|
265
|
+
# Verifies extensions with a decimal number followed by a unit
|
|
266
|
+
elsif units && id.match(/\dDN|\ddn|\dDEG|\ddeg|\dRAD|\drad|\dV|\dA|\dv|\da|\dc|\dC|\df|\dF|\dDPS|\dM\z|\dMPS\z|\dm\z|\dmps\z/)
|
|
267
|
+
temp = id.gsub(/DN\z|dn\z|DEG\z|deg\z|RAD\z|rad\z|V\z|A\z|v\z|a\z|c\z|C\z|f\z|F\z|DPS\z|M\z|MPS\z|m\z|mps\z/, '')
|
|
268
|
+
if in_command and temp.match(/[a-zA-Z]/)
|
|
269
|
+
str = str + "\'" + id.upcase + "\'"
|
|
270
|
+
# if filtered words still contain letter, then it is not a number
|
|
271
|
+
elsif temp.match?(/[a-zA-Z]/)
|
|
272
|
+
str = str + id
|
|
273
|
+
else
|
|
274
|
+
str = str + temp
|
|
275
|
+
end
|
|
276
|
+
elsif id.match?(/\dE\+\d/) # Floating point
|
|
277
|
+
id = id.gsub('+', ' + ')
|
|
278
|
+
temp_num_arr = id.split(' ')
|
|
279
|
+
temp_number = temp_num_arr[0].tr('E', '').to_f * 10**temp_num_arr[2].to_f
|
|
280
|
+
str = str + "#{temp_number}"
|
|
281
|
+
elsif id.match(/\A\d/) or id.match(/\A-\d/) # starts with Decimal number
|
|
282
|
+
str = id
|
|
283
|
+
# Verifies extensions with a decimal number followed by a unit
|
|
284
|
+
# that is by itself separated by whitespace
|
|
285
|
+
elsif units && id.match(/\ADN\z|\Adn\z|\ADEG\z|\Adeg\z|\ARAD\z|\Arad\z|\AV\z|\AA\z|\Av\z|\Aa\z|\Ac\z|\AC\z|\Af\z|\AF\z|\ADPS\z|\AM\z|\AMPS\z|\Am\z|\Amps\z/)
|
|
286
|
+
temp = id.gsub(/DN\z|dn\z|DEG\z|deg\z|RAD\z|rad\z|V\z|A\z|v\z|a\z|c\z|C\z|f\z|F\z|DPS\z|M\z|MPS\z|m\z|mps\z/, '')
|
|
287
|
+
if in_command
|
|
288
|
+
str = str + "\'" + id.upcase + "\'"
|
|
289
|
+
else
|
|
290
|
+
str = str + temp
|
|
291
|
+
end
|
|
292
|
+
elsif id.match?(/\w/) # Any other word
|
|
293
|
+
# If it's quoted still need quotes for comparison
|
|
294
|
+
if in_single_command
|
|
295
|
+
str = id.upcase
|
|
296
|
+
elsif quoted
|
|
297
|
+
str = "\'" + id.upcase + "\'"
|
|
298
|
+
else
|
|
299
|
+
str = "\"" + id.tr('\\', '').upcase + "\""
|
|
300
|
+
end
|
|
301
|
+
else
|
|
302
|
+
str = id
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def parse_macro(words)
|
|
307
|
+
# Call the macro with the first parameter as binding
|
|
308
|
+
str = words[0] + "(binding"
|
|
309
|
+
|
|
310
|
+
# Add all arguments in a loop
|
|
311
|
+
(words.length - 1).times do |i|
|
|
312
|
+
str = str + ", " + parse_id(words[i + 1])
|
|
313
|
+
end
|
|
314
|
+
str = str + ")"
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def parse_time(time)
|
|
318
|
+
# If this is a timestamp
|
|
319
|
+
if time.match?(/[0-9]*:[0-9]*:[0-9]+/) # Timestamp
|
|
320
|
+
# Split on colons to separate hours/minutes/seconds
|
|
321
|
+
tok = time.split(":")
|
|
322
|
+
|
|
323
|
+
# If the first two tokens are empty, set to 0 (ex. ::10 is a valid time)
|
|
324
|
+
if tok[0] == ""
|
|
325
|
+
tok[0] = "0"
|
|
326
|
+
end
|
|
327
|
+
if tok[1] == ""
|
|
328
|
+
tok[1] = "0"
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# Compute the number of seconds
|
|
332
|
+
secs = (3600 * tok[0].to_i + 60 * tok[1].to_i + tok[2].to_i).to_s
|
|
333
|
+
|
|
334
|
+
# Other cases not handled
|
|
335
|
+
else
|
|
336
|
+
secs = "# TODO unsupported: " + time
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def parse_tlm_item(tlm)
|
|
341
|
+
# Remove preceeding parentheses
|
|
342
|
+
if tlm[0].index("(") == 0
|
|
343
|
+
tlm[0] = tlm[0][1..-1]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# If there are two telemetry items (target and mnemonic)
|
|
347
|
+
if tlm.length == 2
|
|
348
|
+
begin
|
|
349
|
+
str = tlm[0].tr('[]"', '').upcase + " LATEST " + tlm[1].tr('[]"', '').upcase
|
|
350
|
+
rescue
|
|
351
|
+
str = "# TODO unknown TLM: " + tlm.to_s
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Other cases not handled
|
|
355
|
+
else
|
|
356
|
+
str = "# TODO unsupported: " + tlm.to_s
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def parse_line(full_line, loc_out_file, wait_check_flag = false)
|
|
361
|
+
line = ""
|
|
362
|
+
comment = ""
|
|
363
|
+
str = ""
|
|
364
|
+
|
|
365
|
+
# Handle any empty lines
|
|
366
|
+
if full_line == nil || full_line.strip == ""
|
|
367
|
+
loc_out_file.puts full_line
|
|
368
|
+
return
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Detemine the location of any comments in this line
|
|
372
|
+
commentIdx = full_line.index(";")
|
|
373
|
+
|
|
374
|
+
# If we found a comment operator
|
|
375
|
+
if commentIdx != nil
|
|
376
|
+
# If there's text to pull out before the ;
|
|
377
|
+
if commentIdx != 0
|
|
378
|
+
line = full_line[0..(commentIdx - 1)].rstrip
|
|
379
|
+
end
|
|
380
|
+
# If there's text to pull out after the ;
|
|
381
|
+
if commentIdx != full_line.length - 1
|
|
382
|
+
comment = "#" + full_line[(commentIdx + 1)..-1]
|
|
383
|
+
end
|
|
384
|
+
else
|
|
385
|
+
# No comment operator so use the entire line
|
|
386
|
+
line = full_line.rstrip
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Determine the number of spaces to indent this line by finding the first
|
|
390
|
+
# non-whitespace character
|
|
391
|
+
numSpaces = full_line.index(/\S/)
|
|
392
|
+
numSpaces.times { str = str + " " }
|
|
393
|
+
|
|
394
|
+
# Handle lines with only comments
|
|
395
|
+
if line == nil or line == ""
|
|
396
|
+
loc_out_file.puts str + comment
|
|
397
|
+
return
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# Redundant substitutions are done for comparators
|
|
401
|
+
line = line.gsub("==", " == ")
|
|
402
|
+
line = line.gsub("/=", " /= ")
|
|
403
|
+
line = line.gsub("<=", " <= ")
|
|
404
|
+
line = line.gsub(">=", " >= ")
|
|
405
|
+
line = line.gsub(/(\w)(=)(\w)/, '\1 = \3')
|
|
406
|
+
line = line.gsub(/(\w)(=)(\d)/, '\1 = \3')
|
|
407
|
+
line = line.gsub(/(\w)(=)(-)/, ' = -')
|
|
408
|
+
line = line.gsub(/(\w)(=)(\s)/, '\1 = \3')
|
|
409
|
+
line = line.gsub(/(\s)(=)(\w)/, '\1 = \3')
|
|
410
|
+
|
|
411
|
+
# Split the line into tokens by spaces, if no spaces between equals sign add them
|
|
412
|
+
words = line.split(" ")
|
|
413
|
+
|
|
414
|
+
# Check for old CSTOL labels which have a trailing colon
|
|
415
|
+
if words[0][-1] == ':'
|
|
416
|
+
loc_out_file.puts "# #{line}"
|
|
417
|
+
return
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# if wait_check flag is activated ensure that the next line is a check otherwise infinite loop
|
|
421
|
+
if wait_check_flag and words[0].downcase != 'check'
|
|
422
|
+
return ""
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
case words[0].downcase
|
|
426
|
+
when "endproc"
|
|
427
|
+
if $inFunction
|
|
428
|
+
str += "end\n#{$inFunction}(#{$inFunctionParams.join(',')})" if $inFunction
|
|
429
|
+
$inFunction = nil
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
when "ask"
|
|
433
|
+
str = str + parse_id(words[1]) + " = ask(" + words[2]
|
|
434
|
+
(words.length - 3).times do |i|
|
|
435
|
+
str = str + " " + words[i + 3]
|
|
436
|
+
end
|
|
437
|
+
str = str + ")"
|
|
438
|
+
|
|
439
|
+
when "begin"
|
|
440
|
+
# Don't need to do anything with this keyword, so exit unless there's
|
|
441
|
+
# a comment to print
|
|
442
|
+
if comment == ""
|
|
443
|
+
return
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
when "check"
|
|
447
|
+
|
|
448
|
+
# If the next word starts with the raw keyword
|
|
449
|
+
if words[1].match?(/\A(raw)/i)
|
|
450
|
+
# If the line contains a colon, parse out the range and use tolerance
|
|
451
|
+
if line.match?(":")
|
|
452
|
+
vsIdx = line.index("VS")
|
|
453
|
+
vsIdx = line.index("vs") if vsIdx == nil
|
|
454
|
+
colIdx = line.index(":")
|
|
455
|
+
lowRange = line[(vsIdx + 2)..(colIdx - 1)]
|
|
456
|
+
highRange = line[(colIdx + 1)..-1]
|
|
457
|
+
str = str + "check_tolerance_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
458
|
+
"\", ((" + parse_expression([highRange], false) + ") + (" +
|
|
459
|
+
parse_expression([lowRange], false) +
|
|
460
|
+
")) / 2," + " ((" + parse_expression([highRange], false) + ") - (" +
|
|
461
|
+
parse_expression([lowRange], false) + "))/2)"
|
|
462
|
+
else
|
|
463
|
+
if wait_check_flag
|
|
464
|
+
if @wait_match_string == "\"" + parse_tlm_item(words[2..3]) +
|
|
465
|
+
parse_cond_operator(words[4]) + parse_expression(words[5..-1], true) + "\""
|
|
466
|
+
@verify_wait_check = true
|
|
467
|
+
# exit function with true flag, and skips check statement next parse
|
|
468
|
+
return " "
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
str = str + "check_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
472
|
+
parse_cond_operator(words[4]) + parse_expression(words[5..-1], true) +
|
|
473
|
+
"\")"
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# If the next word starts with a variable indicator
|
|
477
|
+
elsif words[1].match?(/\$/)
|
|
478
|
+
# If the line contains a colon, make check expression formatted to
|
|
479
|
+
# check against a defined range
|
|
480
|
+
if line.match?(":")
|
|
481
|
+
vsIdx = line.index("VS")
|
|
482
|
+
vsIdx = line.index("vs") if vsIdx == nil
|
|
483
|
+
colIdx = line.index(":")
|
|
484
|
+
lowRange = line[(vsIdx + 2)..(colIdx - 1)]
|
|
485
|
+
highRange = line[(colIdx + 1)..-1]
|
|
486
|
+
str = str + "check_expression(\"(" +
|
|
487
|
+
parse_expression([words[1]], true) + " >= (" +
|
|
488
|
+
parse_expression([lowRange], true) + ")) and (" +
|
|
489
|
+
parse_expression([words[1]], true) + " <= (" +
|
|
490
|
+
parse_expression([highRange], true) + "))\")"
|
|
491
|
+
else
|
|
492
|
+
str = str + "check_expression(\"" +
|
|
493
|
+
parse_expression(words[1..-1], true) + "\")"
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# If the next word doesn't start with raw
|
|
497
|
+
elsif words[1].match?(/\w/)
|
|
498
|
+
# If the line contains a colon, parse out the range and use tolerance
|
|
499
|
+
if line.match?(":")
|
|
500
|
+
vsIdx = line.index("VS")
|
|
501
|
+
vsIdx = line.index("vs") if vsIdx == nil
|
|
502
|
+
colIdx = line.index(":")
|
|
503
|
+
lowRange = line[(vsIdx + 2)..(colIdx - 1)]
|
|
504
|
+
highRange = line[(colIdx + 1)..-1]
|
|
505
|
+
str = str + "check_tolerance(\"" +
|
|
506
|
+
parse_tlm_item(words[1..2]) + "\", ((" +
|
|
507
|
+
parse_expression([highRange], false) + ") + (" +
|
|
508
|
+
parse_expression([lowRange], false) + ")) / 2, ((" +
|
|
509
|
+
parse_expression([highRange], false) + ") - (" +
|
|
510
|
+
parse_expression([lowRange], false) + "))/2)"
|
|
511
|
+
else
|
|
512
|
+
if words[3]
|
|
513
|
+
# if single integer comparison or variable, just parse single (for negative integer cases)
|
|
514
|
+
if words.length <= 6
|
|
515
|
+
if wait_check_flag
|
|
516
|
+
if @wait_match_string == "\"" + parse_tlm_item(words[1..2]) + parse_cond_operator(words[3]) + parse_id(words[4], true) + "\""
|
|
517
|
+
@verify_wait_check = true
|
|
518
|
+
# exit function with true flag, and skips check statement next parse
|
|
519
|
+
return ""
|
|
520
|
+
end
|
|
521
|
+
else
|
|
522
|
+
str = str + "check(\"" + parse_tlm_item(words[1..2]) +
|
|
523
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) +
|
|
524
|
+
"\")"
|
|
525
|
+
end
|
|
526
|
+
else
|
|
527
|
+
str = str + "check(\"" + parse_tlm_item(words[1..2]) +
|
|
528
|
+
parse_cond_operator(words[3]) + parse_expression(words[4..-1], true) +
|
|
529
|
+
"\")"
|
|
530
|
+
end
|
|
531
|
+
else
|
|
532
|
+
str = str + "check(\"" + parse_tlm_item(words[1..2]) +
|
|
533
|
+
"\")"
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
when "cmd"
|
|
539
|
+
str = str + parse_cmd(words)
|
|
540
|
+
|
|
541
|
+
when "set"
|
|
542
|
+
str = str + parse_cmd(words)
|
|
543
|
+
|
|
544
|
+
when "declare"
|
|
545
|
+
# If the next word is input, ignore the line
|
|
546
|
+
if words.length >= 2 and words[1].match(/input/i)
|
|
547
|
+
if $inFunction
|
|
548
|
+
$inFunctionParams << "\"#{words[4].upcase}\""
|
|
549
|
+
else
|
|
550
|
+
str = str + "# SCL Ignored: " + line
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
# If it is a defined enum list, ignore definitions
|
|
554
|
+
elsif words.length >= 6 and
|
|
555
|
+
words[4..-1].join(" ").match(/[A-Z]+\s+[A-Z]+(,\s*[A-Z]+)+/i)
|
|
556
|
+
str = str + parse_id(words[2]) + " " + words[3] + " " +
|
|
557
|
+
parse_id(words[4])
|
|
558
|
+
|
|
559
|
+
# If it is a defined range (one and only one colon), ignore range
|
|
560
|
+
elsif words.length >= 6 and
|
|
561
|
+
words[4..-1].join(" ").count(":") == 1
|
|
562
|
+
str = str + parse_id(words[2]) + " " + words[3] + " " +
|
|
563
|
+
parse_id(words[4])
|
|
564
|
+
|
|
565
|
+
# Parse the expression
|
|
566
|
+
elsif words.length >= 5
|
|
567
|
+
str = str + parse_id(words[2]) + " " + words[3] + " " +
|
|
568
|
+
parse_expression(words[4..-1])
|
|
569
|
+
|
|
570
|
+
else
|
|
571
|
+
str = str + "# TODO unsupported: " + line
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
when "else"
|
|
575
|
+
# Only an else
|
|
576
|
+
if words.length == 1
|
|
577
|
+
str = str + "else"
|
|
578
|
+
|
|
579
|
+
# 'Else if' statement
|
|
580
|
+
elsif words.length >= 2 and words[1].match(/if/i)
|
|
581
|
+
str = str + "elsif " + parse_expression(words[2..-1])
|
|
582
|
+
|
|
583
|
+
# Other cases not handled
|
|
584
|
+
else
|
|
585
|
+
str = str + "# TODO unsupported: " + line
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
when "end"
|
|
589
|
+
# End of an if statement
|
|
590
|
+
if words[1].match?(/if/i)
|
|
591
|
+
str = str + "end"
|
|
592
|
+
|
|
593
|
+
# End of a procedure with arguments
|
|
594
|
+
elsif words[1].match(/proc/i) && $inFunction
|
|
595
|
+
str += "end\n#{$inFunction}(#{$inFunctionParams.join(',')})"
|
|
596
|
+
|
|
597
|
+
# End of a procedure without arguments
|
|
598
|
+
elsif words[1].match(/proc/i) && !$inFunction
|
|
599
|
+
str = str + "# SCL Ignored: " + line
|
|
600
|
+
|
|
601
|
+
# End of a loop
|
|
602
|
+
elsif words[1].match?(/loop/i)
|
|
603
|
+
str = str + "end"
|
|
604
|
+
|
|
605
|
+
# End of a macro
|
|
606
|
+
elsif words[1].match?(/macro/i)
|
|
607
|
+
str = str + "# SCL Ignored: " + line
|
|
608
|
+
|
|
609
|
+
# Other cases not handled
|
|
610
|
+
else
|
|
611
|
+
str = str + "# TODO unsupported: " + line
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
when "endif"
|
|
615
|
+
str = str + "end"
|
|
616
|
+
|
|
617
|
+
when "escape"
|
|
618
|
+
str = str + "break"
|
|
619
|
+
|
|
620
|
+
when "goto"
|
|
621
|
+
# Ignore typical goto for skipping the header section
|
|
622
|
+
if words.length == 2 and words[1].match(/start_here/i)
|
|
623
|
+
str = str + "# SCL Ignored: " + line
|
|
624
|
+
|
|
625
|
+
# Other cases not handled
|
|
626
|
+
else
|
|
627
|
+
str = str + "# TODO unsupported: " + line
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
when "if"
|
|
631
|
+
str = str + "if " + parse_expression(words[1..-1])
|
|
632
|
+
|
|
633
|
+
when "let"
|
|
634
|
+
# If we're assigning a telemetry point
|
|
635
|
+
if $targetList.include?(words[1].upcase)
|
|
636
|
+
# If there is no space between the equal sign reparse string
|
|
637
|
+
str = str + "set_tlm(\"" + parse_tlm_item(words[1..2]) +
|
|
638
|
+
parse_cond_operator(words[3], true) + parse_id(words[4], true) + "\")"
|
|
639
|
+
else
|
|
640
|
+
# there's no spaces between declaration
|
|
641
|
+
str = str + parse_id(words[1]) + " " + words[2] + " " +
|
|
642
|
+
parse_expression(words[3..-1])
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
when "lock"
|
|
646
|
+
# Ignore database commands
|
|
647
|
+
str = str + "# SCL Ignored: " + line
|
|
648
|
+
|
|
649
|
+
when "loop"
|
|
650
|
+
# TODO not sure if this is wise, for some files the loop is infinite and
|
|
651
|
+
# there's no exist case
|
|
652
|
+
if words[1] == nil
|
|
653
|
+
str = str + "# TODO Possible inifinite loop case check script file" +
|
|
654
|
+
"\n" + str + "while(true)"
|
|
655
|
+
else
|
|
656
|
+
str = str + words[1] + ".times do |i|"
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
when "macro"
|
|
660
|
+
str = str + ("# SCL Ignored: " + line)
|
|
661
|
+
$macroName = words[1].upcase
|
|
662
|
+
$macroNumArgs = 0
|
|
663
|
+
i = 2
|
|
664
|
+
while (nextWord = words[i]) != nil
|
|
665
|
+
case nextWord
|
|
666
|
+
when /\$/
|
|
667
|
+
$macroNumArgs = $macroNumArgs + 1
|
|
668
|
+
end
|
|
669
|
+
i = i + 1
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
when "new_mac"
|
|
673
|
+
# Ignore OASIS commands
|
|
674
|
+
str = str + "# SCL Ignored: " + line
|
|
675
|
+
|
|
676
|
+
when "new_proc"
|
|
677
|
+
# Ignore OASIS commands
|
|
678
|
+
str = str + "# SCL Ignored: " + line
|
|
679
|
+
|
|
680
|
+
when "proc"
|
|
681
|
+
# Process procedures without arguments as scripts
|
|
682
|
+
if words.length == 2
|
|
683
|
+
# Set a global so we know how to close this function
|
|
684
|
+
$inFunction = nil
|
|
685
|
+
|
|
686
|
+
# Process procedures with arguments as functions
|
|
687
|
+
else
|
|
688
|
+
# Split the list of arguments on commas
|
|
689
|
+
listWords = words[2..-1].join().split(",")
|
|
690
|
+
|
|
691
|
+
# Print the function name and the first argument
|
|
692
|
+
str = str + "def " + words[1].downcase + "(" + parse_id(listWords[0])
|
|
693
|
+
|
|
694
|
+
# Print the remaining arguments preceeded by a separator
|
|
695
|
+
(listWords.length - 1).times do |i|
|
|
696
|
+
str = str + ", " + parse_id(listWords[i + 1])
|
|
697
|
+
end
|
|
698
|
+
str = str + ")"
|
|
699
|
+
|
|
700
|
+
# Set a global so we know how to close this function
|
|
701
|
+
$inFunction = words[1].downcase
|
|
702
|
+
$inFunctionParams = []
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
when "record"
|
|
706
|
+
# Record messages without a label
|
|
707
|
+
if words.length == 2 and words[1].match(/messages/i)
|
|
708
|
+
str = str + "start_logging()\n"
|
|
709
|
+
numSpaces.times { str = str + " " }
|
|
710
|
+
str = str + "start_new_server_message_log()"
|
|
711
|
+
|
|
712
|
+
# Record message with a label
|
|
713
|
+
elsif words.length == 3 and words[1].match(/messages/i)
|
|
714
|
+
str = str + "set_log_label(" + words[2] + ")\n"
|
|
715
|
+
numSpaces.times { str = str + " " }
|
|
716
|
+
str = str + "start_logging()\n"
|
|
717
|
+
numSpaces.times { str = str + " " }
|
|
718
|
+
str = str + "start_new_server_message_log()"
|
|
719
|
+
|
|
720
|
+
# Other cases not handled
|
|
721
|
+
else
|
|
722
|
+
str = str + "# TODO unsupported: " + line
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
when "restore"
|
|
726
|
+
# Ignore database commands
|
|
727
|
+
str = str + "# SCL Ignored: " + line
|
|
728
|
+
when "run"
|
|
729
|
+
temp = words[1..-1].to_s
|
|
730
|
+
temp = temp.tr(',[]\"', '')
|
|
731
|
+
# removes the quotes symbol remnants
|
|
732
|
+
temp = temp.gsub('\\', '')
|
|
733
|
+
temp = temp.delete_suffix('\\')
|
|
734
|
+
str = str + "system(\'" + temp + "\')"
|
|
735
|
+
when "start"
|
|
736
|
+
# Process procedures without arguments as scripts
|
|
737
|
+
if words.length == 2
|
|
738
|
+
str = str + "start(\"" + words[1].downcase + ".rb\")"
|
|
739
|
+
|
|
740
|
+
# Process procedures with arguments as functions
|
|
741
|
+
else
|
|
742
|
+
# Add the statement to require the function
|
|
743
|
+
str = str + "load_utility(\"" + words[1].downcase + ".rb\")\n"
|
|
744
|
+
numSpaces.times { str = str + " " }
|
|
745
|
+
|
|
746
|
+
# Split the list of arguments on commas
|
|
747
|
+
listWords = words[2..-1].join().split(",")
|
|
748
|
+
listWords.map! do |word|
|
|
749
|
+
if word.match?(/[0-9]*:[0-9]*:[0-9]+/) # Timestamp
|
|
750
|
+
parse_time(word)
|
|
751
|
+
else
|
|
752
|
+
word
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
# Print the function name and the first argument
|
|
757
|
+
str = str + words[1].downcase + "(" + parse_id(listWords[0])
|
|
758
|
+
|
|
759
|
+
# Print the remaining arguments preceeded by a separator
|
|
760
|
+
(listWords.length - 1).times do |i|
|
|
761
|
+
str = str + ", " + parse_id(listWords[i + 1])
|
|
762
|
+
end
|
|
763
|
+
str = str + ")"
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
when "start_here:"
|
|
767
|
+
# Ignore typical starting point label
|
|
768
|
+
str = str + "# SCL Ignored: " + line
|
|
769
|
+
|
|
770
|
+
when "stop"
|
|
771
|
+
# Ignore calls to stop logging since OpenC3 stops logging with each start
|
|
772
|
+
str = str + "# SCL Ignored: " + line
|
|
773
|
+
|
|
774
|
+
when "unlock"
|
|
775
|
+
# Ignore database commands
|
|
776
|
+
str = str + "# SCL Ignored: " + line
|
|
777
|
+
|
|
778
|
+
when "update"
|
|
779
|
+
# Ignore database commands
|
|
780
|
+
str = str + "# SCL Ignored: " + line
|
|
781
|
+
|
|
782
|
+
when "wait"
|
|
783
|
+
# add a space incase there's no space between or and parantheses
|
|
784
|
+
line = line.gsub(')or', ') or')
|
|
785
|
+
words = line.split(' ')
|
|
786
|
+
# Only a wait
|
|
787
|
+
if words.length == 1
|
|
788
|
+
str = str + "wait()"
|
|
789
|
+
|
|
790
|
+
# Waiting for length of time
|
|
791
|
+
elsif words[1].match?(/[0-9]*:[0-9]*:[0-9]+/)
|
|
792
|
+
str = str + "wait(" + parse_time(words[1]) + ")"
|
|
793
|
+
|
|
794
|
+
# Waiting for a variable of time
|
|
795
|
+
elsif words.length == 2 and words[1].match(/\$/)
|
|
796
|
+
str = str + "wait(" + parse_id(words[1]) + ")"
|
|
797
|
+
|
|
798
|
+
# Waiting for an expression [or for a time]
|
|
799
|
+
elsif words.length > 2 and words[1].match(/\$/)
|
|
800
|
+
# Get index of 'OR FOR' if it exists by the 'FOR' keyword
|
|
801
|
+
idx = words.index("FOR")
|
|
802
|
+
if idx == nil
|
|
803
|
+
idx = words.index("for")
|
|
804
|
+
end
|
|
805
|
+
|
|
806
|
+
# If there is a timeout
|
|
807
|
+
if idx != nil
|
|
808
|
+
str = str + "wait_expression(\"" +
|
|
809
|
+
parse_expression(words[1..(idx - 2)], true) + "\", " +
|
|
810
|
+
parse_expression([words[idx + 1]]) + ")"
|
|
811
|
+
|
|
812
|
+
# No timeout given, so insert a default timeout
|
|
813
|
+
else
|
|
814
|
+
str = str + "wait_expression(\"" +
|
|
815
|
+
parse_expression(words[1..-1], true) + "\", " +
|
|
816
|
+
parse_time("::30") + ")"
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
# If the next word starts with the raw keyword
|
|
820
|
+
elsif words[1].match?(/[(]*(raw)/i)
|
|
821
|
+
# Get index of 'OR FOR' if it exists by the 'FOR' keyword
|
|
822
|
+
idx = words.index("FOR")
|
|
823
|
+
if idx == nil
|
|
824
|
+
idx = words.index("for")
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
# If there is a timeout
|
|
828
|
+
if idx != nil
|
|
829
|
+
# If the first part is a complex expression
|
|
830
|
+
if words[1..(idx - 2)].include?("OR") ||
|
|
831
|
+
words[1..(idx - 2)].include?("or") ||
|
|
832
|
+
words[1..(idx - 2)].include?("AND") ||
|
|
833
|
+
words[1..(idx - 2)].include?("and")
|
|
834
|
+
str = str + "wait_expression(\"" +
|
|
835
|
+
parse_expression(words[1..(idx - 2)], true) + "\", "
|
|
836
|
+
|
|
837
|
+
# If it is a single telemetry item
|
|
838
|
+
else
|
|
839
|
+
@wait_match_string = "\"" + parse_tlm_item(words[2..3]) +
|
|
840
|
+
parse_cond_operator(words[4]) +
|
|
841
|
+
parse_expression(words[5..(idx - 2)], true) + "\""
|
|
842
|
+
@verify_wait_check = false
|
|
843
|
+
|
|
844
|
+
parse_line(@data_by_lines[@universal_index + 1], @out_file, true)
|
|
845
|
+
|
|
846
|
+
if @verify_wait_check == true
|
|
847
|
+
str = str + "wait_check_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
848
|
+
parse_cond_operator(words[4]) +
|
|
849
|
+
parse_expression(words[5..(idx - 2)], true) + "\", "
|
|
850
|
+
else
|
|
851
|
+
str = str + "wait_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
852
|
+
parse_cond_operator(words[4]) +
|
|
853
|
+
parse_expression(words[5..(idx - 2)], true) + "\", "
|
|
854
|
+
end
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
# Parse the timeout
|
|
858
|
+
str = str + parse_expression([words[idx + 1]])
|
|
859
|
+
|
|
860
|
+
# If there is no timeout given
|
|
861
|
+
else
|
|
862
|
+
# If it is a complex expression
|
|
863
|
+
if words[1..-1].include?("OR") || words[1..-1].include?("or") ||
|
|
864
|
+
words[1..-1].include?("AND") || words[1..-1].include?("and")
|
|
865
|
+
str = str + "wait_expression(\"" +
|
|
866
|
+
parse_expression(words[1..-1], true) + "\", "
|
|
867
|
+
|
|
868
|
+
# If it is a single telemetry item
|
|
869
|
+
else
|
|
870
|
+
@wait_match_string = "\"" + parse_tlm_item(words[2..3]) +
|
|
871
|
+
parse_cond_operator(words[4]) + parse_id(words[5], true) + "\""
|
|
872
|
+
@verify_wait_check = false
|
|
873
|
+
|
|
874
|
+
parse_line(@data_by_lines[@universal_index + 1], @out_file, true)
|
|
875
|
+
|
|
876
|
+
if @verify_wait_check == true
|
|
877
|
+
str = str + "wait_check_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
878
|
+
parse_cond_operator(words[4]) + parse_id(words[5], true) + "\", "
|
|
879
|
+
else
|
|
880
|
+
str = str + "wait_raw(\"" + parse_tlm_item(words[2..3]) +
|
|
881
|
+
parse_cond_operator(words[4]) + parse_id(words[5], true) + "\", "
|
|
882
|
+
end
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
# Insert a default timeout
|
|
886
|
+
str = str + parse_time("::30")
|
|
887
|
+
end
|
|
888
|
+
str = str + ")"
|
|
889
|
+
|
|
890
|
+
# If the next word doesn't start with raw
|
|
891
|
+
elsif words[1].match?(/[(]*\w/)
|
|
892
|
+
# Get index of 'OR FOR' if it exists by the 'FOR' keyword
|
|
893
|
+
idx = words.index("FOR")
|
|
894
|
+
if idx == nil
|
|
895
|
+
idx = words.index("for")
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
# If there is a timeout
|
|
899
|
+
if idx != nil
|
|
900
|
+
# If the first part is a complex expression
|
|
901
|
+
if words[1..(idx - 2)].include?("OR") ||
|
|
902
|
+
words[1..(idx - 2)].include?("or") ||
|
|
903
|
+
words[1..(idx - 2)].include?("AND") ||
|
|
904
|
+
words[1..(idx - 2)].include?("and")
|
|
905
|
+
str = str + "wait_expression(\"" +
|
|
906
|
+
parse_expression(words[1..(idx - 2)], true) + "\", "
|
|
907
|
+
|
|
908
|
+
# If it is a single telemetry item
|
|
909
|
+
else
|
|
910
|
+
@wait_match_string = "\"" + parse_tlm_item(words[1..2]) +
|
|
911
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\""
|
|
912
|
+
@verify_wait_check = false
|
|
913
|
+
|
|
914
|
+
parse_line(@data_by_lines[@universal_index + 1], @out_file, true)
|
|
915
|
+
|
|
916
|
+
if @verify_wait_check == true
|
|
917
|
+
str = str + "wait_check(\"" + parse_tlm_item(words[1..2]) +
|
|
918
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\", "
|
|
919
|
+
else
|
|
920
|
+
str = str + "wait(\"" + parse_tlm_item(words[1..2]) +
|
|
921
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\", "
|
|
922
|
+
end
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
# Parse the timeout
|
|
926
|
+
str = str + parse_expression([words[idx + 1]])
|
|
927
|
+
|
|
928
|
+
# If there is no timeout given
|
|
929
|
+
else
|
|
930
|
+
# If it is a complex expression
|
|
931
|
+
if words[1..-1].include?("OR") || words[1..-1].include?("or") ||
|
|
932
|
+
words[1..-1].include?("AND") || words[1..-1].include?("and")
|
|
933
|
+
str = str + "wait_expression(\"" +
|
|
934
|
+
parse_expression(words[1..-1], true) + "\", "
|
|
935
|
+
|
|
936
|
+
# If it is a single telemetry item
|
|
937
|
+
else
|
|
938
|
+
@wait_match_string = "\"" + parse_tlm_item(words[1..2]) +
|
|
939
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\""
|
|
940
|
+
@verify_wait_check = false
|
|
941
|
+
|
|
942
|
+
parse_line(@data_by_lines[@universal_index + 1], @out_file, true)
|
|
943
|
+
|
|
944
|
+
if @verify_wait_check == true
|
|
945
|
+
str = str + "wait_check(\"" + parse_tlm_item(words[1..2]) +
|
|
946
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\", "
|
|
947
|
+
else
|
|
948
|
+
str = str + "wait(\"" + parse_tlm_item(words[1..2]) +
|
|
949
|
+
parse_cond_operator(words[3]) + parse_id(words[4], true) + "\", "
|
|
950
|
+
end
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
# Insert a default timeout
|
|
954
|
+
str = str + parse_time("::30")
|
|
955
|
+
end
|
|
956
|
+
str = str + ")"
|
|
957
|
+
|
|
958
|
+
else
|
|
959
|
+
str = str + "# TODO unsupported: " + line
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
when "write"
|
|
963
|
+
# Write the command and first word
|
|
964
|
+
str = str + "puts(" + words[1]
|
|
965
|
+
|
|
966
|
+
# Consolidate a " , to ",
|
|
967
|
+
rem = words[2..-1].join(" ")
|
|
968
|
+
quoteSpaceIdx = rem.index("\" ,")
|
|
969
|
+
if quoteSpaceIdx != nil
|
|
970
|
+
rem = rem[0..(quoteSpaceIdx)] + rem[(quoteSpaceIdx + 2)..-1]
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
# Find the closing quote
|
|
974
|
+
quoteIdx = rem.index("\",")
|
|
975
|
+
|
|
976
|
+
# If there was a closing quote
|
|
977
|
+
if quoteIdx != nil and quoteIdx != rem.length - 1
|
|
978
|
+
# Write the characters up until the quote
|
|
979
|
+
str = str + rem[0..quoteIdx - 1]
|
|
980
|
+
|
|
981
|
+
# Parse the rest after the ", as a quoted expression
|
|
982
|
+
expr = rem[(quoteIdx + 2)..-1]
|
|
983
|
+
if expr.class == String
|
|
984
|
+
# There might be yet another quoted section
|
|
985
|
+
quoteIdx = expr.index("\"")
|
|
986
|
+
remainder = ''
|
|
987
|
+
if quoteIdx
|
|
988
|
+
remainder = expr[quoteIdx + 1..-2]
|
|
989
|
+
expr = expr[0..quoteIdx - 1].strip
|
|
990
|
+
expr = expr[0..-2] if expr[-1] == ','
|
|
991
|
+
end
|
|
992
|
+
str = str + " \#{#{parse_expression([expr], true, true)}}#{remainder}\""
|
|
993
|
+
else
|
|
994
|
+
puts "****************** NOT STRING ******************"
|
|
995
|
+
str = str + " \#{" + parse_expression(expr, true, true) + "}\""
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
# If there was no closing quote
|
|
999
|
+
else
|
|
1000
|
+
words[2..-1].each do |word|
|
|
1001
|
+
str = str + " " + word.to_s
|
|
1002
|
+
end
|
|
1003
|
+
end
|
|
1004
|
+
str = str + ")"
|
|
1005
|
+
|
|
1006
|
+
else
|
|
1007
|
+
# If this keyword is contained in the list of macros
|
|
1008
|
+
if $macroList != nil and $macroList.include?(words[0].upcase)
|
|
1009
|
+
str = str + parse_macro(words)
|
|
1010
|
+
|
|
1011
|
+
# Other keywords not handled
|
|
1012
|
+
else
|
|
1013
|
+
str = str + "# TODO unsupported: " + line
|
|
1014
|
+
end
|
|
1015
|
+
end
|
|
1016
|
+
# Implicit end of case statement
|
|
1017
|
+
|
|
1018
|
+
# Write the code and comment to the output file
|
|
1019
|
+
if comment == ""
|
|
1020
|
+
loc_out_file.puts str
|
|
1021
|
+
else
|
|
1022
|
+
loc_out_file.puts str + " " + comment
|
|
1023
|
+
end
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
################################################################################
|
|
1027
|
+
##### BEGIN SCRIPT ######
|
|
1028
|
+
################################################################################
|
|
1029
|
+
|
|
1030
|
+
require 'ostruct'
|
|
1031
|
+
require 'optparse'
|
|
1032
|
+
|
|
1033
|
+
options = OpenStruct.new
|
|
1034
|
+
options.file = nil
|
|
1035
|
+
options.scope = 'DEFAULT'
|
|
1036
|
+
|
|
1037
|
+
opts = OptionParser.new do |opts|
|
|
1038
|
+
opts.banner = "Usage: cstol_converter [optional filenames]"
|
|
1039
|
+
opts.separator ""
|
|
1040
|
+
opts.separator "By default it will parse all macros (*.mac) and CSTOLS (*.prc)"
|
|
1041
|
+
opts.separator "recursively starting in the current working directory"
|
|
1042
|
+
opts.separator ""
|
|
1043
|
+
# Create the help and version options
|
|
1044
|
+
opts.on("-h", "--help", "Show this message") do
|
|
1045
|
+
puts opts
|
|
1046
|
+
exit
|
|
1047
|
+
end
|
|
1048
|
+
opts.on("-s SCOPE", "--scope SCOPE", "Use the specified scope instead of DEFAULT") do |arg|
|
|
1049
|
+
options.scope = arg
|
|
1050
|
+
end
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
begin
|
|
1054
|
+
opts.parse!(ARGV)
|
|
1055
|
+
rescue => err
|
|
1056
|
+
puts err
|
|
1057
|
+
puts opts
|
|
1058
|
+
exit
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
mac_files = []
|
|
1062
|
+
prc_files = []
|
|
1063
|
+
if ARGV[0]
|
|
1064
|
+
ARGV.each do |filename|
|
|
1065
|
+
prc_files << filename
|
|
1066
|
+
end
|
|
1067
|
+
else
|
|
1068
|
+
# Find all macros
|
|
1069
|
+
mac_files = Dir["**/*.mac"]
|
|
1070
|
+
# Find all procedures
|
|
1071
|
+
prc_files = Dir["**/*.prc"]
|
|
1072
|
+
end
|
|
1073
|
+
|
|
1074
|
+
# List of targets found in the CSTOL files
|
|
1075
|
+
$targetList = OpenC3::TargetModel.names(scope: options.scope)
|
|
1076
|
+
|
|
1077
|
+
# Process all macros first
|
|
1078
|
+
unless mac_files.empty?
|
|
1079
|
+
puts "*****************************************************"
|
|
1080
|
+
macros_file = File.open("macrosAutoGen.rb", "w")
|
|
1081
|
+
mac_files.each do |file|
|
|
1082
|
+
puts " Parsing MAC file: " + file
|
|
1083
|
+
|
|
1084
|
+
# Parse each line in the macro file
|
|
1085
|
+
File.open(file, "r") do |infile|
|
|
1086
|
+
out_file = File.open(File.join(Dir.pwd, file[0..-5] + "_macro.rb"), "w")
|
|
1087
|
+
infile.each do |line|
|
|
1088
|
+
parse_line(line, @out_file)
|
|
1089
|
+
end
|
|
1090
|
+
@out_file.close
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
# Create a Ruby macro file that evaluates the macro in the callers context
|
|
1094
|
+
macros_file.print "#{$macroName}_SRC =
|
|
1095
|
+
open(\"#{file[0..-5]}_macro.rb\"){ |f|\n f.sysread(f.stat().size())\n}\n\n"
|
|
1096
|
+
macros_file.print "def #{$macroName}(locBinding"
|
|
1097
|
+
$macroNumArgs.times { |num|
|
|
1098
|
+
macros_file.print ",macVar#{num + 1}"
|
|
1099
|
+
}
|
|
1100
|
+
macros_file.print ")\n"
|
|
1101
|
+
$macroNumArgs.times { |num|
|
|
1102
|
+
macros_file.print " eval(\"inVar#{num + 1} = \#{macVar#{num + 1}}\",locBinding)\n"
|
|
1103
|
+
}
|
|
1104
|
+
macros_file.print " eval(#{$macroName}_SRC,locBinding)\n"
|
|
1105
|
+
macros_file.print "end\n\n"
|
|
1106
|
+
|
|
1107
|
+
# Append this macro to the master list of macros
|
|
1108
|
+
if $macroList == nil
|
|
1109
|
+
$macroList = [$macroName]
|
|
1110
|
+
else
|
|
1111
|
+
$macroList = $macroList.concat([$macroName])
|
|
1112
|
+
end
|
|
1113
|
+
end
|
|
1114
|
+
macros_file.close
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
if prc_files.empty?
|
|
1118
|
+
puts "No *.prc files found"
|
|
1119
|
+
else
|
|
1120
|
+
puts "*****************************************************"
|
|
1121
|
+
|
|
1122
|
+
# Process all procedures next
|
|
1123
|
+
prc_files.each do |file|
|
|
1124
|
+
puts " Parsing PRC file: " + file
|
|
1125
|
+
|
|
1126
|
+
# Open each procedure
|
|
1127
|
+
File.open(file, "r") do |infile|
|
|
1128
|
+
# Open its equivalent Ruby output file
|
|
1129
|
+
@out_file = File.open(File.join(Dir.pwd, File.basename(file)[0..-5] + ".rb"), "w")
|
|
1130
|
+
|
|
1131
|
+
# Read the entire file in first in order to compress line continuations
|
|
1132
|
+
@data = ""
|
|
1133
|
+
matched_quotes = true
|
|
1134
|
+
infile.each do |line|
|
|
1135
|
+
# Check for matching quotes on this line
|
|
1136
|
+
num_quotes = line.scan(/("|[^\\]")/).size
|
|
1137
|
+
if num_quotes % 2 == 1
|
|
1138
|
+
matched_quotes = !matched_quotes
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
# If the last non-whitespace character is the line continuation char
|
|
1142
|
+
if line.match?(/&\s*$/)
|
|
1143
|
+
# Remove the continuation char and returns to join with next line
|
|
1144
|
+
idx = line.rindex("&")
|
|
1145
|
+
@data = @data + line[0..(idx - 1)]
|
|
1146
|
+
elsif matched_quotes == false
|
|
1147
|
+
# If the unmatched string uses the non-standard underscore char
|
|
1148
|
+
if line.match?(/_\s*$/)
|
|
1149
|
+
# Remove the trailing underscore
|
|
1150
|
+
idx = line.rindex("_")
|
|
1151
|
+
line = line[0..(idx - 1)]
|
|
1152
|
+
end
|
|
1153
|
+
# Remove the returns from this line to join with next line
|
|
1154
|
+
@data = @data + line.rstrip
|
|
1155
|
+
else
|
|
1156
|
+
# Leave it alone
|
|
1157
|
+
@data = @data + line
|
|
1158
|
+
end
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
@universal_index = 0
|
|
1162
|
+
@data_by_lines = @data.lines.to_a
|
|
1163
|
+
# Parse each line in the file
|
|
1164
|
+
@data_by_lines.each do |line|
|
|
1165
|
+
if @verify_wait_check == true
|
|
1166
|
+
# Skip line
|
|
1167
|
+
@verify_wait_check = false
|
|
1168
|
+
else
|
|
1169
|
+
parse_line(@data_by_lines[@universal_index], @out_file)
|
|
1170
|
+
end
|
|
1171
|
+
@universal_index += 1
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
# Close the file
|
|
1175
|
+
@out_file.close
|
|
1176
|
+
end
|
|
1177
|
+
end
|
|
1178
|
+
end
|