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.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,568 @@
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 'irb/ruby-lex'
21
+ require 'stringio'
22
+
23
+ if RUBY_VERSION >= "2.7"
24
+
25
+ # Clear the $VERBOSE global since we're overriding methods
26
+ old_verbose = $VERBOSE; $VERBOSE = nil
27
+ class RubyLex
28
+ attr_accessor :indent
29
+ attr_accessor :line_no
30
+ attr_accessor :exp_line_no
31
+ attr_accessor :tokens
32
+ attr_accessor :code_block_open
33
+ attr_accessor :ltype
34
+ attr_accessor :line
35
+ attr_accessor :continue
36
+
37
+ def reinitialize
38
+ @line_no = 1
39
+ @prompt = nil
40
+ initialize_input()
41
+ end
42
+ end
43
+ $VERBOSE = old_verbose
44
+
45
+ class RubyLexUtils
46
+ # Regular expression to detect blank lines
47
+ BLANK_LINE_REGEX = /^\s*$/
48
+ # Regular expression to detect lines containing only 'else'
49
+ LONELY_ELSE_REGEX = /^\s*else\s*$/
50
+
51
+ KEY_KEYWORDS = [
52
+ 'class'.freeze,
53
+ 'module'.freeze,
54
+ 'def'.freeze,
55
+ 'undef'.freeze,
56
+ 'begin'.freeze,
57
+ 'rescue'.freeze,
58
+ 'ensure'.freeze,
59
+ 'end'.freeze,
60
+ 'if'.freeze,
61
+ 'unless'.freeze,
62
+ 'then'.freeze,
63
+ 'elsif'.freeze,
64
+ 'else'.freeze,
65
+ 'case'.freeze,
66
+ 'when'.freeze,
67
+ 'while'.freeze,
68
+ 'until'.freeze,
69
+ 'for'.freeze,
70
+ 'break'.freeze,
71
+ 'next'.freeze,
72
+ 'redo'.freeze,
73
+ 'retry'.freeze,
74
+ 'in'.freeze,
75
+ 'do'.freeze,
76
+ 'return'.freeze,
77
+ 'alias'.freeze
78
+ ]
79
+
80
+ # Create a new RubyLex and StringIO to hold the text to operate on
81
+ def initialize
82
+ @lex = RubyLex.new
83
+ @lex_io = StringIO.new('')
84
+ end
85
+
86
+ if RUBY_VERSION >= "3.0"
87
+ def ripper_lex_without_warning(code)
88
+ RubyLex.ripper_lex_without_warning(code)
89
+ end
90
+ else
91
+ def ripper_lex_without_warning(code)
92
+ @lex.ripper_lex_without_warning(code)
93
+ end
94
+ end
95
+
96
+ # @param text [String]
97
+ # @return [Boolean] Whether the text contains the 'begin' keyword
98
+ def contains_begin?(text)
99
+ @lex.reinitialize
100
+ @lex_io.string = text
101
+ @lex.set_input(@lex_io)
102
+ tokens = ripper_lex_without_warning(text)
103
+ tokens.each do |token|
104
+ if token[1] == :on_kw and token[2] == 'begin'
105
+ return true
106
+ end
107
+ end
108
+ return false
109
+ end
110
+
111
+ # @param text [String]
112
+ # @return [Boolean] Whether the text contains a Ruby keyword
113
+ def contains_keyword?(text)
114
+ @lex.reinitialize
115
+ @lex_io.string = text
116
+ @lex.set_input(@lex_io)
117
+ tokens = ripper_lex_without_warning(text)
118
+ tokens.each do |token|
119
+ if token[1] == :on_kw
120
+ if KEY_KEYWORDS.include?(token[2])
121
+ return true
122
+ end
123
+ elsif token[1] == :on_lbrace and !token[3].allbits?(Ripper::EXPR_BEG | Ripper::EXPR_LABEL)
124
+ return true
125
+ end
126
+ end
127
+ return false
128
+ end
129
+
130
+ # @param text [String]
131
+ # @return [Boolean] Whether the text contains a keyword which starts a block.
132
+ # i.e. 'do', '{', or 'begin'
133
+ def contains_block_beginning?(text)
134
+ @lex.reinitialize
135
+ @lex_io.string = text
136
+ @lex.set_input(@lex_io)
137
+ tokens = ripper_lex_without_warning(text)
138
+ tokens.each do |token|
139
+ if token[1] == :on_kw
140
+ if token[2] == 'begin' || token[2] == 'do'
141
+ return true
142
+ end
143
+ elsif token[1] == :on_lbrace
144
+ return true
145
+ end
146
+ end
147
+ return false
148
+ end
149
+
150
+ # @param text [String]
151
+ # @param progress_dialog [OpenC3::ProgressDialog] If this is set, the overall
152
+ # progress will be set as the processing progresses
153
+ # @return [String] The text with all comments removed
154
+ def remove_comments(text, progress_dialog = nil)
155
+ @lex.reinitialize
156
+ @lex_io.string = text
157
+ @lex.set_input(@lex_io)
158
+ comments_removed = ""
159
+ token_count = 0
160
+ progress = 0.0
161
+ tokens = ripper_lex_without_warning(text)
162
+ tokens.each do |token|
163
+ token_count += 1
164
+ if token[1] != :on_comment
165
+ comments_removed << token[2]
166
+ else
167
+ newline_count = token[2].count("\n")
168
+ comments_removed << ("\n" * newline_count)
169
+ end
170
+ if progress_dialog and token_count % 10000 == 0
171
+ progress += 0.01
172
+ progress = 0.0 if progress >= 0.99
173
+ progress_dialog.set_overall_progress(progress)
174
+ end
175
+ end
176
+
177
+ return comments_removed
178
+ end
179
+
180
+ # Yields each lexed segment and if the segment is instrumentable
181
+ #
182
+ # @param text [String]
183
+ # @yieldparam line [String] The entire line
184
+ # @yieldparam instrumentable [Boolean] Whether the line is instrumentable
185
+ # @yieldparam inside_begin [Integer] The level of indentation
186
+ # @yieldparam line_no [Integer] The current line number
187
+ def each_lexed_segment(text)
188
+ inside_begin = false
189
+ indent = 0
190
+ lex = RubyLex.new
191
+ lex_io = StringIO.new(text)
192
+ lex.set_input(lex_io)
193
+ lex.line = ''
194
+ while lexed = lex.lex
195
+ lex.line_no += lexed.count("\n")
196
+ lex.line.concat lexed
197
+ next if lex.ltype or lex.continue
198
+
199
+ # Detect the beginning and end of begin blocks so we can not catch exceptions there
200
+ if indent == 0 and contains_begin?(lex.line)
201
+ inside_begin = true
202
+ indent = lex.indent
203
+ else
204
+ indent += lex.indent if indent > 0
205
+ end
206
+
207
+ if inside_begin and indent <= 0
208
+ indent = 0
209
+ inside_begin = false
210
+ end
211
+
212
+ loop do # loop to allow restarting for nested conditions
213
+ # Yield blank lines and lonely else lines before the actual line
214
+ while (index = lex.line.index("\n"))
215
+ line = lex.line[0..index]
216
+ if BLANK_LINE_REGEX.match?(line)
217
+ yield line, true, inside_begin, lex.exp_line_no
218
+ lex.exp_line_no += 1
219
+ lex.line = lex.line[(index + 1)..-1]
220
+ elsif LONELY_ELSE_REGEX.match?(line)
221
+ yield line, false, inside_begin, lex.exp_line_no
222
+ lex.exp_line_no += 1
223
+ lex.line = lex.line[(index + 1)..-1]
224
+ else
225
+ break
226
+ end
227
+ end
228
+
229
+ if contains_keyword?(lex.line)
230
+ if contains_block_beginning?(lex.line)
231
+ section = ''
232
+ lex.line.each_line do |lexed_part|
233
+ section << lexed_part
234
+ if contains_block_beginning?(section)
235
+ yield section, false, inside_begin, lex.exp_line_no
236
+ break
237
+ end
238
+ lex.exp_line_no += 1
239
+ end
240
+ lex.exp_line_no += 1
241
+ remainder = lex.line[(section.length)..-1]
242
+ lex.line = remainder
243
+ next unless remainder.empty?
244
+ else
245
+ yield lex.line, false, inside_begin, lex.exp_line_no
246
+ end
247
+ elsif !lex.line.empty?
248
+ num_left_brackets = lex.line.count('{')
249
+ num_right_brackets = lex.line.count('}')
250
+ if num_left_brackets != num_right_brackets
251
+ # Don't instrument lines with unequal numbers of { and } brackets
252
+ yield lex.line, false, inside_begin, lex.exp_line_no
253
+ else
254
+ yield lex.line, true, inside_begin, lex.exp_line_no
255
+ end
256
+ end
257
+ lex.line = ''
258
+ lex.exp_line_no = lex.line_no
259
+ lex.indent = 0
260
+ break
261
+ end # loop do
262
+ end # while lexed
263
+ end # def each_lexed_segment
264
+ end
265
+
266
+ else
267
+
268
+ # Clear the $VERBOSE global since we're overriding methods
269
+ old_verbose = $VERBOSE; $VERBOSE = nil
270
+ class RubyLex
271
+ if self.method_defined?(:indent)
272
+ attr_writer :indent
273
+ else
274
+ attr_accessor :indent
275
+ end
276
+ # @return [Integer] The expression line number. This can differ from the
277
+ # actual line number due to white space and Ruby control keywords.
278
+ attr_accessor :exp_line_no
279
+
280
+ # Resets the RubyLex in preparation of parsing a line
281
+ def reinitialize
282
+ @seek = 0
283
+ @exp_line_no = 1
284
+ @line_no = 1
285
+ @base_char_no = 0
286
+ @char_no = 0
287
+ @rests.clear
288
+ @readed.clear
289
+ @here_readed.clear
290
+ @indent = 0
291
+ @indent_stack.clear
292
+ @lex_state = EXPR_BEG
293
+ @space_seen = false
294
+ @here_header = false
295
+ @continue = false
296
+ @line = ''
297
+ @skip_space = false
298
+ @readed_auto_clean_up = false
299
+ @exception_on_syntax_error = true
300
+ @prompt = nil
301
+ end
302
+
303
+ # Monkey patch to keep this from looping forever if the string never is closed with a right brace
304
+ def identify_string_dvar
305
+ getc
306
+
307
+ reserve_continue = @continue
308
+ reserve_ltype = @ltype
309
+ reserve_indent = @indent
310
+ reserve_indent_stack = @indent_stack
311
+ reserve_state = @lex_state
312
+ reserve_quoted = @quoted
313
+
314
+ @ltype = nil
315
+ @quoted = nil
316
+ @indent = 0
317
+ @indent_stack = []
318
+ @lex_state = EXPR_BEG
319
+
320
+ loop do
321
+ @continue = false
322
+ prompt
323
+ tk = token
324
+ break if tk.nil? # This is the patch
325
+ if @ltype or @continue or @indent >= 0
326
+ next
327
+ end
328
+ break if tk.kind_of?(TkRBRACE)
329
+ end
330
+ ensure
331
+ @continue = reserve_continue
332
+ @ltype = reserve_ltype
333
+ @indent = reserve_indent
334
+ @indent_stack = reserve_indent_stack
335
+ @lex_state = reserve_state
336
+ @quoted = reserve_quoted
337
+ end
338
+ end
339
+ $VERBOSE = old_verbose
340
+
341
+ class RubyLexUtils
342
+ # Regular expression to detect blank lines
343
+ BLANK_LINE_REGEX = /^\s*$/
344
+ # Regular expression to detect lines containing only 'else'
345
+ LONELY_ELSE_REGEX = /^\s*else\s*$/
346
+
347
+ # Ruby keywords
348
+ KEYWORD_TOKENS = [RubyToken::TkCLASS,
349
+ RubyToken::TkMODULE,
350
+ RubyToken::TkDEF,
351
+ RubyToken::TkUNDEF,
352
+ RubyToken::TkBEGIN,
353
+ RubyToken::TkRESCUE,
354
+ RubyToken::TkENSURE,
355
+ RubyToken::TkEND,
356
+ RubyToken::TkIF,
357
+ RubyToken::TkUNLESS,
358
+ RubyToken::TkTHEN,
359
+ RubyToken::TkELSIF,
360
+ RubyToken::TkELSE,
361
+ RubyToken::TkCASE,
362
+ RubyToken::TkWHEN,
363
+ RubyToken::TkWHILE,
364
+ RubyToken::TkUNTIL,
365
+ RubyToken::TkFOR,
366
+ RubyToken::TkBREAK,
367
+ RubyToken::TkNEXT,
368
+ RubyToken::TkREDO,
369
+ RubyToken::TkRETRY,
370
+ RubyToken::TkIN,
371
+ RubyToken::TkDO,
372
+ RubyToken::TkRETURN,
373
+ RubyToken::TkIF_MOD,
374
+ RubyToken::TkUNLESS_MOD,
375
+ RubyToken::TkWHILE_MOD,
376
+ RubyToken::TkUNTIL_MOD,
377
+ RubyToken::TkALIAS,
378
+ RubyToken::TklBEGIN,
379
+ RubyToken::TklEND,
380
+ RubyToken::TkfLBRACE]
381
+
382
+ # Ruby keywords which define the beginning of a block: do, {, begin
383
+ BLOCK_BEGINNING_TOKENS = [RubyToken::TkDO,
384
+ RubyToken::TkfLBRACE,
385
+ RubyToken::TkBEGIN]
386
+
387
+ # Create a new RubyLex and StringIO to hold the text to operate on
388
+ def initialize
389
+ @lex = RubyLex.new
390
+ @lex_io = StringIO.new('')
391
+ end
392
+
393
+ # @param text [String]
394
+ # @return [Boolean] Whether the text contains the 'begin' keyword
395
+ def contains_begin?(text)
396
+ @lex.reinitialize
397
+ @lex.exception_on_syntax_error = false
398
+ @lex_io.string = text
399
+ @lex.set_input(@lex_io)
400
+ while token = @lex.token
401
+ if token.class == RubyToken::TkBEGIN
402
+ return true
403
+ end
404
+ end
405
+ return false
406
+ end
407
+
408
+ # @param text [String]
409
+ # @return [Boolean] Whether the text contains a Ruby keyword
410
+ def contains_keyword?(text)
411
+ @lex.reinitialize
412
+ @lex.exception_on_syntax_error = false
413
+ @lex_io.string = text
414
+ @lex.set_input(@lex_io)
415
+ while token = @lex.token
416
+ if KEYWORD_TOKENS.include?(token.class)
417
+ return true
418
+ end
419
+ end
420
+ return false
421
+ end
422
+
423
+ # @param text [String]
424
+ # @return [Boolean] Whether the text contains a keyword which starts a block.
425
+ # i.e. 'do', '{', or 'begin'
426
+ def contains_block_beginning?(text)
427
+ @lex.reinitialize
428
+ @lex.exception_on_syntax_error = false
429
+ @lex_io.string = text
430
+ @lex.set_input(@lex_io)
431
+ while token = @lex.token
432
+ if BLOCK_BEGINNING_TOKENS.include?(token.class)
433
+ return true
434
+ end
435
+ end
436
+ return false
437
+ end
438
+
439
+ # @param text [String]
440
+ # @param progress_dialog [OpenC3::ProgressDialog] If this is set, the overall
441
+ # progress will be set as the processing progresses
442
+ # @return [String] The text with all comments removed
443
+ def remove_comments(text, progress_dialog = nil)
444
+ comments_removed = text.clone
445
+ @lex.reinitialize
446
+ @lex.exception_on_syntax_error = false
447
+ @lex_io.string = text
448
+ @lex.set_input(@lex_io)
449
+ need_remove = nil
450
+ delete_ranges = []
451
+ token_count = 0
452
+ progress = 0.0
453
+ while token = @lex.token
454
+ token_count += 1
455
+ if need_remove
456
+ delete_ranges << (need_remove..(token.seek - 1))
457
+ need_remove = nil
458
+ end
459
+ if token.class == RubyToken::TkCOMMENT
460
+ need_remove = token.seek
461
+ end
462
+ if progress_dialog and token_count % 10000 == 0
463
+ progress += 0.01
464
+ progress = 0.0 if progress >= 0.99
465
+ progress_dialog.set_overall_progress(progress)
466
+ end
467
+ end
468
+
469
+ if need_remove
470
+ delete_ranges << (need_remove..(text.length - 1))
471
+ need_remove = nil
472
+ end
473
+
474
+ delete_count = 0
475
+ delete_ranges.reverse_each do |range|
476
+ delete_count += 1
477
+ comments_removed[range] = ''
478
+ if progress_dialog and delete_count % 10000 == 0
479
+ progress += 0.01
480
+ progress = 0.0 if progress >= 0.99
481
+ progress_dialog.set_overall_progress(progress)
482
+ end
483
+ end
484
+
485
+ return comments_removed
486
+ end
487
+
488
+ # Yields each lexed segment and if the segment is instrumentable
489
+ #
490
+ # @param text [String]
491
+ # @yieldparam line [String] The entire line
492
+ # @yieldparam instrumentable [Boolean] Whether the line is instrumentable
493
+ # @yieldparam inside_begin [Integer] The level of indentation
494
+ # @yieldparam line_no [Integer] The current line number
495
+ def each_lexed_segment(text)
496
+ inside_begin = false
497
+ inside_indent = nil
498
+ lex = RubyLex.new
499
+ lex.exception_on_syntax_error = false
500
+ lex_io = StringIO.new(text)
501
+ lex.set_input(lex_io)
502
+
503
+ while lexed = lex.lex
504
+ line_no = lex.exp_line_no
505
+
506
+ if inside_indent.nil? and contains_begin?(lexed)
507
+ inside_indent = lex.indent - 1
508
+ inside_begin = true
509
+ end
510
+
511
+ if lex.indent == inside_indent
512
+ inside_indent = nil
513
+ inside_begin = false
514
+ end
515
+
516
+ loop do # loop to allow restarting for nested conditions
517
+ # Yield blank lines and lonely else lines before the actual line
518
+ while (index = lexed.index("\n"))
519
+ line = lexed[0..index]
520
+ if BLANK_LINE_REGEX.match?(line)
521
+ yield line, true, inside_begin, line_no
522
+ line_no += 1
523
+ lexed = lexed[(index + 1)..-1]
524
+ elsif LONELY_ELSE_REGEX.match?(line)
525
+ yield line, false, inside_begin, line_no
526
+ line_no += 1
527
+ lexed = lexed[(index + 1)..-1]
528
+ else
529
+ break
530
+ end
531
+ end
532
+
533
+ if contains_keyword?(lexed)
534
+ if contains_block_beginning?(lexed)
535
+ section = ''
536
+ lexed.each_line do |lexed_part|
537
+ section << lexed_part
538
+ if contains_block_beginning?(section)
539
+ yield section, false, inside_begin, line_no
540
+ break
541
+ end
542
+ line_no += 1
543
+ end
544
+ line_no += 1
545
+ remainder = lexed[(section.length)..-1]
546
+ lexed = remainder
547
+ next unless remainder.empty?
548
+ else
549
+ yield lexed, false, inside_begin, line_no
550
+ end
551
+ elsif !lexed.empty?
552
+ num_left_brackets = lexed.count('{')
553
+ num_right_brackets = lexed.count('}')
554
+ if num_left_brackets != num_right_brackets
555
+ # Don't instrument lines with unequal numbers of { and } brackets
556
+ yield lexed, false, inside_begin, line_no
557
+ else
558
+ yield lexed, true, inside_begin, line_no
559
+ end
560
+ end
561
+ lex.exp_line_no = lex.line_no
562
+ break
563
+ end # loop do
564
+ end # while lexed
565
+ end # def each_lexed_segment
566
+ end
567
+
568
+ end # RUBY_VERSION < "2.7"