cosmos 3.5.1 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1158) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -1
  3. data/.gitattributes +3 -3
  4. data/.gitignore +48 -48
  5. data/.travis.yml +8 -8
  6. data/CONTRIBUTING.txt +50 -50
  7. data/Gemfile +10 -10
  8. data/Guardfile +27 -27
  9. data/LICENSE.txt +879 -879
  10. data/Manifest.txt +1414 -1414
  11. data/README.md +111 -111
  12. data/Rakefile +218 -214
  13. data/autohotkey/config/data/diamond.STL +57 -57
  14. data/autohotkey/config/system/system.txt +34 -34
  15. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  16. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  17. data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  18. data/autohotkey/config/targets/COSMOS/target.txt +5 -5
  19. data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  20. data/autohotkey/config/targets/INST/cmd_tlm/inst_tlm.txt +270 -270
  21. data/autohotkey/config/targets/INST/cmd_tlm_server.txt +5 -5
  22. data/autohotkey/config/targets/INST/lib/example_limits_response.rb +30 -30
  23. data/autohotkey/config/targets/INST/lib/sim_inst.rb +305 -305
  24. data/autohotkey/config/targets/INST/screens/adcs.txt +46 -46
  25. data/autohotkey/config/targets/INST/screens/array.txt +7 -7
  26. data/autohotkey/config/targets/INST/screens/block.txt +8 -8
  27. data/autohotkey/config/targets/INST/screens/commanding.txt +30 -30
  28. data/autohotkey/config/targets/INST/screens/graphs.txt +14 -14
  29. data/autohotkey/config/targets/INST/screens/ground.txt +25 -25
  30. data/autohotkey/config/targets/INST/screens/health_status.txt +33 -33
  31. data/autohotkey/config/targets/INST/screens/hs.txt +49 -49
  32. data/autohotkey/config/targets/INST/screens/image.txt +21 -21
  33. data/autohotkey/config/targets/INST/screens/latest.txt +23 -23
  34. data/autohotkey/config/targets/INST/screens/mech.txt +25 -25
  35. data/autohotkey/config/targets/INST/screens/other.txt +25 -25
  36. data/autohotkey/config/targets/INST/screens/params.txt +25 -25
  37. data/autohotkey/config/targets/INST/screens/tabs.txt +68 -68
  38. data/autohotkey/config/targets/INST/target.txt +26 -26
  39. data/autohotkey/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  40. data/autohotkey/config/targets/META/cmd_tlm/meta_tlm.txt +9 -9
  41. data/autohotkey/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  42. data/autohotkey/config/targets/SYSTEM/screens/error.txt +11 -11
  43. data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +22 -22
  44. data/autohotkey/config/tools/data_viewer/data_viewer.txt +11 -11
  45. data/autohotkey/config/tools/handbook_creator/handbook_creator.txt +49 -49
  46. data/autohotkey/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  47. data/autohotkey/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  48. data/autohotkey/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  49. data/autohotkey/config/tools/handbook_creator/templates/header.html.erb +25 -25
  50. data/autohotkey/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  51. data/autohotkey/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  52. data/autohotkey/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  53. data/autohotkey/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  54. data/autohotkey/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  55. data/autohotkey/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  56. data/autohotkey/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  57. data/autohotkey/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  58. data/autohotkey/config/tools/handbook_creator/templates/title.html.erb +1 -1
  59. data/autohotkey/config/tools/launcher/launcher.txt +38 -38
  60. data/autohotkey/config/tools/script_runner/script_runner.txt +3 -3
  61. data/autohotkey/config/tools/table_manager/ConfigTables_def.txt +8 -8
  62. data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +19 -19
  63. data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +248 -248
  64. data/autohotkey/config/tools/test_runner/test_runner.txt +8 -8
  65. data/autohotkey/config/tools/test_runner/test_runner2.txt +11 -11
  66. data/autohotkey/config/tools/test_runner/test_runner3.txt +6 -6
  67. data/autohotkey/config/tools/test_runner/test_runner4.txt +1 -1
  68. data/autohotkey/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  69. data/autohotkey/config/tools/tlm_extractor/tlm_extractor2.txt +9 -9
  70. data/autohotkey/config/tools/tlm_grapher/bad.txt +50 -50
  71. data/autohotkey/config/tools/tlm_grapher/temp1-4.txt +51 -51
  72. data/autohotkey/config/tools/tlm_grapher/test2.txt +111 -111
  73. data/autohotkey/config/tools/tlm_viewer/tlm_viewer.txt +24 -24
  74. data/autohotkey/config/tools/tlm_viewer/tlm_viewer2.txt +4 -4
  75. data/autohotkey/config/tools/tlm_viewer/tlm_viewer3.txt +3 -3
  76. data/autohotkey/lib/example_background_task.rb +42 -42
  77. data/autohotkey/lib/user_version.rb +3 -3
  78. data/autohotkey/procedures/clear_util.rb +7 -7
  79. data/autohotkey/procedures/collect_util.rb +14 -14
  80. data/autohotkey/procedures/example_test.rb +67 -67
  81. data/autohotkey/procedures/example_test2.rb +74 -74
  82. data/autohotkey/procedures/script_test.rb +17 -17
  83. data/autohotkey/procedures/syntax_error.rb +18 -18
  84. data/autohotkey/tools/CmdExtractorAHK +16 -16
  85. data/autohotkey/tools/CmdSender +14 -14
  86. data/autohotkey/tools/CmdSenderAHK +18 -18
  87. data/autohotkey/tools/CmdTlmServer +14 -14
  88. data/autohotkey/tools/CmdTlmServerAHK +28 -28
  89. data/autohotkey/tools/CmdTlmServerAHK2 +17 -17
  90. data/autohotkey/tools/DataViewer +14 -14
  91. data/autohotkey/tools/DataViewerAHK +17 -17
  92. data/autohotkey/tools/HandbookCreatorAHK +20 -20
  93. data/autohotkey/tools/LauncherAHK +17 -17
  94. data/autohotkey/tools/LimitsMonitorAHK +20 -20
  95. data/autohotkey/tools/OpenGLBuilderAHK +24 -24
  96. data/autohotkey/tools/PacketViewer +14 -14
  97. data/autohotkey/tools/PacketViewerAHK +18 -18
  98. data/autohotkey/tools/PacketViewerAHK2 +17 -17
  99. data/autohotkey/tools/Replay +14 -14
  100. data/autohotkey/tools/ReplayAHK +17 -17
  101. data/autohotkey/tools/ScriptRunner +14 -14
  102. data/autohotkey/tools/ScriptRunnerAHK +20 -20
  103. data/autohotkey/tools/ScriptRunnerAHK2 +17 -17
  104. data/autohotkey/tools/TableManager +14 -14
  105. data/autohotkey/tools/TableManagerAHK +30 -30
  106. data/autohotkey/tools/TestRunner +15 -15
  107. data/autohotkey/tools/TestRunnerAHK +17 -17
  108. data/autohotkey/tools/TestRunnerAHK2 +17 -17
  109. data/autohotkey/tools/TestRunnerAHK3 +17 -17
  110. data/autohotkey/tools/TestRunnerAHK4 +17 -17
  111. data/autohotkey/tools/TestRunnerAHK5 +17 -17
  112. data/autohotkey/tools/TestRunnerAHK6 +17 -17
  113. data/autohotkey/tools/TlmExtractor +15 -15
  114. data/autohotkey/tools/TlmExtractorAHK +19 -19
  115. data/autohotkey/tools/TlmExtractorAHK2 +16 -16
  116. data/autohotkey/tools/TlmExtractorAHK3 +16 -16
  117. data/autohotkey/tools/TlmGrapher +14 -14
  118. data/autohotkey/tools/TlmGrapherAHK +19 -19
  119. data/autohotkey/tools/TlmGrapherAHK2 +23 -23
  120. data/autohotkey/tools/TlmGrapherAHK3 +17 -17
  121. data/autohotkey/tools/TlmGrapherAHK4 +17 -17
  122. data/autohotkey/tools/TlmViewer +14 -14
  123. data/autohotkey/tools/TlmViewerAHK +28 -28
  124. data/autohotkey/tools/TlmViewerAHK2 +22 -22
  125. data/autohotkey/tools/TlmViewerAHK3 +23 -23
  126. data/autohotkey/tools/TlmViewerAHK4 +22 -22
  127. data/autohotkey/tools/TlmViewerAHK5 +18 -18
  128. data/autohotkey/tools/autohotkey.rb +37 -37
  129. data/autohotkey/tools/cmd_extractor.ahk +33 -33
  130. data/autohotkey/tools/cmd_sender.ahk +182 -182
  131. data/autohotkey/tools/cmd_tlm_server.ahk +90 -90
  132. data/autohotkey/tools/cmd_tlm_server2.ahk +45 -45
  133. data/autohotkey/tools/data_viewer.ahk +141 -141
  134. data/autohotkey/tools/handbook_creator.ahk +32 -32
  135. data/autohotkey/tools/launcher.ahk +41 -41
  136. data/autohotkey/tools/limits_monitor.ahk +123 -123
  137. data/autohotkey/tools/open_gl_builder.ahk +134 -134
  138. data/autohotkey/tools/packet_viewer.ahk +196 -196
  139. data/autohotkey/tools/packet_viewer2.ahk +9 -9
  140. data/autohotkey/tools/replay.ahk +104 -104
  141. data/autohotkey/tools/script_runner.ahk +589 -589
  142. data/autohotkey/tools/script_runner2.ahk +38 -38
  143. data/autohotkey/tools/table_manager.ahk +220 -220
  144. data/autohotkey/tools/test_runner.ahk +262 -262
  145. data/autohotkey/tools/test_runner2.ahk +53 -53
  146. data/autohotkey/tools/test_runner3.ahk +13 -13
  147. data/autohotkey/tools/test_runner5.ahk +8 -8
  148. data/autohotkey/tools/test_runner6.ahk +5 -5
  149. data/autohotkey/tools/tlm_extractor.ahk +296 -296
  150. data/autohotkey/tools/tlm_grapher.ahk +660 -660
  151. data/autohotkey/tools/tlm_grapher2.ahk +115 -115
  152. data/autohotkey/tools/tlm_grapher3.ahk +24 -24
  153. data/autohotkey/tools/tlm_viewer.ahk +133 -133
  154. data/autohotkey/tools/tlm_viewer2.ahk +50 -50
  155. data/autohotkey/tools/tlm_viewer4.ahk +4 -4
  156. data/autohotkey/tools/tlm_viewer5.ahk +20 -20
  157. data/bin/cosmos +96 -96
  158. data/bin/cstol_converter +1166 -1166
  159. data/bin/rubysloc +85 -85
  160. data/cosmos.gemspec +99 -99
  161. data/data/about.txt +4 -4
  162. data/data/crc.txt +326 -326
  163. data/data/diamond.STL +57 -57
  164. data/data/legal.txt +9 -9
  165. data/demo/Gemfile +10 -10
  166. data/demo/Launcher +16 -16
  167. data/demo/Launcher.bat +0 -0
  168. data/demo/Rakefile +77 -77
  169. data/demo/config/data/crc.txt +224 -226
  170. data/demo/config/data/diamond.STL +57 -57
  171. data/demo/config/data/meta_init.txt +4 -4
  172. data/demo/config/system/system.txt +35 -35
  173. data/demo/config/system/system2.txt +33 -33
  174. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  175. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  176. data/demo/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  177. data/demo/config/targets/COSMOS/screens/limits_change.txt +20 -20
  178. data/demo/config/targets/COSMOS/screens/version.txt +19 -19
  179. data/demo/config/targets/COSMOS/target.txt +11 -11
  180. data/demo/config/targets/EXAMPLE/cmd_tlm/example_cmds.txt +2 -2
  181. data/demo/config/targets/EXAMPLE/cmd_tlm/example_tlm.txt +5 -5
  182. data/demo/config/targets/EXAMPLE/cmd_tlm_server.txt +6 -6
  183. data/demo/config/targets/EXAMPLE/lib/example_interface.rb +22 -22
  184. data/demo/config/targets/EXAMPLE/target.txt +6 -6
  185. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  186. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +247 -247
  187. data/demo/config/targets/INST/cmd_tlm_server.txt +5 -5
  188. data/demo/config/targets/INST/lib/example_limits_response.rb +30 -30
  189. data/demo/config/targets/INST/lib/sim_inst.rb +305 -305
  190. data/demo/config/targets/INST/screens/adcs.txt +46 -46
  191. data/demo/config/targets/INST/screens/array.txt +15 -15
  192. data/demo/config/targets/INST/screens/block.txt +8 -8
  193. data/demo/config/targets/INST/screens/commanding.txt +30 -30
  194. data/demo/config/targets/INST/screens/graphs.txt +14 -14
  195. data/demo/config/targets/INST/screens/ground.txt +25 -25
  196. data/demo/config/targets/INST/screens/hs.txt +44 -44
  197. data/demo/config/targets/INST/screens/latest.txt +23 -23
  198. data/demo/config/targets/INST/screens/other.txt +29 -29
  199. data/demo/config/targets/INST/screens/tabs.txt +70 -70
  200. data/demo/config/targets/INST/target.txt +33 -33
  201. data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  202. data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +13 -13
  203. data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  204. data/demo/config/targets/SYSTEM/cmd_tlm/override.txt +29 -29
  205. data/demo/config/targets/SYSTEM/screens/status.txt +12 -12
  206. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_cmds.txt +13 -13
  207. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_tlm.txt +3 -3
  208. data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +6 -6
  209. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +56 -56
  210. data/demo/config/targets/TEMPLATED/target.txt +6 -6
  211. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +39 -39
  212. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +34 -34
  213. data/demo/config/tools/data_viewer/data_viewer.txt +11 -11
  214. data/demo/config/tools/handbook_creator/handbook_creator.txt +66 -66
  215. data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +88 -88
  216. data/demo/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  217. data/demo/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  218. data/demo/config/tools/handbook_creator/templates/header.html.erb +25 -25
  219. data/demo/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  220. data/demo/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  221. data/demo/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  222. data/demo/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  223. data/demo/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  224. data/demo/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  225. data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +82 -82
  226. data/demo/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  227. data/demo/config/tools/handbook_creator/templates/title.html.erb +1 -1
  228. data/demo/config/tools/launcher/launcher.txt +45 -45
  229. data/demo/config/tools/launcher/launcher2.txt +45 -45
  230. data/demo/config/tools/script_runner/script_runner.txt +3 -3
  231. data/demo/config/tools/table_manager/ConfigTables_def.txt +8 -8
  232. data/demo/config/tools/table_manager/ExampleTableDefinition.txt +24 -24
  233. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +25 -25
  234. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +25 -25
  235. data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -8
  236. data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +248 -248
  237. data/demo/config/tools/test_runner/test_runner.txt +17 -17
  238. data/demo/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  239. data/demo/config/tools/tlm_extractor/tlm_extractor2.txt +2 -2
  240. data/demo/config/tools/tlm_extractor/tlm_extractor3.txt +2 -2
  241. data/demo/config/tools/tlm_extractor/tlm_extractor4.txt +2 -2
  242. data/demo/config/tools/tlm_viewer/tlm_viewer.txt +41 -41
  243. data/demo/lib/example_background_task.rb +57 -57
  244. data/demo/lib/example_target.rb +113 -113
  245. data/demo/lib/scpi_target.rb +74 -74
  246. data/demo/lib/user_version.rb +3 -3
  247. data/demo/procedures/checks.rb +11 -11
  248. data/demo/procedures/clear_util.rb +7 -7
  249. data/demo/procedures/collect.rb +18 -18
  250. data/demo/procedures/collect_util.rb +14 -14
  251. data/demo/procedures/cosmos_api_test.rb +293 -293
  252. data/demo/procedures/disconnect.rb +29 -29
  253. data/demo/procedures/example_test.rb +183 -183
  254. data/demo/procedures/plot_test.rb +8 -8
  255. data/demo/procedures/run_example_test.rb +3 -3
  256. data/demo/procedures/test.rb +51 -51
  257. data/demo/tools/CmdExtractor +16 -16
  258. data/demo/tools/CmdExtractor.bat +0 -0
  259. data/demo/tools/CmdSender +16 -16
  260. data/demo/tools/CmdSender.bat +0 -0
  261. data/demo/tools/CmdTlmServer +16 -16
  262. data/demo/tools/CmdTlmServer.bat +0 -0
  263. data/demo/tools/DataViewer +16 -16
  264. data/demo/tools/DataViewer.bat +0 -0
  265. data/demo/tools/ExampleTarget +16 -16
  266. data/demo/tools/ExampleTarget.bat +0 -0
  267. data/demo/tools/HandbookCreator +16 -16
  268. data/demo/tools/HandbookCreator.bat +0 -0
  269. data/demo/tools/Launcher +16 -16
  270. data/demo/tools/Launcher.bat +0 -0
  271. data/demo/tools/LimitsMonitor +16 -16
  272. data/demo/tools/LimitsMonitor.bat +0 -0
  273. data/demo/tools/OpenGLBuilder +16 -16
  274. data/demo/tools/OpenGLBuilder.bat +0 -0
  275. data/demo/tools/PacketViewer +16 -16
  276. data/demo/tools/PacketViewer.bat +0 -0
  277. data/demo/tools/Replay +16 -16
  278. data/demo/tools/Replay.bat +0 -0
  279. data/demo/tools/ScpiTarget +16 -16
  280. data/demo/tools/ScpiTarget.bat +0 -0
  281. data/demo/tools/ScriptRunner +16 -16
  282. data/demo/tools/ScriptRunner.bat +0 -0
  283. data/demo/tools/TableManager +16 -16
  284. data/demo/tools/TableManager.bat +0 -0
  285. data/demo/tools/TestRunner +16 -16
  286. data/demo/tools/TestRunner.bat +0 -0
  287. data/demo/tools/TlmExtractor +16 -16
  288. data/demo/tools/TlmExtractor.bat +0 -0
  289. data/demo/tools/TlmGrapher +16 -16
  290. data/demo/tools/TlmGrapher.bat +0 -0
  291. data/demo/tools/TlmViewer +16 -16
  292. data/demo/tools/TlmViewer.bat +0 -0
  293. data/demo/tools/ToolLaunch.bat +14 -5
  294. data/demo/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  295. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +16 -16
  296. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +10 -10
  297. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  298. data/demo/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  299. data/demo/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +16 -16
  300. data/demo/tools/mac/CmdSender.app/Contents/MacOS/main.sh +10 -10
  301. data/demo/tools/mac/CmdSender.app/Contents/MacOS/tool_launch.rb +38 -38
  302. data/demo/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  303. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +16 -16
  304. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +10 -10
  305. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/tool_launch.rb +38 -38
  306. data/demo/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  307. data/demo/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +16 -16
  308. data/demo/tools/mac/DataViewer.app/Contents/MacOS/main.sh +10 -10
  309. data/demo/tools/mac/DataViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  310. data/demo/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  311. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +16 -16
  312. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +10 -10
  313. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/tool_launch.rb +38 -38
  314. data/demo/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  315. data/demo/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +16 -16
  316. data/demo/tools/mac/Launcher.app/Contents/MacOS/main.sh +10 -10
  317. data/demo/tools/mac/Launcher.app/Contents/MacOS/tool_launch.rb +38 -38
  318. data/demo/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  319. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +16 -16
  320. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +10 -10
  321. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/tool_launch.rb +38 -38
  322. data/demo/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  323. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +16 -16
  324. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +10 -10
  325. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/tool_launch.rb +38 -38
  326. data/demo/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  327. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +16 -16
  328. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +10 -10
  329. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  330. data/demo/tools/mac/Replay.app/Contents/Info.plist +38 -38
  331. data/demo/tools/mac/Replay.app/Contents/MacOS/Replay.rb +16 -16
  332. data/demo/tools/mac/Replay.app/Contents/MacOS/main.sh +10 -10
  333. data/demo/tools/mac/Replay.app/Contents/MacOS/tool_launch.rb +38 -38
  334. data/demo/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  335. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +16 -16
  336. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +10 -10
  337. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  338. data/demo/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  339. data/demo/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +16 -16
  340. data/demo/tools/mac/TableManager.app/Contents/MacOS/main.sh +10 -10
  341. data/demo/tools/mac/TableManager.app/Contents/MacOS/tool_launch.rb +38 -38
  342. data/demo/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  343. data/demo/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +16 -16
  344. data/demo/tools/mac/TestRunner.app/Contents/MacOS/main.sh +10 -10
  345. data/demo/tools/mac/TestRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  346. data/demo/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  347. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +16 -16
  348. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +10 -10
  349. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  350. data/demo/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  351. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +16 -16
  352. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +10 -10
  353. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/tool_launch.rb +38 -38
  354. data/demo/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  355. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +16 -16
  356. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +10 -10
  357. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  358. data/demo/tools/tool_launch.rb +38 -38
  359. data/ext/cosmos/ext/array/array.c +111 -111
  360. data/ext/cosmos/ext/array/extconf.rb +13 -13
  361. data/ext/cosmos/ext/buffered_file/buffered_file.c +167 -167
  362. data/ext/cosmos/ext/buffered_file/extconf.rb +13 -13
  363. data/ext/cosmos/ext/config_parser/config_parser.c +237 -237
  364. data/ext/cosmos/ext/config_parser/extconf.rb +13 -13
  365. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +117 -117
  366. data/ext/cosmos/ext/cosmos_io/extconf.rb +13 -13
  367. data/ext/cosmos/ext/crc/crc.c +341 -341
  368. data/ext/cosmos/ext/crc/extconf.rb +12 -12
  369. data/ext/cosmos/ext/line_graph/extconf.rb +13 -13
  370. data/ext/cosmos/ext/line_graph/line_graph.c +501 -501
  371. data/ext/cosmos/ext/low_fragmentation_array/extconf.rb +12 -12
  372. data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +265 -265
  373. data/ext/cosmos/ext/packet/extconf.rb +13 -13
  374. data/ext/cosmos/ext/packet/packet.c +339 -339
  375. data/ext/cosmos/ext/platform/extconf.rb +13 -13
  376. data/ext/cosmos/ext/platform/platform.c +101 -101
  377. data/ext/cosmos/ext/polynomial_conversion/extconf.rb +13 -13
  378. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +73 -73
  379. data/ext/cosmos/ext/string/extconf.rb +13 -13
  380. data/ext/cosmos/ext/string/string.c +49 -49
  381. data/ext/cosmos/ext/structure/structure.c +1428 -1428
  382. data/ext/cosmos/ext/tabbed_plots_config/extconf.rb +13 -13
  383. data/ext/cosmos/ext/tabbed_plots_config/tabbed_plots_config.c +51 -51
  384. data/ext/cosmos/ext/telemetry/extconf.rb +13 -13
  385. data/ext/cosmos/ext/telemetry/telemetry.c +307 -307
  386. data/ext/mkrf_conf.rb +40 -40
  387. data/install/Gemfile +10 -10
  388. data/install/Launcher +16 -16
  389. data/install/Launcher.bat +0 -0
  390. data/install/Rakefile +77 -77
  391. data/install/config/data/crc.txt +151 -151
  392. data/install/config/system/system.txt +29 -29
  393. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  394. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  395. data/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  396. data/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  397. data/install/config/targets/COSMOS/screens/version.txt +19 -19
  398. data/install/config/targets/COSMOS/target.txt +8 -8
  399. data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
  400. data/install/config/tools/data_viewer/data_viewer.txt +3 -3
  401. data/install/config/tools/handbook_creator/handbook_creator.txt +49 -49
  402. data/install/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  403. data/install/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  404. data/install/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  405. data/install/config/tools/handbook_creator/templates/header.html.erb +25 -25
  406. data/install/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  407. data/install/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  408. data/install/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  409. data/install/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  410. data/install/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  411. data/install/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  412. data/install/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  413. data/install/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  414. data/install/config/tools/handbook_creator/templates/title.html.erb +1 -1
  415. data/install/config/tools/launcher/launcher.txt +40 -40
  416. data/install/config/tools/script_runner/script_runner.txt +3 -3
  417. data/install/config/tools/test_runner/test_runner.txt +8 -8
  418. data/install/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
  419. data/install/lib/user_version.rb +3 -3
  420. data/install/tools/CmdExtractor +16 -16
  421. data/install/tools/CmdExtractor.bat +0 -0
  422. data/install/tools/CmdSender +16 -16
  423. data/install/tools/CmdSender.bat +0 -0
  424. data/install/tools/CmdTlmServer +16 -16
  425. data/install/tools/CmdTlmServer.bat +0 -0
  426. data/install/tools/DataViewer +16 -16
  427. data/install/tools/DataViewer.bat +0 -0
  428. data/install/tools/HandbookCreator +16 -16
  429. data/install/tools/HandbookCreator.bat +0 -0
  430. data/install/tools/Launcher +16 -16
  431. data/install/tools/Launcher.bat +0 -0
  432. data/install/tools/LimitsMonitor +16 -16
  433. data/install/tools/LimitsMonitor.bat +0 -0
  434. data/install/tools/OpenGLBuilder +16 -16
  435. data/install/tools/OpenGLBuilder.bat +0 -0
  436. data/install/tools/PacketViewer +16 -16
  437. data/install/tools/PacketViewer.bat +0 -0
  438. data/install/tools/Replay +16 -16
  439. data/install/tools/Replay.bat +0 -0
  440. data/install/tools/ScriptRunner +16 -16
  441. data/install/tools/ScriptRunner.bat +0 -0
  442. data/install/tools/TableManager +16 -16
  443. data/install/tools/TableManager.bat +0 -0
  444. data/install/tools/TestRunner +16 -16
  445. data/install/tools/TestRunner.bat +0 -0
  446. data/install/tools/TlmExtractor +16 -16
  447. data/install/tools/TlmExtractor.bat +0 -0
  448. data/install/tools/TlmGrapher +16 -16
  449. data/install/tools/TlmGrapher.bat +0 -0
  450. data/install/tools/TlmViewer +16 -16
  451. data/install/tools/TlmViewer.bat +0 -0
  452. data/install/tools/ToolLaunch.bat +14 -5
  453. data/install/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  454. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +16 -16
  455. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +10 -10
  456. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  457. data/install/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  458. data/install/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +16 -16
  459. data/install/tools/mac/CmdSender.app/Contents/MacOS/main.sh +10 -10
  460. data/install/tools/mac/CmdSender.app/Contents/MacOS/tool_launch.rb +38 -38
  461. data/install/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  462. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +16 -16
  463. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +10 -10
  464. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/tool_launch.rb +38 -38
  465. data/install/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  466. data/install/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +16 -16
  467. data/install/tools/mac/DataViewer.app/Contents/MacOS/main.sh +10 -10
  468. data/install/tools/mac/DataViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  469. data/install/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  470. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +16 -16
  471. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +10 -10
  472. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/tool_launch.rb +38 -38
  473. data/install/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  474. data/install/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +16 -16
  475. data/install/tools/mac/Launcher.app/Contents/MacOS/main.sh +10 -10
  476. data/install/tools/mac/Launcher.app/Contents/MacOS/tool_launch.rb +38 -38
  477. data/install/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  478. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +16 -16
  479. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +10 -10
  480. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/tool_launch.rb +38 -38
  481. data/install/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  482. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +16 -16
  483. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +10 -10
  484. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/tool_launch.rb +38 -38
  485. data/install/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  486. data/install/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +16 -16
  487. data/install/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +10 -10
  488. data/install/tools/mac/PacketViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  489. data/install/tools/mac/Replay.app/Contents/Info.plist +38 -38
  490. data/install/tools/mac/Replay.app/Contents/MacOS/Replay.rb +16 -16
  491. data/install/tools/mac/Replay.app/Contents/MacOS/main.sh +10 -10
  492. data/install/tools/mac/Replay.app/Contents/MacOS/tool_launch.rb +38 -38
  493. data/install/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  494. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +16 -16
  495. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +10 -10
  496. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  497. data/install/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  498. data/install/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +16 -16
  499. data/install/tools/mac/TableManager.app/Contents/MacOS/main.sh +10 -10
  500. data/install/tools/mac/TableManager.app/Contents/MacOS/tool_launch.rb +38 -38
  501. data/install/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  502. data/install/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +16 -16
  503. data/install/tools/mac/TestRunner.app/Contents/MacOS/main.sh +10 -10
  504. data/install/tools/mac/TestRunner.app/Contents/MacOS/tool_launch.rb +38 -38
  505. data/install/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  506. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +16 -16
  507. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +10 -10
  508. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/tool_launch.rb +38 -38
  509. data/install/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  510. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +16 -16
  511. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +10 -10
  512. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/tool_launch.rb +38 -38
  513. data/install/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  514. data/install/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +16 -16
  515. data/install/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +10 -10
  516. data/install/tools/mac/TlmViewer.app/Contents/MacOS/tool_launch.rb +38 -38
  517. data/install/tools/tool_launch.rb +38 -38
  518. data/lib/cosmos.rb +63 -63
  519. data/lib/cosmos/ccsds/ccsds_packet.rb +63 -63
  520. data/lib/cosmos/ccsds/ccsds_parser.rb +143 -143
  521. data/lib/cosmos/config/config_parser.rb +324 -324
  522. data/lib/cosmos/conversions.rb +13 -13
  523. data/lib/cosmos/conversions/conversion.rb +47 -47
  524. data/lib/cosmos/conversions/generic_conversion.rb +55 -55
  525. data/lib/cosmos/conversions/new_packet_log_conversion.rb +45 -45
  526. data/lib/cosmos/conversions/polynomial_conversion.rb +57 -57
  527. data/lib/cosmos/conversions/processor_conversion.rb +46 -46
  528. data/lib/cosmos/conversions/received_count_conversion.rb +33 -33
  529. data/lib/cosmos/conversions/received_time_formatted_conversion.rb +37 -37
  530. data/lib/cosmos/conversions/received_time_seconds_conversion.rb +37 -37
  531. data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +128 -128
  532. data/lib/cosmos/conversions/unix_time_conversion.rb +50 -50
  533. data/lib/cosmos/conversions/unix_time_formatted_conversion.rb +44 -44
  534. data/lib/cosmos/conversions/unix_time_seconds_conversion.rb +44 -44
  535. data/lib/cosmos/core_ext.rb +18 -18
  536. data/lib/cosmos/core_ext/array.rb +354 -354
  537. data/lib/cosmos/core_ext/class.rb +51 -51
  538. data/lib/cosmos/core_ext/cosmos_io.rb +29 -29
  539. data/lib/cosmos/core_ext/exception.rb +52 -52
  540. data/lib/cosmos/core_ext/file.rb +75 -75
  541. data/lib/cosmos/core_ext/hash.rb +28 -28
  542. data/lib/cosmos/core_ext/io.rb +75 -75
  543. data/lib/cosmos/core_ext/kernel.rb +38 -38
  544. data/lib/cosmos/core_ext/math.rb +119 -119
  545. data/lib/cosmos/core_ext/matrix.rb +146 -146
  546. data/lib/cosmos/core_ext/objectspace.rb +29 -29
  547. data/lib/cosmos/core_ext/range.rb +22 -22
  548. data/lib/cosmos/core_ext/socket.rb +32 -32
  549. data/lib/cosmos/core_ext/string.rb +311 -311
  550. data/lib/cosmos/core_ext/stringio.rb +24 -24
  551. data/lib/cosmos/core_ext/time.rb +448 -448
  552. data/lib/cosmos/gui/choosers/combobox_chooser.rb +130 -130
  553. data/lib/cosmos/gui/choosers/file_chooser.rb +68 -68
  554. data/lib/cosmos/gui/choosers/float_chooser.rb +82 -82
  555. data/lib/cosmos/gui/choosers/integer_chooser.rb +80 -80
  556. data/lib/cosmos/gui/choosers/string_chooser.rb +53 -53
  557. data/lib/cosmos/gui/choosers/telemetry_chooser.rb +326 -326
  558. data/lib/cosmos/gui/dialogs/about_dialog.rb +137 -137
  559. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +136 -136
  560. data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +52 -52
  561. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +149 -149
  562. data/lib/cosmos/gui/dialogs/details_dialog.rb +174 -174
  563. data/lib/cosmos/gui/dialogs/exception_dialog.rb +97 -97
  564. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +59 -59
  565. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +260 -260
  566. data/lib/cosmos/gui/dialogs/legal_dialog.rb +169 -169
  567. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +118 -118
  568. data/lib/cosmos/gui/dialogs/progress_dialog.rb +276 -276
  569. data/lib/cosmos/gui/dialogs/pry_dialog.rb +165 -165
  570. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +37 -37
  571. data/lib/cosmos/gui/dialogs/select_dialog.rb +54 -54
  572. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +131 -131
  573. data/lib/cosmos/gui/dialogs/splash.rb +135 -135
  574. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +206 -206
  575. data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +81 -81
  576. data/lib/cosmos/gui/line_graph/line_graph.rb +456 -456
  577. data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +34 -34
  578. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +473 -473
  579. data/lib/cosmos/gui/line_graph/line_graph_popups.rb +116 -116
  580. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +451 -451
  581. data/lib/cosmos/gui/line_graph/line_graph_script.rb +26 -26
  582. data/lib/cosmos/gui/line_graph/lines.rb +290 -290
  583. data/lib/cosmos/gui/line_graph/overview_graph.rb +469 -469
  584. data/lib/cosmos/gui/opengl/earth_model.rb +22 -22
  585. data/lib/cosmos/gui/opengl/gl_bounds.rb +67 -67
  586. data/lib/cosmos/gui/opengl/gl_light.rb +39 -39
  587. data/lib/cosmos/gui/opengl/gl_material.rb +29 -29
  588. data/lib/cosmos/gui/opengl/gl_scene.rb +72 -72
  589. data/lib/cosmos/gui/opengl/gl_shape.rb +146 -146
  590. data/lib/cosmos/gui/opengl/gl_viewer.rb +724 -724
  591. data/lib/cosmos/gui/opengl/gl_viewport.rb +35 -35
  592. data/lib/cosmos/gui/opengl/moon_model.rb +22 -22
  593. data/lib/cosmos/gui/opengl/opengl.rb +8 -8
  594. data/lib/cosmos/gui/opengl/stl_reader.rb +211 -211
  595. data/lib/cosmos/gui/opengl/stl_shape.rb +124 -124
  596. data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +202 -202
  597. data/lib/cosmos/gui/qt.rb +860 -860
  598. data/lib/cosmos/gui/qt_tool.rb +380 -380
  599. data/lib/cosmos/gui/text/completion.rb +381 -381
  600. data/lib/cosmos/gui/text/completion_line_edit.rb +30 -30
  601. data/lib/cosmos/gui/text/completion_text_edit.rb +179 -179
  602. data/lib/cosmos/gui/text/ruby_editor.rb +415 -415
  603. data/lib/cosmos/gui/utilities/screenshot.rb +25 -25
  604. data/lib/cosmos/gui/utilities/script_module_gui.rb +330 -330
  605. data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +161 -161
  606. data/lib/cosmos/gui/widgets/packet_log_frame.rb +305 -305
  607. data/lib/cosmos/gui/widgets/realtime_button_bar.rb +98 -98
  608. data/lib/cosmos/interfaces.rb +11 -11
  609. data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +153 -153
  610. data/lib/cosmos/interfaces/interface.rb +225 -225
  611. data/lib/cosmos/interfaces/linc_interface.rb +360 -360
  612. data/lib/cosmos/interfaces/serial_interface.rb +76 -76
  613. data/lib/cosmos/interfaces/simulated_target_interface.rb +129 -129
  614. data/lib/cosmos/interfaces/stream_interface.rb +136 -136
  615. data/lib/cosmos/interfaces/tcpip_client_interface.rb +60 -60
  616. data/lib/cosmos/interfaces/tcpip_server_interface.rb +164 -164
  617. data/lib/cosmos/interfaces/udp_interface.rb +161 -161
  618. data/lib/cosmos/io/buffered_file.rb +11 -11
  619. data/lib/cosmos/io/cosmos_snmp.rb +50 -50
  620. data/lib/cosmos/io/io_multiplexer.rb +89 -89
  621. data/lib/cosmos/io/json_drb.rb +376 -376
  622. data/lib/cosmos/io/json_drb_object.rb +198 -198
  623. data/lib/cosmos/io/json_rpc.rb +365 -365
  624. data/lib/cosmos/io/posix_serial_driver.rb +145 -145
  625. data/lib/cosmos/io/raw_logger.rb +174 -174
  626. data/lib/cosmos/io/raw_logger_pair.rb +71 -71
  627. data/lib/cosmos/io/serial_driver.rb +85 -85
  628. data/lib/cosmos/io/stderr.rb +36 -36
  629. data/lib/cosmos/io/stdout.rb +36 -36
  630. data/lib/cosmos/io/tcpip_server.rb +571 -571
  631. data/lib/cosmos/io/udp_sockets.rb +152 -152
  632. data/lib/cosmos/io/win32_serial_driver.rb +145 -145
  633. data/lib/cosmos/packet_logs.rb +7 -7
  634. data/lib/cosmos/packet_logs/ccsds_log_reader.rb +104 -104
  635. data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +107 -107
  636. data/lib/cosmos/packet_logs/packet_log_reader.rb +450 -450
  637. data/lib/cosmos/packet_logs/packet_log_writer.rb +323 -323
  638. data/lib/cosmos/packet_logs/packet_log_writer_pair.rb +30 -30
  639. data/lib/cosmos/packets/binary_accessor.rb +634 -634
  640. data/lib/cosmos/packets/commands.rb +293 -293
  641. data/lib/cosmos/packets/limits.rb +267 -267
  642. data/lib/cosmos/packets/limits_response.rb +38 -38
  643. data/lib/cosmos/packets/packet.rb +786 -786
  644. data/lib/cosmos/packets/packet_config.rb +482 -482
  645. data/lib/cosmos/packets/packet_item.rb +317 -317
  646. data/lib/cosmos/packets/packet_item_limits.rb +128 -128
  647. data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -58
  648. data/lib/cosmos/packets/parsers/limits_parser.rb +146 -146
  649. data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -52
  650. data/lib/cosmos/packets/parsers/macro_parser.rb +116 -116
  651. data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -215
  652. data/lib/cosmos/packets/parsers/packet_parser.rb +123 -123
  653. data/lib/cosmos/packets/parsers/processor_parser.rb +63 -63
  654. data/lib/cosmos/packets/parsers/state_parser.rb +116 -116
  655. data/lib/cosmos/packets/structure.rb +458 -458
  656. data/lib/cosmos/packets/structure_item.rb +233 -233
  657. data/lib/cosmos/packets/telemetry.rb +350 -350
  658. data/lib/cosmos/processors.rb +6 -6
  659. data/lib/cosmos/processors/new_packet_log_processor.rb +34 -34
  660. data/lib/cosmos/processors/processor.rb +71 -71
  661. data/lib/cosmos/processors/statistics_processor.rb +65 -65
  662. data/lib/cosmos/processors/watermark_processor.rb +44 -44
  663. data/lib/cosmos/script.rb +9 -9
  664. data/lib/cosmos/script/cmd_tlm_server.rb +110 -110
  665. data/lib/cosmos/script/commands.rb +184 -184
  666. data/lib/cosmos/script/extract.rb +123 -123
  667. data/lib/cosmos/script/limits.rb +114 -114
  668. data/lib/cosmos/script/script.rb +76 -76
  669. data/lib/cosmos/script/scripting.rb +897 -897
  670. data/lib/cosmos/script/telemetry.rb +174 -174
  671. data/lib/cosmos/script/tools.rb +138 -138
  672. data/lib/cosmos/streams/burst_stream_protocol.rb +25 -25
  673. data/lib/cosmos/streams/fixed_stream_protocol.rb +111 -111
  674. data/lib/cosmos/streams/length_stream_protocol.rb +140 -140
  675. data/lib/cosmos/streams/preidentified_stream_protocol.rb +118 -118
  676. data/lib/cosmos/streams/serial_stream.rb +157 -157
  677. data/lib/cosmos/streams/stream.rb +63 -63
  678. data/lib/cosmos/streams/stream_protocol.rb +373 -373
  679. data/lib/cosmos/streams/tcpip_client_stream.rb +113 -113
  680. data/lib/cosmos/streams/tcpip_socket_stream.rb +143 -143
  681. data/lib/cosmos/streams/template_stream_protocol.rb +140 -140
  682. data/lib/cosmos/streams/terminated_stream_protocol.rb +81 -81
  683. data/lib/cosmos/system.rb +4 -4
  684. data/lib/cosmos/system/system.rb +618 -618
  685. data/lib/cosmos/system/target.rb +197 -197
  686. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +255 -255
  687. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +717 -717
  688. data/lib/cosmos/tools/cmd_sender/cmd_sender_item_delegate.rb +77 -77
  689. data/lib/cosmos/tools/cmd_sender/cmd_sender_text_edit.rb +70 -70
  690. data/lib/cosmos/tools/cmd_tlm_server/api.rb +1034 -1034
  691. data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +46 -46
  692. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +67 -67
  693. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +515 -515
  694. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +253 -253
  695. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +408 -408
  696. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +112 -112
  697. data/lib/cosmos/tools/cmd_tlm_server/connections.rb +175 -175
  698. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +200 -200
  699. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +176 -176
  700. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +150 -150
  701. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +244 -244
  702. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +90 -90
  703. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +266 -266
  704. data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +127 -127
  705. data/lib/cosmos/tools/cmd_tlm_server/packet_logging.rb +132 -132
  706. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +66 -66
  707. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +97 -97
  708. data/lib/cosmos/tools/data_viewer/data_viewer.rb +621 -621
  709. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +134 -134
  710. data/lib/cosmos/tools/data_viewer/dump_component.rb +40 -40
  711. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +156 -156
  712. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +382 -382
  713. data/lib/cosmos/tools/launcher/launcher.rb +188 -188
  714. data/lib/cosmos/tools/launcher/launcher_config.rb +256 -256
  715. data/lib/cosmos/tools/launcher/launcher_multitool.rb +40 -40
  716. data/lib/cosmos/tools/launcher/launcher_tool.rb +116 -116
  717. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +837 -837
  718. data/lib/cosmos/tools/opengl_builder/opengl_builder.rb +416 -416
  719. data/lib/cosmos/tools/opengl_builder/scene_config.rb +118 -118
  720. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +542 -542
  721. data/lib/cosmos/tools/replay/replay.rb +501 -501
  722. data/lib/cosmos/tools/replay/replay_server.rb +91 -91
  723. data/lib/cosmos/tools/script_runner/script_audit.rb +147 -147
  724. data/lib/cosmos/tools/script_runner/script_runner.rb +922 -922
  725. data/lib/cosmos/tools/script_runner/script_runner_config.rb +40 -40
  726. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +1798 -1798
  727. data/lib/cosmos/tools/table_manager/table.rb +70 -70
  728. data/lib/cosmos/tools/table_manager/table_config.rb +764 -764
  729. data/lib/cosmos/tools/table_manager/table_item.rb +74 -74
  730. data/lib/cosmos/tools/table_manager/table_manager.rb +1065 -1065
  731. data/lib/cosmos/tools/table_manager/table_manager_core.rb +539 -539
  732. data/lib/cosmos/tools/test_runner/results_writer.rb +283 -283
  733. data/lib/cosmos/tools/test_runner/test.rb +539 -539
  734. data/lib/cosmos/tools/test_runner/test_runner.rb +1189 -1189
  735. data/lib/cosmos/tools/test_runner/test_runner_chooser.rb +341 -341
  736. data/lib/cosmos/tools/tlm_extractor/text_item_chooser.rb +60 -60
  737. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +1016 -1016
  738. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +371 -371
  739. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +60 -60
  740. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +75 -75
  741. data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +44 -44
  742. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +95 -95
  743. data/lib/cosmos/tools/tlm_grapher/data_object_editors/data_object_editor.rb +61 -61
  744. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +181 -181
  745. data/lib/cosmos/tools/tlm_grapher/data_object_editors/linegraph_data_object_editor.rb +141 -141
  746. data/lib/cosmos/tools/tlm_grapher/data_object_editors/singlexy_data_object_editor.rb +30 -30
  747. data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +174 -174
  748. data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +193 -193
  749. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +407 -407
  750. data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +176 -176
  751. data/lib/cosmos/tools/tlm_grapher/data_objects/singlexy_data_object.rb +25 -25
  752. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +323 -323
  753. data/lib/cosmos/tools/tlm_grapher/plot_editors/linegraph_plot_editor.rb +181 -181
  754. data/lib/cosmos/tools/tlm_grapher/plot_editors/plot_editor.rb +28 -28
  755. data/lib/cosmos/tools/tlm_grapher/plot_editors/singlexy_plot_editor.rb +30 -30
  756. data/lib/cosmos/tools/tlm_grapher/plot_editors/xy_plot_editor.rb +59 -59
  757. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/linegraph_plot_gui_object.rb +172 -172
  758. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/singlexy_plot_gui_object.rb +27 -27
  759. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/xy_plot_gui_object.rb +74 -74
  760. data/lib/cosmos/tools/tlm_grapher/plots/linegraph_plot.rb +201 -201
  761. data/lib/cosmos/tools/tlm_grapher/plots/plot.rb +69 -69
  762. data/lib/cosmos/tools/tlm_grapher/plots/singlexy_plot.rb +20 -20
  763. data/lib/cosmos/tools/tlm_grapher/plots/xy_plot.rb +61 -61
  764. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1291 -1291
  765. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +430 -430
  766. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_data_object_editor.rb +107 -107
  767. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_logfile_thread.rb +114 -114
  768. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +101 -101
  769. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +78 -78
  770. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tab.rb +57 -57
  771. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1004 -1004
  772. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +87 -87
  773. data/lib/cosmos/tools/tlm_viewer/screen.rb +486 -486
  774. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +561 -561
  775. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +290 -290
  776. data/lib/cosmos/tools/tlm_viewer/widgets.rb +53 -53
  777. data/lib/cosmos/tools/tlm_viewer/widgets/aging_widget.rb +110 -110
  778. data/lib/cosmos/tools/tlm_viewer/widgets/array_widget.rb +66 -66
  779. data/lib/cosmos/tools/tlm_viewer/widgets/block_widget.rb +57 -57
  780. data/lib/cosmos/tools/tlm_viewer/widgets/button_widget.rb +39 -39
  781. data/lib/cosmos/tools/tlm_viewer/widgets/canvas_widget.rb +62 -62
  782. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimage_widget.rb +41 -41
  783. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimagevalue_widget.rb +57 -57
  784. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabel_widget.rb +37 -37
  785. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabelvalue_widget.rb +56 -56
  786. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +55 -55
  787. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +66 -66
  788. data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +124 -124
  789. data/lib/cosmos/tools/tlm_viewer/widgets/checkbutton_widget.rb +31 -31
  790. data/lib/cosmos/tools/tlm_viewer/widgets/combobox_widget.rb +30 -30
  791. data/lib/cosmos/tools/tlm_viewer/widgets/formatfontvalue_widget.rb +36 -36
  792. data/lib/cosmos/tools/tlm_viewer/widgets/formatvalue_widget.rb +35 -35
  793. data/lib/cosmos/tools/tlm_viewer/widgets/horizontal_widget.rb +27 -27
  794. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalbox_widget.rb +31 -31
  795. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalline_widget.rb +26 -26
  796. data/lib/cosmos/tools/tlm_viewer/widgets/label_widget.rb +29 -29
  797. data/lib/cosmos/tools/tlm_viewer/widgets/labelformatvalue_widget.rb +39 -39
  798. data/lib/cosmos/tools/tlm_viewer/widgets/labelprogressbar_widget.rb +38 -38
  799. data/lib/cosmos/tools/tlm_viewer/widgets/labeltrendlimitsbar_widget.rb +38 -38
  800. data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +39 -39
  801. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluedesc_widget.rb +42 -42
  802. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluelimitsbar_widget.rb +37 -37
  803. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluerangebar_widget.rb +37 -37
  804. data/lib/cosmos/tools/tlm_viewer/widgets/layout_widget.rb +34 -34
  805. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +178 -178
  806. data/lib/cosmos/tools/tlm_viewer/widgets/linegraph_widget.rb +54 -54
  807. data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +47 -47
  808. data/lib/cosmos/tools/tlm_viewer/widgets/multi_widget.rb +116 -116
  809. data/lib/cosmos/tools/tlm_viewer/widgets/progressbar_widget.rb +34 -34
  810. data/lib/cosmos/tools/tlm_viewer/widgets/radiobutton_widget.rb +30 -30
  811. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +57 -57
  812. data/lib/cosmos/tools/tlm_viewer/widgets/screenshotbutton_widget.rb +34 -34
  813. data/lib/cosmos/tools/tlm_viewer/widgets/scrollwindow_widget.rb +35 -35
  814. data/lib/cosmos/tools/tlm_viewer/widgets/sectionheader_widget.rb +33 -33
  815. data/lib/cosmos/tools/tlm_viewer/widgets/tabbook_widget.rb +26 -26
  816. data/lib/cosmos/tools/tlm_viewer/widgets/tabitem_widget.rb +28 -28
  817. data/lib/cosmos/tools/tlm_viewer/widgets/textbox_widget.rb +47 -47
  818. data/lib/cosmos/tools/tlm_viewer/widgets/textfield_widget.rb +26 -26
  819. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +88 -88
  820. data/lib/cosmos/tools/tlm_viewer/widgets/title_widget.rb +27 -27
  821. data/lib/cosmos/tools/tlm_viewer/widgets/trendbar_widget.rb +130 -130
  822. data/lib/cosmos/tools/tlm_viewer/widgets/trendlimitsbar_widget.rb +46 -46
  823. data/lib/cosmos/tools/tlm_viewer/widgets/value_widget.rb +43 -43
  824. data/lib/cosmos/tools/tlm_viewer/widgets/valuelimitsbar_widget.rb +37 -37
  825. data/lib/cosmos/tools/tlm_viewer/widgets/valuerangebar_widget.rb +37 -37
  826. data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +35 -35
  827. data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +37 -37
  828. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +257 -257
  829. data/lib/cosmos/top_level.rb +759 -759
  830. data/lib/cosmos/utilities.rb +11 -11
  831. data/lib/cosmos/utilities/crc.rb +166 -166
  832. data/lib/cosmos/utilities/csv.rb +83 -83
  833. data/lib/cosmos/utilities/logger.rb +137 -137
  834. data/lib/cosmos/utilities/low_fragmentation_array.rb +11 -11
  835. data/lib/cosmos/utilities/message_log.rb +79 -79
  836. data/lib/cosmos/utilities/quaternion.rb +258 -258
  837. data/lib/cosmos/utilities/ruby_lex_utils.rb +313 -313
  838. data/lib/cosmos/utilities/simulated_target.rb +99 -99
  839. data/lib/cosmos/utilities/sleeper.rb +44 -44
  840. data/lib/cosmos/version.rb +12 -12
  841. data/lib/cosmos/win32/excel.rb +66 -66
  842. data/lib/cosmos/win32/win32.rb +387 -387
  843. data/lib/cosmos/win32/win32_main.rb +321 -321
  844. data/roodi.yml +24 -24
  845. data/run_gui_tests.bat +0 -0
  846. data/spec/ccsds/ccsds_packet_spec.rb +67 -67
  847. data/spec/ccsds/ccsds_parser_spec.rb +148 -148
  848. data/spec/config/config_parser_spec.rb +322 -322
  849. data/spec/conversions/conversion_spec.rb +31 -31
  850. data/spec/conversions/generic_conversion_spec.rb +45 -45
  851. data/spec/conversions/new_packet_log_conversion_spec.rb +39 -39
  852. data/spec/conversions/polynomial_conversion_spec.rb +40 -40
  853. data/spec/conversions/processor_conversion_spec.rb +45 -45
  854. data/spec/conversions/received_count_conversion_spec.rb +43 -43
  855. data/spec/conversions/received_time_formatted_conversion_spec.rb +49 -49
  856. data/spec/conversions/received_time_seconds_conversion_spec.rb +50 -50
  857. data/spec/conversions/segmented_polynomial_conversion_spec.rb +51 -51
  858. data/spec/conversions/unix_time_formatted_conversion_spec.rb +74 -74
  859. data/spec/conversions/unix_time_seconds_conversion_spec.rb +76 -76
  860. data/spec/core_ext/array_spec.rb +186 -186
  861. data/spec/core_ext/class_spec.rb +36 -36
  862. data/spec/core_ext/cosmos_io_spec.rb +77 -77
  863. data/spec/core_ext/exception_spec.rb +91 -91
  864. data/spec/core_ext/file_spec.rb +72 -72
  865. data/spec/core_ext/hash_spec.rb +24 -24
  866. data/spec/core_ext/io_spec.rb +46 -46
  867. data/spec/core_ext/kernel_spec.rb +54 -54
  868. data/spec/core_ext/math_spec.rb +116 -116
  869. data/spec/core_ext/matrix_spec.rb +66 -66
  870. data/spec/core_ext/objectspace_spec.rb +29 -29
  871. data/spec/core_ext/range_spec.rb +21 -21
  872. data/spec/core_ext/socket_spec.rb +32 -32
  873. data/spec/core_ext/string_spec.rb +223 -223
  874. data/spec/core_ext/stringio_spec.rb +21 -21
  875. data/spec/core_ext/time_spec.rb +202 -202
  876. data/spec/gui/line_graph/line_clip_spec.rb +322 -322
  877. data/spec/gui/qt_spec.rb +102 -102
  878. data/spec/install/config/system/system.txt +33 -33
  879. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  880. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  881. data/spec/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  882. data/spec/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  883. data/spec/install/config/targets/COSMOS/screens/version.txt +19 -19
  884. data/spec/install/config/targets/COSMOS/target.txt +5 -5
  885. data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +30 -30
  886. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +111 -111
  887. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm.txt +236 -236
  888. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +25 -25
  889. data/spec/install/config/targets/INST/cmd_tlm_server.txt +5 -5
  890. data/spec/install/config/targets/INST/lib/sim_inst.rb +305 -305
  891. data/spec/install/config/targets/INST/target.txt +10 -10
  892. data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +4 -4
  893. data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +4 -4
  894. data/spec/install/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  895. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +150 -150
  896. data/spec/interfaces/interface_spec.rb +130 -130
  897. data/spec/interfaces/linc_interface_spec.rb +259 -259
  898. data/spec/interfaces/serial_interface_spec.rb +56 -56
  899. data/spec/interfaces/simulated_target_interface_spec.rb +128 -128
  900. data/spec/interfaces/stream_interface_spec.rb +157 -157
  901. data/spec/interfaces/tcpip_client_interface_spec.rb +55 -55
  902. data/spec/interfaces/tcpip_server_interface_spec.rb +160 -160
  903. data/spec/interfaces/udp_interface_spec.rb +175 -175
  904. data/spec/io/buffered_file_spec.rb +113 -113
  905. data/spec/io/io_multiplexer_spec.rb +94 -94
  906. data/spec/io/json_drb_object_spec.rb +119 -119
  907. data/spec/io/json_drb_spec.rb +311 -311
  908. data/spec/io/json_rpc_spec.rb +264 -264
  909. data/spec/io/raw_logger_pair_spec.rb +76 -76
  910. data/spec/io/raw_logger_spec.rb +133 -133
  911. data/spec/io/serial_driver_spec.rb +60 -60
  912. data/spec/io/stderr_spec.rb +32 -32
  913. data/spec/io/stdout_spec.rb +32 -32
  914. data/spec/io/tcpip_server_spec.rb +338 -338
  915. data/spec/io/udp_sockets_spec.rb +94 -94
  916. data/spec/io/win32_serial_driver_spec.rb +88 -88
  917. data/spec/packet_logs/meta_packet_log_writer_spec.rb +170 -170
  918. data/spec/packet_logs/packet_log_reader_spec.rb +468 -468
  919. data/spec/packet_logs/packet_log_writer_pair_spec.rb +30 -30
  920. data/spec/packet_logs/packet_log_writer_spec.rb +225 -225
  921. data/spec/packets/binary_accessor_spec.rb +2326 -2326
  922. data/spec/packets/commands_spec.rb +369 -369
  923. data/spec/packets/limits_response_spec.rb +25 -25
  924. data/spec/packets/limits_spec.rb +344 -344
  925. data/spec/packets/packet_config_spec.rb +805 -805
  926. data/spec/packets/packet_item_limits_spec.rb +161 -161
  927. data/spec/packets/packet_item_spec.rb +386 -386
  928. data/spec/packets/packet_spec.rb +1317 -1317
  929. data/spec/packets/parsers/format_string_parser_spec.rb +122 -122
  930. data/spec/packets/parsers/limits_parser_spec.rb +282 -282
  931. data/spec/packets/parsers/limits_response_parser_spec.rb +149 -149
  932. data/spec/packets/parsers/macro_parser_spec.rb +212 -212
  933. data/spec/packets/parsers/packet_item_parser_spec.rb +306 -306
  934. data/spec/packets/parsers/packet_parser_spec.rb +99 -99
  935. data/spec/packets/parsers/processor_parser_spec.rb +114 -114
  936. data/spec/packets/parsers/state_parser_spec.rb +156 -156
  937. data/spec/packets/structure_item_spec.rb +195 -195
  938. data/spec/packets/structure_spec.rb +565 -565
  939. data/spec/packets/telemetry_spec.rb +578 -578
  940. data/spec/processors/new_packet_log_processor_spec.rb +39 -39
  941. data/spec/processors/processor_spec.rb +55 -55
  942. data/spec/processors/statistics_processor_spec.rb +60 -60
  943. data/spec/processors/watermark_processor_spec.rb +51 -51
  944. data/spec/script/cmd_tlm_server_spec.rb +110 -110
  945. data/spec/script/commands_disconnect_spec.rb +270 -270
  946. data/spec/script/commands_spec.rb +302 -302
  947. data/spec/script/limits_spec.rb +153 -153
  948. data/spec/script/script_spec.rb +86 -86
  949. data/spec/script/scripting_spec.rb +440 -440
  950. data/spec/script/telemetry_spec.rb +165 -165
  951. data/spec/script/tools_spec.rb +117 -117
  952. data/spec/spec_helper.rb +190 -190
  953. data/spec/streams/burst_stream_protocol_spec.rb +32 -32
  954. data/spec/streams/fixed_stream_protocol_spec.rb +113 -113
  955. data/spec/streams/length_stream_protocol_spec.rb +300 -300
  956. data/spec/streams/preidentified_stream_protocol_spec.rb +121 -121
  957. data/spec/streams/serial_stream_spec.rb +117 -117
  958. data/spec/streams/stream_protocol_spec.rb +346 -346
  959. data/spec/streams/stream_spec.rb +30 -30
  960. data/spec/streams/tcpip_client_stream_spec.rb +57 -57
  961. data/spec/streams/tcpip_socket_stream_spec.rb +193 -193
  962. data/spec/streams/template_stream_protocol_spec.rb +156 -156
  963. data/spec/streams/terminated_stream_protocol_spec.rb +127 -127
  964. data/spec/system/system_spec.rb +665 -665
  965. data/spec/system/target_spec.rb +250 -250
  966. data/spec/tools/cmd_tlm_server/api_spec.rb +1117 -1117
  967. data/spec/tools/cmd_tlm_server/background_task_spec.rb +32 -32
  968. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +81 -81
  969. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +453 -453
  970. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +415 -415
  971. data/spec/tools/cmd_tlm_server/commanding_spec.rb +151 -151
  972. data/spec/tools/cmd_tlm_server/connections_spec.rb +235 -235
  973. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +306 -306
  974. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +252 -252
  975. data/spec/tools/cmd_tlm_server/packet_logging_spec.rb +143 -143
  976. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +151 -151
  977. data/spec/tools/cmd_tlm_server/routers_spec.rb +223 -223
  978. data/spec/tools/launcher/launcher_config_spec.rb +464 -464
  979. data/spec/top_level/top_level_spec.rb +334 -334
  980. data/spec/utilities/crc_spec.rb +45 -45
  981. data/spec/utilities/csv_spec.rb +97 -97
  982. data/spec/utilities/logger_spec.rb +102 -102
  983. data/spec/utilities/message_log_spec.rb +89 -89
  984. data/spec/utilities/quaternion_spec.rb +107 -107
  985. data/spec/utilities/ruby_lex_utils_spec.rb +86 -86
  986. data/tasks/manifest.rake +22 -22
  987. data/tasks/spec.rake +23 -23
  988. data/test/benchmarks/binary_accessor_benchmark.rb +14 -14
  989. data/test/benchmarks/gsub_benchmark.rb +152 -152
  990. data/test/benchmarks/is_a_benchmark.rb +34 -34
  991. data/test/performance/PACKETS.bat +0 -0
  992. data/test/performance/Rakefile +77 -77
  993. data/test/performance/THREADS.bat +0 -0
  994. data/test/performance/config/data/crc.txt +196 -196
  995. data/test/performance/config/data/diamond.STL +57 -57
  996. data/test/performance/config/data/meta_init.txt +4 -4
  997. data/test/performance/config/system/system_packets.txt +39 -39
  998. data/test/performance/config/system/system_threads.txt +59 -59
  999. data/test/performance/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +46 -46
  1000. data/test/performance/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  1001. data/test/performance/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  1002. data/test/performance/config/targets/COSMOS/screens/limits_change.txt +20 -20
  1003. data/test/performance/config/targets/COSMOS/screens/version.txt +19 -19
  1004. data/test/performance/config/targets/COSMOS/target.txt +11 -11
  1005. data/test/performance/config/targets/PACKET/cmd_tlm/packet_cmds.txt +20 -20
  1006. data/test/performance/config/targets/PACKET/cmd_tlm/packet_tlm.txt +98 -98
  1007. data/test/performance/config/targets/PACKET/cmd_tlm_server.txt +6 -6
  1008. data/test/performance/config/targets/PACKET/lib/packet_interface.rb +22 -22
  1009. data/test/performance/config/targets/PACKET/lib/packet_limits_response.rb +24 -24
  1010. data/test/performance/config/targets/PACKET/screens/status.txt +25 -25
  1011. data/test/performance/config/targets/PACKET/target.txt +28 -28
  1012. data/test/performance/config/targets/SYSTEM/screens/status.txt +12 -12
  1013. data/test/performance/config/targets/THREAD/cmd_tlm/thread_cmds.txt +17 -17
  1014. data/test/performance/config/targets/THREAD/cmd_tlm/thread_tlm.txt +18 -18
  1015. data/test/performance/config/targets/THREAD/cmd_tlm_server.txt +6 -6
  1016. data/test/performance/config/targets/THREAD/lib/thread_interface.rb +22 -22
  1017. data/test/performance/config/targets/THREAD/screens/status.txt +25 -25
  1018. data/test/performance/config/targets/THREAD/target.txt +6 -6
  1019. data/test/performance/config/tools/cmd_tlm_server/cmd_tlm_server_packets.txt +28 -28
  1020. data/test/performance/config/tools/cmd_tlm_server/cmd_tlm_server_threads.txt +68 -68
  1021. data/test/performance/config/tools/data_viewer/data_viewer.txt +11 -11
  1022. data/test/performance/config/tools/handbook_creator/handbook_creator.txt +66 -66
  1023. data/test/performance/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  1024. data/test/performance/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  1025. data/test/performance/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  1026. data/test/performance/config/tools/handbook_creator/templates/header.html.erb +25 -25
  1027. data/test/performance/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  1028. data/test/performance/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  1029. data/test/performance/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  1030. data/test/performance/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  1031. data/test/performance/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  1032. data/test/performance/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  1033. data/test/performance/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  1034. data/test/performance/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  1035. data/test/performance/config/tools/handbook_creator/templates/title.html.erb +1 -1
  1036. data/test/performance/config/tools/launcher/launcher_packets.txt +34 -34
  1037. data/test/performance/config/tools/launcher/launcher_threads.txt +83 -83
  1038. data/test/performance/config/tools/script_runner/script_runner.txt +3 -3
  1039. data/test/performance/config/tools/table_manager/ConfigTables_def.txt +8 -8
  1040. data/test/performance/config/tools/table_manager/ExampleTableDefinition.txt +24 -24
  1041. data/test/performance/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +25 -25
  1042. data/test/performance/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +25 -25
  1043. data/test/performance/config/tools/table_manager/PPSSelectionTable_def.txt +8 -8
  1044. data/test/performance/config/tools/table_manager/TLMMonitoringTable_def.txt +248 -248
  1045. data/test/performance/config/tools/test_runner/test_runner.txt +17 -17
  1046. data/test/performance/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  1047. data/test/performance/config/tools/tlm_extractor/tlm_extractor2.txt +2 -2
  1048. data/test/performance/config/tools/tlm_extractor/tlm_extractor3.txt +2 -2
  1049. data/test/performance/config/tools/tlm_extractor/tlm_extractor4.txt +2 -2
  1050. data/test/performance/config/tools/tlm_grapher/tlm_grapher.txt +204 -204
  1051. data/test/performance/config/tools/tlm_viewer/tlm_viewer.txt +13 -13
  1052. data/test/performance/lib/packet_target.rb +126 -126
  1053. data/test/performance/lib/thread_target.rb +120 -120
  1054. data/test/performance/lib/user_version.rb +3 -3
  1055. data/test/performance/procedures/checks.rb +11 -11
  1056. data/test/performance/procedures/clear_util.rb +7 -7
  1057. data/test/performance/procedures/collect.rb +18 -18
  1058. data/test/performance/procedures/collect_util.rb +14 -14
  1059. data/test/performance/procedures/cosmos_api_test.rb +293 -293
  1060. data/test/performance/procedures/disconnect.rb +29 -29
  1061. data/test/performance/procedures/example_test.rb +182 -182
  1062. data/test/performance/procedures/plot_test.rb +8 -8
  1063. data/test/performance/procedures/procedure.rb +2 -2
  1064. data/test/performance/procedures/run_example_test.rb +3 -3
  1065. data/test/performance/procedures/test.rb +51 -51
  1066. data/test/performance/tools/CmdExtractor +14 -14
  1067. data/test/performance/tools/CmdExtractor.bat +0 -0
  1068. data/test/performance/tools/CmdSender +14 -14
  1069. data/test/performance/tools/CmdSender.bat +0 -0
  1070. data/test/performance/tools/CmdTlmServer +16 -16
  1071. data/test/performance/tools/CmdTlmServer.bat +0 -0
  1072. data/test/performance/tools/CmdTlmServerMemProf +20 -20
  1073. data/test/performance/tools/CmdTlmServerMemProf.bat +0 -0
  1074. data/test/performance/tools/DataViewer +14 -14
  1075. data/test/performance/tools/DataViewer.bat +0 -0
  1076. data/test/performance/tools/HandbookCreator +14 -14
  1077. data/test/performance/tools/HandbookCreator.bat +0 -0
  1078. data/test/performance/tools/Launcher +14 -14
  1079. data/test/performance/tools/Launcher.bat +0 -0
  1080. data/test/performance/tools/LimitsMonitor +14 -14
  1081. data/test/performance/tools/LimitsMonitor.bat +0 -0
  1082. data/test/performance/tools/OpenGLBuilder +14 -14
  1083. data/test/performance/tools/OpenGLBuilder.bat +0 -0
  1084. data/test/performance/tools/PacketTarget +14 -14
  1085. data/test/performance/tools/PacketTarget.bat +0 -0
  1086. data/test/performance/tools/PacketViewer +14 -14
  1087. data/test/performance/tools/PacketViewer.bat +0 -0
  1088. data/test/performance/tools/Replay +14 -14
  1089. data/test/performance/tools/Replay.bat +0 -0
  1090. data/test/performance/tools/ScpiTarget +14 -14
  1091. data/test/performance/tools/ScpiTarget.bat +0 -0
  1092. data/test/performance/tools/ScriptRunner +14 -14
  1093. data/test/performance/tools/ScriptRunner.bat +0 -0
  1094. data/test/performance/tools/TableManager +14 -14
  1095. data/test/performance/tools/TableManager.bat +0 -0
  1096. data/test/performance/tools/TestRunner +14 -14
  1097. data/test/performance/tools/TestRunner.bat +0 -0
  1098. data/test/performance/tools/ThreadTarget +14 -14
  1099. data/test/performance/tools/ThreadTarget.bat +0 -0
  1100. data/test/performance/tools/TlmExtractor +14 -14
  1101. data/test/performance/tools/TlmExtractor.bat +0 -0
  1102. data/test/performance/tools/TlmGrapher +14 -14
  1103. data/test/performance/tools/TlmGrapher.bat +0 -0
  1104. data/test/performance/tools/TlmGrapherMemProf +19 -19
  1105. data/test/performance/tools/TlmGrapherMemProf.bat +0 -0
  1106. data/test/performance/tools/TlmViewer +14 -14
  1107. data/test/performance/tools/TlmViewer.bat +0 -0
  1108. data/test/performance/tools/TlmViewerMemProf +19 -19
  1109. data/test/performance/tools/TlmViewerMemProf.bat +0 -0
  1110. data/test/performance/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  1111. data/test/performance/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +15 -15
  1112. data/test/performance/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +6 -6
  1113. data/test/performance/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  1114. data/test/performance/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +15 -15
  1115. data/test/performance/tools/mac/CmdSender.app/Contents/MacOS/main.sh +6 -6
  1116. data/test/performance/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  1117. data/test/performance/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +15 -15
  1118. data/test/performance/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +6 -6
  1119. data/test/performance/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  1120. data/test/performance/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +15 -15
  1121. data/test/performance/tools/mac/DataViewer.app/Contents/MacOS/main.sh +6 -6
  1122. data/test/performance/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  1123. data/test/performance/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +15 -15
  1124. data/test/performance/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +6 -6
  1125. data/test/performance/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  1126. data/test/performance/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +15 -15
  1127. data/test/performance/tools/mac/Launcher.app/Contents/MacOS/main.sh +6 -6
  1128. data/test/performance/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  1129. data/test/performance/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +15 -15
  1130. data/test/performance/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +6 -6
  1131. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  1132. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +15 -15
  1133. data/test/performance/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +6 -6
  1134. data/test/performance/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  1135. data/test/performance/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +15 -15
  1136. data/test/performance/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +6 -6
  1137. data/test/performance/tools/mac/Replay.app/Contents/Info.plist +38 -38
  1138. data/test/performance/tools/mac/Replay.app/Contents/MacOS/Replay.rb +15 -15
  1139. data/test/performance/tools/mac/Replay.app/Contents/MacOS/main.sh +6 -6
  1140. data/test/performance/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  1141. data/test/performance/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +15 -15
  1142. data/test/performance/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +6 -6
  1143. data/test/performance/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  1144. data/test/performance/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +15 -15
  1145. data/test/performance/tools/mac/TableManager.app/Contents/MacOS/main.sh +6 -6
  1146. data/test/performance/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  1147. data/test/performance/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +15 -15
  1148. data/test/performance/tools/mac/TestRunner.app/Contents/MacOS/main.sh +6 -6
  1149. data/test/performance/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  1150. data/test/performance/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +15 -15
  1151. data/test/performance/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +6 -6
  1152. data/test/performance/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  1153. data/test/performance/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +15 -15
  1154. data/test/performance/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +6 -6
  1155. data/test/performance/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  1156. data/test/performance/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +15 -15
  1157. data/test/performance/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +6 -6
  1158. metadata +3 -3
@@ -1,759 +1,759 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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 file contains top level functions in the Cosmos namespace
12
-
13
- require 'thread'
14
- require 'digest/md5'
15
- require 'open3'
16
- require 'cosmos/core_ext'
17
- require 'cosmos/version'
18
- require 'cosmos/utilities/logger'
19
- require 'socket'
20
- require 'pathname'
21
- require 'bundler'
22
-
23
- # If a hazardous command is sent through the {Cosmos::Api} this error is raised.
24
- # {Cosmos::Script} rescues the error and prompts the user to continue.
25
- class HazardousError < StandardError
26
- attr_accessor :target_name
27
- attr_accessor :cmd_name
28
- attr_accessor :cmd_params
29
- attr_accessor :hazardous_description
30
- end
31
-
32
- # The Ball Aerospace COSMOS system is almost
33
- # wholly contained within the Cosmos module. COSMOS also extends some of the
34
- # core Ruby classes to add additional functionality as well as creates
35
- # additional QT GUI classes under the {Qt} module.
36
- #
37
- # The primary entry point into COSMOS is through {Cosmos::System}. The System
38
- # class provides two class variables {Cosmos::System#commands} and
39
- # {Cosmos::System#telemetry} which provide access to all the commands and
40
- # telemetry in Cosmos. The targets are available through the
41
- # {Cosmos::System#targets} hash whose keys are the target names and values are
42
- # {Cosmos::Target} instances.
43
- #
44
- # Creating a new COSMOS tool involves subclassing {Cosmos::QtTool}. All COSMOS
45
- # tools derive from {Cosmos::QtTool} and provide a good basis for creating a
46
- # new tool. Be sure to explore the various GUI classes
47
- module Cosmos
48
-
49
- BASE_PWD = Dir.pwd
50
-
51
- # FatalErrors cause an exit but are not as dangerous as other errors.
52
- # They are used for known issues and thus we don't need a full error report.
53
- class FatalError < StandardError; end
54
-
55
- # Global mutex for the Cosmos module
56
- COSMOS_MUTEX = Mutex.new
57
-
58
- # Path to COSMOS Gem based on location of top_level.rb
59
- PATH = File.expand_path(File.join(File.dirname(__FILE__), '../..'))
60
- PATH.freeze
61
-
62
- # Header to put on all marshal files created by COSMOS
63
- COSMOS_MARSHAL_HEADER = "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}] COSMOS #{COSMOS_VERSION}"
64
-
65
- # Disables the Ruby interpreter warnings such as when redefining a constant
66
- def self.disable_warnings
67
- saved_verbose = $VERBOSE
68
- $VERBOSE = nil
69
- yield
70
- $VERBOSE = saved_verbose
71
- end
72
-
73
- # Searches for the file userpath.txt to define the USERPATH constant
74
- #
75
- # @param start_dir [String] Path to start the search for userpath.txt. The
76
- # search will continue by moving up directories until the root directory is
77
- # reached.
78
- def self.define_user_path(start_dir = Dir.pwd)
79
- current_dir = File.expand_path(start_dir)
80
- while true
81
- if File.exist?(File.join(current_dir, 'userpath.txt'))
82
- disable_warnings do
83
- Cosmos.const_set(:USERPATH, current_dir)
84
- end
85
- break
86
- else
87
- old_current_dir = current_dir
88
- current_dir = File.expand_path(File.join(current_dir, '..'))
89
- if old_current_dir == current_dir
90
- # Hit the root dir - give up
91
- break
92
- end
93
- end
94
- end
95
- end
96
-
97
- #############################################################################
98
- # This code is executed in place when this file is required
99
-
100
- # Initialize to nil before searching
101
- USERPATH = nil
102
-
103
- # First attempt try from the location of the executable ($0)
104
- # Note this method will fail when a intermediary executable is used like rcov
105
- self.define_user_path(File.dirname($0))
106
- if USERPATH.nil?
107
- # Second attempt try from location of the current working directory
108
- self.define_user_path(Dir.pwd)
109
- if USERPATH.nil?
110
- # Last chance - Check environment
111
- if ENV['COSMOS_USERPATH']
112
- disable_warnings do
113
- Cosmos.const_set(:USERPATH, ENV['COSMOS_USERPATH'])
114
- end
115
- else
116
- # Give up and assume we are in the tools directory and there is no userpath.txt file
117
- disable_warnings do
118
- Cosmos.const_set(:USERPATH, File.expand_path(File.join(File.dirname($0), '..')))
119
- end
120
- end
121
- end
122
- end
123
- USERPATH.freeze
124
-
125
- #############################################################################
126
-
127
-
128
- # Adds a path to the global Ruby search path
129
- #
130
- # @param path [String] Directory path
131
- def self.add_to_search_path(path, front = true)
132
- Cosmos.set_working_dir do
133
- path = File.expand_path(path)
134
- $:.delete(path)
135
- if front
136
- $:.unshift(path)
137
- else # Back
138
- $: << path
139
- end
140
- end
141
- end
142
-
143
- # Searches the COSMOS::USERPATH/config/data directory and then the core
144
- # COSMOS/data directory for the given file name. Returns the absolute file
145
- # path or nil if the file could not be found. This allows for user configuration
146
- # files to override COSMOS data file defaults.
147
- def self.data_path(name)
148
- # Check USERPATH
149
- filename = File.join(::Cosmos::USERPATH, 'config', 'data', name)
150
- return filename if File.exist? filename
151
-
152
- # Check extensions
153
- begin
154
- Bundler.load.specs.each do |spec|
155
- spec_name_split = spec.name.split('-')
156
- if spec_name_split.length > 1 and spec_name_split[0] == 'cosmos'
157
- filename = File.join(spec.gem_dir, 'config', 'data', name)
158
- return filename if File.exist? filename
159
- end
160
- end
161
- rescue Bundler::GemfileNotFound
162
- # No Gemfile - so no gem based extensions
163
- end
164
-
165
- filename = File.join(::Cosmos::PATH, 'data', name)
166
- return filename if File.exist? filename
167
-
168
- # Check CORE
169
- filename = Cosmos.path('data', name)
170
- return filename if File.exist? filename
171
-
172
- nil
173
- end
174
-
175
- # Returns a path to a cosmos file. Prefers files in USERPATH but will look
176
- # relative to calling_file if not present in USERPATH
177
- # @param calling_file [String] Should be __FILE__ from the calling file
178
- # @param paths [Array<String>] Partial paths like in File.join
179
- def self.path(calling_file, *paths)
180
- partial_path = File.join(*paths)
181
-
182
- # First look in the Cosmos::USERPATH
183
- user_path = File.join(Cosmos::USERPATH, partial_path)
184
- return user_path if File.exist?(user_path)
185
-
186
- # Then look relative to the calling file
187
- if Pathname.new(calling_file).absolute?
188
- current_dir = File.dirname(calling_file)
189
- else
190
- current_dir = File.join(BASE_PWD, calling_file)
191
- end
192
- while true
193
- test_path = File.join(current_dir, partial_path)
194
- if File.exist?(test_path)
195
- return test_path
196
- else
197
- old_current_dir = current_dir
198
- current_dir = File.expand_path(File.join(current_dir, '..'))
199
- if old_current_dir == current_dir
200
- # Hit the root dir - give up
201
- raise "Could not find path to #{File.join(*paths)}"
202
- end
203
- end
204
- end
205
- end
206
-
207
- # Creates a marshal file by serializing the given obj
208
- #
209
- # @param marshal_filename [String] Name of the marshal file to create
210
- # @param obj [Object] The object to serialize to the file
211
- def self.marshal_dump(marshal_filename, obj)
212
- begin
213
- Cosmos.set_working_dir do
214
- File.open(marshal_filename, 'wb') do |file|
215
- file.write(COSMOS_MARSHAL_HEADER)
216
- file.write(Marshal.dump(obj))
217
- end
218
- end
219
- rescue Exception => exception
220
- begin
221
- Cosmos.set_working_dir do
222
- File.delete(marshal_filename)
223
- end
224
- rescue Exception
225
- # Oh well - we tried
226
- end
227
- self.handle_fatal_exception(exception)
228
- end
229
- end
230
-
231
- # Loads the marshal file back into a Ruby object
232
- #
233
- # @param marshal_filename [String] Name of the marshal file to load
234
- def self.marshal_load(marshal_filename)
235
- begin
236
- cosmos_marshal_header = nil
237
- data = nil
238
- Cosmos.set_working_dir do
239
- File.open(marshal_filename, 'rb') do |file|
240
- cosmos_marshal_header = file.read(COSMOS_MARSHAL_HEADER.length)
241
- data = file.read
242
- end
243
- end
244
- if cosmos_marshal_header == COSMOS_MARSHAL_HEADER
245
- return Marshal.load(data)
246
- else
247
- Logger.warn "Marshal load failed with invalid marshal file: #{marshal_filename}"
248
- return nil
249
- end
250
- rescue Exception => exception
251
- Cosmos.set_working_dir do
252
- if File.exist?(marshal_filename)
253
- Logger.error "Marshal load failed with exception: #{marshal_filename}\n#{exception.formatted}"
254
- else
255
- Logger.info "Marshal file does not exist: #{marshal_filename}"
256
- end
257
-
258
- # Try to delete the bad marshal file
259
- begin
260
- File.delete(marshal_filename)
261
- rescue Exception
262
- # Oh well - we tried
263
- end
264
- self.handle_fatal_exception(exception) if File.exist?(marshal_filename)
265
- end
266
- return nil
267
- end
268
- end
269
-
270
- # Changes the current working directory to the USERPATH and then executes the
271
- # command in a new Ruby Thread.
272
- #
273
- # @param command [String] The command to execute via the 'system' call
274
- def self.run_process(command)
275
- thread = nil
276
- Cosmos.set_working_dir do
277
- thread = Thread.new do
278
- system(command)
279
- end
280
- # Wait for the thread and process to start
281
- sleep 0.01 until !thread.status.nil?
282
- sleep 0.1
283
- end
284
- thread
285
- end
286
-
287
- # Changes the current working directory to the USERPATH and then executes the
288
- # command in a new Ruby Thread. Will show a messagebox or print the output if the
289
- # process produces any output
290
- #
291
- # @param command [String] The command to execute via the 'system' call
292
- def self.run_process_check_output(command)
293
- thread = nil
294
- Cosmos.set_working_dir do
295
- thread = Thread.new do
296
- output, _ = Open3.capture2e(command)
297
- if !output.empty?
298
- # Work around modalSession messages on Mac Mavericks
299
- real_lines = 0
300
- output.each_line do |line|
301
- real_lines += 1 if line !~ /modalSession/
302
- end
303
-
304
- if real_lines > 0
305
- Logger.error output
306
- self.write_unexpected_file(output)
307
- if defined? ::Qt and ::Qt::Application.instance
308
- Qt.execute_in_main_thread(false) do
309
- dialog = Qt::Dialog.new do |box|
310
- box.setWindowTitle('Unexpected text output')
311
- box.resize(600, 600)
312
- text_field = Qt::PlainTextEdit.new
313
- text_field.setReadOnly(true)
314
- orig_font = text_field.font
315
- text_field.setFont(Cosmos.getFont(orig_font.family, orig_font.point_size+2))
316
- text_field.setWordWrapMode(Qt::TextOption::NoWrap)
317
- text_field.appendPlainText(output)
318
- vframe = Qt::VBoxLayout.new
319
- vframe.addWidget(text_field)
320
- sep = Qt::Frame.new(box)
321
- sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
322
- vframe.addWidget(sep)
323
- ok = Qt::PushButton.new('OK')
324
- ok.setDefault(true)
325
- ok.connect(SIGNAL('clicked(bool)')) { box.accept }
326
- vframe.addWidget(ok)
327
- box.setLayout(vframe)
328
- box.show
329
- box.raise
330
- end
331
- dialog.exec
332
- dialog.dispose
333
- end
334
- end
335
- end
336
- end
337
- end
338
- # Wait for the thread and process to start
339
- sleep 0.01 until !thread.status.nil?
340
- sleep 0.1
341
- end
342
- thread
343
- end
344
-
345
- # Runs an md5 sum over one or more files and returns the Digest::MD5 object.
346
- # Handles windows/unix new line differences but changes in whitespace will
347
- # change the md5 sum.
348
- #
349
- # Usage:
350
- # digest = Cosmos.md5_files(files)
351
- # digest.digest # => the 16 bytes of digest
352
- # digest.hexdigest # => the formatted string in hex
353
- #
354
- # @param filenames [Array<String>] List of files to read and calculate a md5
355
- # sum on
356
- # @param additional_data [String] Additional data to add to the md5 sum
357
- # @return [Digest::MD5] The md5 sum
358
- def self.md5_files(filenames, additional_data = nil)
359
- digest = Digest::MD5.new
360
- Cosmos.set_working_dir do
361
- filenames.each do |filename|
362
- # Read the file's data and add to the running MD5 sum
363
- digest << File.read(filename).gsub(/\r/,'')
364
- end
365
- end
366
- digest << additional_data if additional_data
367
- digest
368
- end
369
-
370
- # Opens a timestamped log file for writing. The opened file is yielded back
371
- # to the block.
372
- #
373
- # @param filename [String] String to append to the exception log filename.
374
- # The filename will start with a date/time stamp.
375
- # @param log_dir [String] By default this method will write to the COSMOS
376
- # default log directory. By setting this parameter you can override the
377
- # directory the log will be written to.
378
- # @yieldparam file [File] The log file
379
- # @return [String|nil] The fully pathed log file name or nil if there was
380
- # an error creating the log file.
381
- def self.create_log_file(filename, log_dir)
382
- log_file = nil
383
- Cosmos.set_working_dir do
384
- begin
385
- # The following code goes inside a begin rescue because it reads the
386
- # system.txt configuration file. If this has an error we won't be able
387
- # to determine the log path but we still want to write the log.
388
- log_dir = System.instance.paths['LOGS'] unless log_dir
389
- log_file = File.join(log_dir,
390
- File.build_timestamped_filename([filename]))
391
- # Make sure the log directory exists
392
- raise unless File.exist?(log_dir)
393
- log_file
394
- rescue Exception
395
- # If not then we just build a file locally
396
- if File.exist?('./outputs/logs')
397
- log_file = File.join('./outputs/logs', File.build_timestamped_filename([filename]))
398
- elsif File.exist?('./logs')
399
- log_file = File.join('./logs', File.build_timestamped_filename([filename]))
400
- else
401
- log_file = File.build_timestamped_filename([filename])
402
- end
403
- end
404
- begin
405
- # Log exception to file, open the file in append mode in case we get
406
- # multiple exceptions in the same second. That way we don't lose
407
- # exceptions by overwritting the last exception file.
408
- COSMOS_MUTEX.synchronize do
409
- begin
410
- file = File.open(log_file, 'a')
411
- yield file
412
- ensure
413
- file.close unless file.closed?
414
- end
415
- end
416
- rescue Exception
417
- # Ensure we always return
418
- end
419
- log_file = File.expand_path(log_file)
420
- end
421
- return log_file
422
- end
423
-
424
- # Writes a log file with information about the current configuration
425
- # including the Ruby version, Cosmos version, whether you are on Windows, the
426
- # COSMOS path and userpath, and the Ruby path along with the exception that
427
- # is passed in.
428
- #
429
- # @param [String] filename String to append to the exception log filename.
430
- # The filename will start with a date/time stamp.
431
- # @param [String] log_dir By default this method will write to the COSMOS
432
- # default log directory. By setting this parameter you can override the
433
- # directory the log will be written to.
434
- # @return [String|nil] The fully pathed log file name or nil if there was
435
- # an error creating the log file.
436
- def self.write_exception_file(exception, filename = 'exception', log_dir = nil)
437
- log_file = create_log_file(filename, log_dir) do |file|
438
- begin
439
- file.puts "Exception:"
440
- if exception
441
- file.puts exception.formatted
442
- file.puts
443
- else
444
- file.puts "No Exception Given"
445
- file.puts caller.join("\n")
446
- file.puts
447
- end
448
- file.puts "Caller Backtrace:"
449
- file.puts caller().join("\n")
450
- file.puts
451
-
452
- file.puts "Ruby Version: ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"
453
- file.puts "Rubygems Version: #{Gem::VERSION}"
454
- file.puts "Cosmos Version: #{Cosmos::VERSION}"
455
- file.puts "Cosmos::PATH: #{Cosmos::PATH}"
456
- file.puts "Cosmos::USERPATH: #{Cosmos::USERPATH}"
457
- file.puts ""
458
- file.puts "Environment:"
459
- file.puts "RUBYOPT: #{ENV['GEM_HOME']}"
460
- file.puts "RUBYLIB: #{ENV['GEM_HOME']}"
461
- file.puts "GEM_PATH: #{ENV['GEM_HOME']}"
462
- file.puts "GEMRC: #{ENV['GEM_HOME']}"
463
- file.puts "RI_DEVKIT: #{ENV['GEM_HOME']}"
464
- file.puts "GEM_HOME: #{ENV['GEM_HOME']}"
465
- file.puts "PATH: #{ENV['PATH']}"
466
- file.puts ""
467
- file.puts "Ruby Path:\n #{$:.join("\n ")}\n\n"
468
- file.puts "Gems:"
469
- Gem.loaded_specs.values.map {|x| file.puts "#{x.name} #{x.version} #{x.platform}"}
470
- file.puts ""
471
- file.puts "All Threads Backtraces:"
472
- Thread.list.each do |thread|
473
- file.puts thread.backtrace.join("\n")
474
- file.puts
475
- end
476
- file.puts ""
477
- file.puts ""
478
- ensure
479
- file.close
480
- end
481
- end
482
- return log_file
483
- end
484
-
485
- # Writes a log file with information about unexpected output
486
- #
487
- # @param[String] text The unexpected output text
488
- # @param [String] filename String to append to the exception log filename.
489
- # The filename will start with a date/time stamp.
490
- # @param [String] log_dir By default this method will write to the COSMOS
491
- # default log directory. By setting this parameter you can override the
492
- # directory the log will be written to.
493
- # @return [String|nil] The fully pathed log file name or nil if there was
494
- # an error creating the log file.
495
- def self.write_unexpected_file(text, filename = 'unexpected', log_dir = nil)
496
- log_file = create_log_file(filename, log_dir) do |file|
497
- begin
498
- file.puts "Unexpected Output:\n\n"
499
- file.puts text
500
- ensure
501
- file.close
502
- end
503
- end
504
- return log_file
505
- end
506
-
507
- # Catch fatal exceptions within the block
508
- # This is intended to catch exceptions before the GUI is available
509
- def self.catch_fatal_exception
510
- begin
511
- yield
512
- rescue Exception => error
513
- unless error.class == SystemExit or error.class == Interrupt
514
- Logger.level = Logger::FATAL
515
- Cosmos.handle_fatal_exception(error, false)
516
- end
517
- end
518
- end
519
-
520
- # Write a message to the Logger, write an exception file, and popup a GUI
521
- # window if try_gui. Finally 'exit 1' is called to end the calling program.
522
- #
523
- # @param error [Exception] The exception to handle
524
- # @param try_gui [Boolean] Whether to try and create a GUI exception popup
525
- def self.handle_fatal_exception(error, try_gui = true)
526
- $cosmos_fatal_exception = error
527
- log_file = self.write_exception_file(error)
528
- Logger.level = Logger::FATAL unless try_gui
529
- Logger.fatal "Fatal Exception! Exiting..."
530
- Logger.fatal error.formatted
531
- if defined? ExceptionDialog and try_gui and Qt::Application.instance
532
- Qt.execute_in_main_thread(true) {||ExceptionDialog.new(nil, error, '', true, false, log_file)}
533
- else
534
- if $stdout != STDOUT
535
- $stdout = STDOUT
536
- Logger.fatal "Fatal Exception! Exiting..."
537
- Logger.fatal error.formatted
538
- end
539
- sleep 1 # Allow the messages to be printed and then crash
540
- exit 1
541
- end
542
- end
543
-
544
- # CriticalErrors are errors that need to be brought to a user's attention but
545
- # do not cause an exit. A good example is if the packet log writer fails and
546
- # can no longer write the log file. Write a message to the Logger, write an
547
- # exception file, and popup a GUI window if try_gui. Ensure the GUI only
548
- # comes up once so this method can be called over and over by failing code.
549
- #
550
- # @param error [Exception] The exception to handle
551
- # @param try_gui [Boolean] Whether to try and create a GUI exception popup
552
- def self.handle_critical_exception(error, try_gui = true)
553
- Logger.error "Critical Exception! #{error.formatted}"
554
- if defined? ExceptionDialog and !ExceptionDialog.dialog_open?
555
- log_file = self.write_exception_file(error)
556
- if try_gui
557
- Qt.execute_in_main_thread(true) {|| ExceptionDialog.new(nil, error, '', false, false, log_file)}
558
- end
559
- end
560
- end
561
-
562
- # Creates a Ruby Thread to run the given block. Rescues any exceptions and
563
- # retries the threads the given number of times before handling the thread
564
- # death by calling {Cosmos.handle_fatal_exception}.
565
- #
566
- # @param name [String] Name of the thread
567
- # @param retry_attempts [Integer] The number of times to allow the thread to
568
- # restart before exiting
569
- def self.safe_thread(name, retry_attempts = 0)
570
- Thread.new do
571
- retry_count = 0
572
- begin
573
- yield
574
- rescue Exception => error
575
- Logger.error "#{name} thread unexpectedly died. Retries: #{retry_count} of #{retry_attempts}"
576
- Logger.error error.formatted
577
- retry_count += 1
578
- if retry_count <= retry_attempts
579
- self.write_exception_file(error)
580
- retry
581
- end
582
- handle_fatal_exception(error)
583
- end
584
- end
585
- end
586
-
587
- # Require the class represented by the filename. This uses the standard Ruby
588
- # convention of having a single class per file where the class name is camel
589
- # cased and filename is lowercase with underscores.
590
- #
591
- # @param class_filename [String] The name of the file which contains the
592
- # Ruby class to require
593
- def self.require_class(class_filename)
594
- class_name = class_filename.filename_to_class_name
595
- return class_name.to_class if class_name.to_class and defined? class_name.to_class
596
- self.require_file(class_filename)
597
- klass = class_name.to_class
598
- if klass
599
- return klass
600
- else
601
- raise "Ruby class #{class_name} not found"
602
- end
603
- end
604
-
605
- # Requires a file with a standard error message if it fails
606
- #
607
- # @param filename [String] The name of the file to require
608
- def self.require_file(filename)
609
- begin
610
- require filename
611
- rescue Exception => err
612
- msg = "Unable to require #{filename} due to #{err.message}. Ensure #{filename} is in the COSMOS lib directory."
613
- Logger.error msg
614
- raise msg
615
- end
616
- end
617
-
618
- # @param filename [String] Name of the file to open in the editor
619
- def self.open_in_text_editor(filename)
620
- if filename
621
- if Kernel.is_windows?
622
- if File.extname(filename).to_s.downcase == '.csv'
623
- self.run_process("cmd /c \"start wordpad \"#{filename.gsub('/','\\')}\"\"")
624
- else
625
- self.run_process("cmd /c \"start \"\" \"#{filename.gsub('/','\\')}\"\"")
626
- end
627
- elsif Kernel.is_mac?
628
- self.run_process("open -a TextEdit \"#{filename}\"")
629
- else
630
- which_gedit = `which gedit 2>&1`.chomp
631
- if which_gedit =~ /Command not found/i or which_gedit =~ /no .* in/i
632
- # No gedit
633
- editor = ENV['EDITOR']
634
- editor = 'vi' unless editor
635
- which_xterm = `which xterm 2>&1`.chomp
636
- if which_xterm =~ /Command not found/i or which_xterm =~ /no .* in/i
637
- # No xterm
638
- which_gnome_terminal = `which gnome-terminal 2>&1`.chomp
639
- if which_gnome_terminal =~ /Command not found/i or which_gnome_terminal =~ /no .* in/i
640
- # No gnome-terminal - Do nothing
641
- else
642
- # Have gnome-terminal
643
- system_call = "gnome-terminal -e #{editor} \"#{filename}\""
644
- end
645
- else
646
- # Have xterm
647
- system_call = "xterm -e #{editor} \"#{filename}\""
648
- end
649
- else
650
- # Have gedit
651
- system_call = "gedit \"#{filename}\""
652
- end
653
- self.run_process(system_call)
654
- end
655
- end
656
- end
657
-
658
- # @param filename [String] Name of the file to open in the web browser
659
- def self.open_in_web_browser(filename)
660
- if filename
661
- if Kernel.is_windows?
662
- self.run_process("cmd /c \"start \"\" \"#{filename.gsub('/','\\')}\"\"")
663
- elsif Kernel.is_mac?
664
- self.run_process("open -a Safari \"#{filename}\"")
665
- else
666
- which_firefox = `which firefox`.chomp
667
- if which_firefox =~ /Command not found/i or which_firefox =~ /no .* in/i
668
- raise "Firefox not found"
669
- else
670
- system_call = "#{which_firefox} \"#{filename}\""
671
- end
672
- self.run_process(system_call)
673
- end
674
- end
675
- end
676
-
677
- # Temporarily set the working directory during a block
678
- def self.set_working_dir(working_dir = Cosmos::USERPATH)
679
- current_dir = Dir.pwd
680
- Dir.chdir(working_dir)
681
- begin
682
- yield
683
- ensure
684
- Dir.chdir(current_dir)
685
- end
686
- end
687
-
688
- # Attempt to gracefully kill a thread
689
- # @param owner Object that owns the thread and may have a graceful_kill method
690
- # @param thread The thread to gracefully kill
691
- # @param graceful_timeout Timeout in seconds to wait for it to die gracefully
692
- # @param timeout_interval How often to poll for aliveness
693
- # @param hard_timeout Timeout in seconds to wait for it to die ungracefully
694
- def self.kill_thread(owner, thread, graceful_timeout = 1, timeout_interval = 0.01, hard_timeout = 1)
695
- if thread
696
- if owner and owner.respond_to? :graceful_kill
697
- if Thread.current != thread
698
- owner.graceful_kill
699
- end_time = Time.now + graceful_timeout
700
- while thread.alive? && ((end_time - Time.now) > 0)
701
- sleep(timeout_interval)
702
- end
703
- else
704
- Logger.warn "Threads cannot graceful_kill themselves"
705
- end
706
- elsif owner
707
- Logger.info "Thread owner #{owner.class} does not support graceful_kill"
708
- end
709
- if thread.alive?
710
- # Graceful failed
711
- Logger.warn "Failed to gracefully kill thread:\n Caller Backtrace:\n #{caller().join("\n ")}\n \n Thread Backtrace:\n #{thread.backtrace.join("\n ")}\n\n"
712
- thread.kill
713
- end_time = Time.now + hard_timeout
714
- while thread.alive? && ((end_time - Time.now) > 0)
715
- sleep(timeout_interval)
716
- end
717
- end
718
- if thread.alive?
719
- Logger.error "Failed to kill thread"
720
- end
721
- end
722
- end
723
-
724
- # Close a socket in a manner that ensures that any reads blocked in select
725
- # will unblock across platforms
726
- # @param socket The socket to close
727
- def self.close_socket(socket)
728
- if socket
729
- # Calling shutdown and then sleep seems to be required
730
- # to get select to reliably unblock on linux
731
- begin
732
- socket.shutdown(:RDWR)
733
- sleep(0)
734
- rescue Exception
735
- # Oh well we tried
736
- end
737
- begin
738
- socket.close unless socket.closed?
739
- rescue Exception
740
- # Oh well we tried
741
- end
742
- end
743
- end
744
-
745
- # Play a wav file
746
- # @param wav_filename filename of the wav file
747
- def self.play_wav_file(wav_filename)
748
- if defined? Qt and wav_filename
749
- Qt.execute_in_main_thread(true) do
750
- if Qt::CoreApplication.instance and Qt::Sound.isAvailable
751
- Cosmos.set_working_dir do
752
- Qt::Sound.play(wav_filename.to_s)
753
- end
754
- end
755
- end
756
- end
757
- end
758
-
759
- end
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 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 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 file contains top level functions in the Cosmos namespace
12
+
13
+ require 'thread'
14
+ require 'digest/md5'
15
+ require 'open3'
16
+ require 'cosmos/core_ext'
17
+ require 'cosmos/version'
18
+ require 'cosmos/utilities/logger'
19
+ require 'socket'
20
+ require 'pathname'
21
+ require 'bundler'
22
+
23
+ # If a hazardous command is sent through the {Cosmos::Api} this error is raised.
24
+ # {Cosmos::Script} rescues the error and prompts the user to continue.
25
+ class HazardousError < StandardError
26
+ attr_accessor :target_name
27
+ attr_accessor :cmd_name
28
+ attr_accessor :cmd_params
29
+ attr_accessor :hazardous_description
30
+ end
31
+
32
+ # The Ball Aerospace COSMOS system is almost
33
+ # wholly contained within the Cosmos module. COSMOS also extends some of the
34
+ # core Ruby classes to add additional functionality as well as creates
35
+ # additional QT GUI classes under the {Qt} module.
36
+ #
37
+ # The primary entry point into COSMOS is through {Cosmos::System}. The System
38
+ # class provides two class variables {Cosmos::System#commands} and
39
+ # {Cosmos::System#telemetry} which provide access to all the commands and
40
+ # telemetry in Cosmos. The targets are available through the
41
+ # {Cosmos::System#targets} hash whose keys are the target names and values are
42
+ # {Cosmos::Target} instances.
43
+ #
44
+ # Creating a new COSMOS tool involves subclassing {Cosmos::QtTool}. All COSMOS
45
+ # tools derive from {Cosmos::QtTool} and provide a good basis for creating a
46
+ # new tool. Be sure to explore the various GUI classes
47
+ module Cosmos
48
+
49
+ BASE_PWD = Dir.pwd
50
+
51
+ # FatalErrors cause an exit but are not as dangerous as other errors.
52
+ # They are used for known issues and thus we don't need a full error report.
53
+ class FatalError < StandardError; end
54
+
55
+ # Global mutex for the Cosmos module
56
+ COSMOS_MUTEX = Mutex.new
57
+
58
+ # Path to COSMOS Gem based on location of top_level.rb
59
+ PATH = File.expand_path(File.join(File.dirname(__FILE__), '../..'))
60
+ PATH.freeze
61
+
62
+ # Header to put on all marshal files created by COSMOS
63
+ COSMOS_MARSHAL_HEADER = "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}] COSMOS #{COSMOS_VERSION}"
64
+
65
+ # Disables the Ruby interpreter warnings such as when redefining a constant
66
+ def self.disable_warnings
67
+ saved_verbose = $VERBOSE
68
+ $VERBOSE = nil
69
+ yield
70
+ $VERBOSE = saved_verbose
71
+ end
72
+
73
+ # Searches for the file userpath.txt to define the USERPATH constant
74
+ #
75
+ # @param start_dir [String] Path to start the search for userpath.txt. The
76
+ # search will continue by moving up directories until the root directory is
77
+ # reached.
78
+ def self.define_user_path(start_dir = Dir.pwd)
79
+ current_dir = File.expand_path(start_dir)
80
+ while true
81
+ if File.exist?(File.join(current_dir, 'userpath.txt'))
82
+ disable_warnings do
83
+ Cosmos.const_set(:USERPATH, current_dir)
84
+ end
85
+ break
86
+ else
87
+ old_current_dir = current_dir
88
+ current_dir = File.expand_path(File.join(current_dir, '..'))
89
+ if old_current_dir == current_dir
90
+ # Hit the root dir - give up
91
+ break
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ #############################################################################
98
+ # This code is executed in place when this file is required
99
+
100
+ # Initialize to nil before searching
101
+ USERPATH = nil
102
+
103
+ # First attempt try from the location of the executable ($0)
104
+ # Note this method will fail when a intermediary executable is used like rcov
105
+ self.define_user_path(File.dirname($0))
106
+ if USERPATH.nil?
107
+ # Second attempt try from location of the current working directory
108
+ self.define_user_path(Dir.pwd)
109
+ if USERPATH.nil?
110
+ # Last chance - Check environment
111
+ if ENV['COSMOS_USERPATH']
112
+ disable_warnings do
113
+ Cosmos.const_set(:USERPATH, ENV['COSMOS_USERPATH'])
114
+ end
115
+ else
116
+ # Give up and assume we are in the tools directory and there is no userpath.txt file
117
+ disable_warnings do
118
+ Cosmos.const_set(:USERPATH, File.expand_path(File.join(File.dirname($0), '..')))
119
+ end
120
+ end
121
+ end
122
+ end
123
+ USERPATH.freeze
124
+
125
+ #############################################################################
126
+
127
+
128
+ # Adds a path to the global Ruby search path
129
+ #
130
+ # @param path [String] Directory path
131
+ def self.add_to_search_path(path, front = true)
132
+ Cosmos.set_working_dir do
133
+ path = File.expand_path(path)
134
+ $:.delete(path)
135
+ if front
136
+ $:.unshift(path)
137
+ else # Back
138
+ $: << path
139
+ end
140
+ end
141
+ end
142
+
143
+ # Searches the COSMOS::USERPATH/config/data directory and then the core
144
+ # COSMOS/data directory for the given file name. Returns the absolute file
145
+ # path or nil if the file could not be found. This allows for user configuration
146
+ # files to override COSMOS data file defaults.
147
+ def self.data_path(name)
148
+ # Check USERPATH
149
+ filename = File.join(::Cosmos::USERPATH, 'config', 'data', name)
150
+ return filename if File.exist? filename
151
+
152
+ # Check extensions
153
+ begin
154
+ Bundler.load.specs.each do |spec|
155
+ spec_name_split = spec.name.split('-')
156
+ if spec_name_split.length > 1 and spec_name_split[0] == 'cosmos'
157
+ filename = File.join(spec.gem_dir, 'config', 'data', name)
158
+ return filename if File.exist? filename
159
+ end
160
+ end
161
+ rescue Bundler::GemfileNotFound
162
+ # No Gemfile - so no gem based extensions
163
+ end
164
+
165
+ filename = File.join(::Cosmos::PATH, 'data', name)
166
+ return filename if File.exist? filename
167
+
168
+ # Check CORE
169
+ filename = Cosmos.path('data', name)
170
+ return filename if File.exist? filename
171
+
172
+ nil
173
+ end
174
+
175
+ # Returns a path to a cosmos file. Prefers files in USERPATH but will look
176
+ # relative to calling_file if not present in USERPATH
177
+ # @param calling_file [String] Should be __FILE__ from the calling file
178
+ # @param paths [Array<String>] Partial paths like in File.join
179
+ def self.path(calling_file, *paths)
180
+ partial_path = File.join(*paths)
181
+
182
+ # First look in the Cosmos::USERPATH
183
+ user_path = File.join(Cosmos::USERPATH, partial_path)
184
+ return user_path if File.exist?(user_path)
185
+
186
+ # Then look relative to the calling file
187
+ if Pathname.new(calling_file).absolute?
188
+ current_dir = File.dirname(calling_file)
189
+ else
190
+ current_dir = File.join(BASE_PWD, calling_file)
191
+ end
192
+ while true
193
+ test_path = File.join(current_dir, partial_path)
194
+ if File.exist?(test_path)
195
+ return test_path
196
+ else
197
+ old_current_dir = current_dir
198
+ current_dir = File.expand_path(File.join(current_dir, '..'))
199
+ if old_current_dir == current_dir
200
+ # Hit the root dir - give up
201
+ raise "Could not find path to #{File.join(*paths)}"
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ # Creates a marshal file by serializing the given obj
208
+ #
209
+ # @param marshal_filename [String] Name of the marshal file to create
210
+ # @param obj [Object] The object to serialize to the file
211
+ def self.marshal_dump(marshal_filename, obj)
212
+ begin
213
+ Cosmos.set_working_dir do
214
+ File.open(marshal_filename, 'wb') do |file|
215
+ file.write(COSMOS_MARSHAL_HEADER)
216
+ file.write(Marshal.dump(obj))
217
+ end
218
+ end
219
+ rescue Exception => exception
220
+ begin
221
+ Cosmos.set_working_dir do
222
+ File.delete(marshal_filename)
223
+ end
224
+ rescue Exception
225
+ # Oh well - we tried
226
+ end
227
+ self.handle_fatal_exception(exception)
228
+ end
229
+ end
230
+
231
+ # Loads the marshal file back into a Ruby object
232
+ #
233
+ # @param marshal_filename [String] Name of the marshal file to load
234
+ def self.marshal_load(marshal_filename)
235
+ begin
236
+ cosmos_marshal_header = nil
237
+ data = nil
238
+ Cosmos.set_working_dir do
239
+ File.open(marshal_filename, 'rb') do |file|
240
+ cosmos_marshal_header = file.read(COSMOS_MARSHAL_HEADER.length)
241
+ data = file.read
242
+ end
243
+ end
244
+ if cosmos_marshal_header == COSMOS_MARSHAL_HEADER
245
+ return Marshal.load(data)
246
+ else
247
+ Logger.warn "Marshal load failed with invalid marshal file: #{marshal_filename}"
248
+ return nil
249
+ end
250
+ rescue Exception => exception
251
+ Cosmos.set_working_dir do
252
+ if File.exist?(marshal_filename)
253
+ Logger.error "Marshal load failed with exception: #{marshal_filename}\n#{exception.formatted}"
254
+ else
255
+ Logger.info "Marshal file does not exist: #{marshal_filename}"
256
+ end
257
+
258
+ # Try to delete the bad marshal file
259
+ begin
260
+ File.delete(marshal_filename)
261
+ rescue Exception
262
+ # Oh well - we tried
263
+ end
264
+ self.handle_fatal_exception(exception) if File.exist?(marshal_filename)
265
+ end
266
+ return nil
267
+ end
268
+ end
269
+
270
+ # Changes the current working directory to the USERPATH and then executes the
271
+ # command in a new Ruby Thread.
272
+ #
273
+ # @param command [String] The command to execute via the 'system' call
274
+ def self.run_process(command)
275
+ thread = nil
276
+ Cosmos.set_working_dir do
277
+ thread = Thread.new do
278
+ system(command)
279
+ end
280
+ # Wait for the thread and process to start
281
+ sleep 0.01 until !thread.status.nil?
282
+ sleep 0.1
283
+ end
284
+ thread
285
+ end
286
+
287
+ # Changes the current working directory to the USERPATH and then executes the
288
+ # command in a new Ruby Thread. Will show a messagebox or print the output if the
289
+ # process produces any output
290
+ #
291
+ # @param command [String] The command to execute via the 'system' call
292
+ def self.run_process_check_output(command)
293
+ thread = nil
294
+ Cosmos.set_working_dir do
295
+ thread = Thread.new do
296
+ output, _ = Open3.capture2e(command)
297
+ if !output.empty?
298
+ # Work around modalSession messages on Mac Mavericks
299
+ real_lines = 0
300
+ output.each_line do |line|
301
+ real_lines += 1 if line !~ /modalSession/
302
+ end
303
+
304
+ if real_lines > 0
305
+ Logger.error output
306
+ self.write_unexpected_file(output)
307
+ if defined? ::Qt and ::Qt::Application.instance
308
+ Qt.execute_in_main_thread(false) do
309
+ dialog = Qt::Dialog.new do |box|
310
+ box.setWindowTitle('Unexpected text output')
311
+ box.resize(600, 600)
312
+ text_field = Qt::PlainTextEdit.new
313
+ text_field.setReadOnly(true)
314
+ orig_font = text_field.font
315
+ text_field.setFont(Cosmos.getFont(orig_font.family, orig_font.point_size+2))
316
+ text_field.setWordWrapMode(Qt::TextOption::NoWrap)
317
+ text_field.appendPlainText(output)
318
+ vframe = Qt::VBoxLayout.new
319
+ vframe.addWidget(text_field)
320
+ sep = Qt::Frame.new(box)
321
+ sep.setFrameStyle(Qt::Frame::VLine | Qt::Frame::Sunken)
322
+ vframe.addWidget(sep)
323
+ ok = Qt::PushButton.new('OK')
324
+ ok.setDefault(true)
325
+ ok.connect(SIGNAL('clicked(bool)')) { box.accept }
326
+ vframe.addWidget(ok)
327
+ box.setLayout(vframe)
328
+ box.show
329
+ box.raise
330
+ end
331
+ dialog.exec
332
+ dialog.dispose
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+ # Wait for the thread and process to start
339
+ sleep 0.01 until !thread.status.nil?
340
+ sleep 0.1
341
+ end
342
+ thread
343
+ end
344
+
345
+ # Runs an md5 sum over one or more files and returns the Digest::MD5 object.
346
+ # Handles windows/unix new line differences but changes in whitespace will
347
+ # change the md5 sum.
348
+ #
349
+ # Usage:
350
+ # digest = Cosmos.md5_files(files)
351
+ # digest.digest # => the 16 bytes of digest
352
+ # digest.hexdigest # => the formatted string in hex
353
+ #
354
+ # @param filenames [Array<String>] List of files to read and calculate a md5
355
+ # sum on
356
+ # @param additional_data [String] Additional data to add to the md5 sum
357
+ # @return [Digest::MD5] The md5 sum
358
+ def self.md5_files(filenames, additional_data = nil)
359
+ digest = Digest::MD5.new
360
+ Cosmos.set_working_dir do
361
+ filenames.each do |filename|
362
+ # Read the file's data and add to the running MD5 sum
363
+ digest << File.read(filename).gsub(/\r/,'')
364
+ end
365
+ end
366
+ digest << additional_data if additional_data
367
+ digest
368
+ end
369
+
370
+ # Opens a timestamped log file for writing. The opened file is yielded back
371
+ # to the block.
372
+ #
373
+ # @param filename [String] String to append to the exception log filename.
374
+ # The filename will start with a date/time stamp.
375
+ # @param log_dir [String] By default this method will write to the COSMOS
376
+ # default log directory. By setting this parameter you can override the
377
+ # directory the log will be written to.
378
+ # @yieldparam file [File] The log file
379
+ # @return [String|nil] The fully pathed log file name or nil if there was
380
+ # an error creating the log file.
381
+ def self.create_log_file(filename, log_dir)
382
+ log_file = nil
383
+ Cosmos.set_working_dir do
384
+ begin
385
+ # The following code goes inside a begin rescue because it reads the
386
+ # system.txt configuration file. If this has an error we won't be able
387
+ # to determine the log path but we still want to write the log.
388
+ log_dir = System.instance.paths['LOGS'] unless log_dir
389
+ log_file = File.join(log_dir,
390
+ File.build_timestamped_filename([filename]))
391
+ # Make sure the log directory exists
392
+ raise unless File.exist?(log_dir)
393
+ log_file
394
+ rescue Exception
395
+ # If not then we just build a file locally
396
+ if File.exist?('./outputs/logs')
397
+ log_file = File.join('./outputs/logs', File.build_timestamped_filename([filename]))
398
+ elsif File.exist?('./logs')
399
+ log_file = File.join('./logs', File.build_timestamped_filename([filename]))
400
+ else
401
+ log_file = File.build_timestamped_filename([filename])
402
+ end
403
+ end
404
+ begin
405
+ # Log exception to file, open the file in append mode in case we get
406
+ # multiple exceptions in the same second. That way we don't lose
407
+ # exceptions by overwritting the last exception file.
408
+ COSMOS_MUTEX.synchronize do
409
+ begin
410
+ file = File.open(log_file, 'a')
411
+ yield file
412
+ ensure
413
+ file.close unless file.closed?
414
+ end
415
+ end
416
+ rescue Exception
417
+ # Ensure we always return
418
+ end
419
+ log_file = File.expand_path(log_file)
420
+ end
421
+ return log_file
422
+ end
423
+
424
+ # Writes a log file with information about the current configuration
425
+ # including the Ruby version, Cosmos version, whether you are on Windows, the
426
+ # COSMOS path and userpath, and the Ruby path along with the exception that
427
+ # is passed in.
428
+ #
429
+ # @param [String] filename String to append to the exception log filename.
430
+ # The filename will start with a date/time stamp.
431
+ # @param [String] log_dir By default this method will write to the COSMOS
432
+ # default log directory. By setting this parameter you can override the
433
+ # directory the log will be written to.
434
+ # @return [String|nil] The fully pathed log file name or nil if there was
435
+ # an error creating the log file.
436
+ def self.write_exception_file(exception, filename = 'exception', log_dir = nil)
437
+ log_file = create_log_file(filename, log_dir) do |file|
438
+ begin
439
+ file.puts "Exception:"
440
+ if exception
441
+ file.puts exception.formatted
442
+ file.puts
443
+ else
444
+ file.puts "No Exception Given"
445
+ file.puts caller.join("\n")
446
+ file.puts
447
+ end
448
+ file.puts "Caller Backtrace:"
449
+ file.puts caller().join("\n")
450
+ file.puts
451
+
452
+ file.puts "Ruby Version: ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"
453
+ file.puts "Rubygems Version: #{Gem::VERSION}"
454
+ file.puts "Cosmos Version: #{Cosmos::VERSION}"
455
+ file.puts "Cosmos::PATH: #{Cosmos::PATH}"
456
+ file.puts "Cosmos::USERPATH: #{Cosmos::USERPATH}"
457
+ file.puts ""
458
+ file.puts "Environment:"
459
+ file.puts "RUBYOPT: #{ENV['GEM_HOME']}"
460
+ file.puts "RUBYLIB: #{ENV['GEM_HOME']}"
461
+ file.puts "GEM_PATH: #{ENV['GEM_HOME']}"
462
+ file.puts "GEMRC: #{ENV['GEM_HOME']}"
463
+ file.puts "RI_DEVKIT: #{ENV['GEM_HOME']}"
464
+ file.puts "GEM_HOME: #{ENV['GEM_HOME']}"
465
+ file.puts "PATH: #{ENV['PATH']}"
466
+ file.puts ""
467
+ file.puts "Ruby Path:\n #{$:.join("\n ")}\n\n"
468
+ file.puts "Gems:"
469
+ Gem.loaded_specs.values.map {|x| file.puts "#{x.name} #{x.version} #{x.platform}"}
470
+ file.puts ""
471
+ file.puts "All Threads Backtraces:"
472
+ Thread.list.each do |thread|
473
+ file.puts thread.backtrace.join("\n")
474
+ file.puts
475
+ end
476
+ file.puts ""
477
+ file.puts ""
478
+ ensure
479
+ file.close
480
+ end
481
+ end
482
+ return log_file
483
+ end
484
+
485
+ # Writes a log file with information about unexpected output
486
+ #
487
+ # @param[String] text The unexpected output text
488
+ # @param [String] filename String to append to the exception log filename.
489
+ # The filename will start with a date/time stamp.
490
+ # @param [String] log_dir By default this method will write to the COSMOS
491
+ # default log directory. By setting this parameter you can override the
492
+ # directory the log will be written to.
493
+ # @return [String|nil] The fully pathed log file name or nil if there was
494
+ # an error creating the log file.
495
+ def self.write_unexpected_file(text, filename = 'unexpected', log_dir = nil)
496
+ log_file = create_log_file(filename, log_dir) do |file|
497
+ begin
498
+ file.puts "Unexpected Output:\n\n"
499
+ file.puts text
500
+ ensure
501
+ file.close
502
+ end
503
+ end
504
+ return log_file
505
+ end
506
+
507
+ # Catch fatal exceptions within the block
508
+ # This is intended to catch exceptions before the GUI is available
509
+ def self.catch_fatal_exception
510
+ begin
511
+ yield
512
+ rescue Exception => error
513
+ unless error.class == SystemExit or error.class == Interrupt
514
+ Logger.level = Logger::FATAL
515
+ Cosmos.handle_fatal_exception(error, false)
516
+ end
517
+ end
518
+ end
519
+
520
+ # Write a message to the Logger, write an exception file, and popup a GUI
521
+ # window if try_gui. Finally 'exit 1' is called to end the calling program.
522
+ #
523
+ # @param error [Exception] The exception to handle
524
+ # @param try_gui [Boolean] Whether to try and create a GUI exception popup
525
+ def self.handle_fatal_exception(error, try_gui = true)
526
+ $cosmos_fatal_exception = error
527
+ log_file = self.write_exception_file(error)
528
+ Logger.level = Logger::FATAL unless try_gui
529
+ Logger.fatal "Fatal Exception! Exiting..."
530
+ Logger.fatal error.formatted
531
+ if defined? ExceptionDialog and try_gui and Qt::Application.instance
532
+ Qt.execute_in_main_thread(true) {||ExceptionDialog.new(nil, error, '', true, false, log_file)}
533
+ else
534
+ if $stdout != STDOUT
535
+ $stdout = STDOUT
536
+ Logger.fatal "Fatal Exception! Exiting..."
537
+ Logger.fatal error.formatted
538
+ end
539
+ sleep 1 # Allow the messages to be printed and then crash
540
+ exit 1
541
+ end
542
+ end
543
+
544
+ # CriticalErrors are errors that need to be brought to a user's attention but
545
+ # do not cause an exit. A good example is if the packet log writer fails and
546
+ # can no longer write the log file. Write a message to the Logger, write an
547
+ # exception file, and popup a GUI window if try_gui. Ensure the GUI only
548
+ # comes up once so this method can be called over and over by failing code.
549
+ #
550
+ # @param error [Exception] The exception to handle
551
+ # @param try_gui [Boolean] Whether to try and create a GUI exception popup
552
+ def self.handle_critical_exception(error, try_gui = true)
553
+ Logger.error "Critical Exception! #{error.formatted}"
554
+ if defined? ExceptionDialog and !ExceptionDialog.dialog_open?
555
+ log_file = self.write_exception_file(error)
556
+ if try_gui
557
+ Qt.execute_in_main_thread(true) {|| ExceptionDialog.new(nil, error, '', false, false, log_file)}
558
+ end
559
+ end
560
+ end
561
+
562
+ # Creates a Ruby Thread to run the given block. Rescues any exceptions and
563
+ # retries the threads the given number of times before handling the thread
564
+ # death by calling {Cosmos.handle_fatal_exception}.
565
+ #
566
+ # @param name [String] Name of the thread
567
+ # @param retry_attempts [Integer] The number of times to allow the thread to
568
+ # restart before exiting
569
+ def self.safe_thread(name, retry_attempts = 0)
570
+ Thread.new do
571
+ retry_count = 0
572
+ begin
573
+ yield
574
+ rescue Exception => error
575
+ Logger.error "#{name} thread unexpectedly died. Retries: #{retry_count} of #{retry_attempts}"
576
+ Logger.error error.formatted
577
+ retry_count += 1
578
+ if retry_count <= retry_attempts
579
+ self.write_exception_file(error)
580
+ retry
581
+ end
582
+ handle_fatal_exception(error)
583
+ end
584
+ end
585
+ end
586
+
587
+ # Require the class represented by the filename. This uses the standard Ruby
588
+ # convention of having a single class per file where the class name is camel
589
+ # cased and filename is lowercase with underscores.
590
+ #
591
+ # @param class_filename [String] The name of the file which contains the
592
+ # Ruby class to require
593
+ def self.require_class(class_filename)
594
+ class_name = class_filename.filename_to_class_name
595
+ return class_name.to_class if class_name.to_class and defined? class_name.to_class
596
+ self.require_file(class_filename)
597
+ klass = class_name.to_class
598
+ if klass
599
+ return klass
600
+ else
601
+ raise "Ruby class #{class_name} not found"
602
+ end
603
+ end
604
+
605
+ # Requires a file with a standard error message if it fails
606
+ #
607
+ # @param filename [String] The name of the file to require
608
+ def self.require_file(filename)
609
+ begin
610
+ require filename
611
+ rescue Exception => err
612
+ msg = "Unable to require #{filename} due to #{err.message}. Ensure #{filename} is in the COSMOS lib directory."
613
+ Logger.error msg
614
+ raise msg
615
+ end
616
+ end
617
+
618
+ # @param filename [String] Name of the file to open in the editor
619
+ def self.open_in_text_editor(filename)
620
+ if filename
621
+ if Kernel.is_windows?
622
+ if File.extname(filename).to_s.downcase == '.csv'
623
+ self.run_process("cmd /c \"start wordpad \"#{filename.gsub('/','\\')}\"\"")
624
+ else
625
+ self.run_process("cmd /c \"start \"\" \"#{filename.gsub('/','\\')}\"\"")
626
+ end
627
+ elsif Kernel.is_mac?
628
+ self.run_process("open -a TextEdit \"#{filename}\"")
629
+ else
630
+ which_gedit = `which gedit 2>&1`.chomp
631
+ if which_gedit =~ /Command not found/i or which_gedit =~ /no .* in/i
632
+ # No gedit
633
+ editor = ENV['EDITOR']
634
+ editor = 'vi' unless editor
635
+ which_xterm = `which xterm 2>&1`.chomp
636
+ if which_xterm =~ /Command not found/i or which_xterm =~ /no .* in/i
637
+ # No xterm
638
+ which_gnome_terminal = `which gnome-terminal 2>&1`.chomp
639
+ if which_gnome_terminal =~ /Command not found/i or which_gnome_terminal =~ /no .* in/i
640
+ # No gnome-terminal - Do nothing
641
+ else
642
+ # Have gnome-terminal
643
+ system_call = "gnome-terminal -e #{editor} \"#{filename}\""
644
+ end
645
+ else
646
+ # Have xterm
647
+ system_call = "xterm -e #{editor} \"#{filename}\""
648
+ end
649
+ else
650
+ # Have gedit
651
+ system_call = "gedit \"#{filename}\""
652
+ end
653
+ self.run_process(system_call)
654
+ end
655
+ end
656
+ end
657
+
658
+ # @param filename [String] Name of the file to open in the web browser
659
+ def self.open_in_web_browser(filename)
660
+ if filename
661
+ if Kernel.is_windows?
662
+ self.run_process("cmd /c \"start \"\" \"#{filename.gsub('/','\\')}\"\"")
663
+ elsif Kernel.is_mac?
664
+ self.run_process("open -a Safari \"#{filename}\"")
665
+ else
666
+ which_firefox = `which firefox`.chomp
667
+ if which_firefox =~ /Command not found/i or which_firefox =~ /no .* in/i
668
+ raise "Firefox not found"
669
+ else
670
+ system_call = "#{which_firefox} \"#{filename}\""
671
+ end
672
+ self.run_process(system_call)
673
+ end
674
+ end
675
+ end
676
+
677
+ # Temporarily set the working directory during a block
678
+ def self.set_working_dir(working_dir = Cosmos::USERPATH)
679
+ current_dir = Dir.pwd
680
+ Dir.chdir(working_dir)
681
+ begin
682
+ yield
683
+ ensure
684
+ Dir.chdir(current_dir)
685
+ end
686
+ end
687
+
688
+ # Attempt to gracefully kill a thread
689
+ # @param owner Object that owns the thread and may have a graceful_kill method
690
+ # @param thread The thread to gracefully kill
691
+ # @param graceful_timeout Timeout in seconds to wait for it to die gracefully
692
+ # @param timeout_interval How often to poll for aliveness
693
+ # @param hard_timeout Timeout in seconds to wait for it to die ungracefully
694
+ def self.kill_thread(owner, thread, graceful_timeout = 1, timeout_interval = 0.01, hard_timeout = 1)
695
+ if thread
696
+ if owner and owner.respond_to? :graceful_kill
697
+ if Thread.current != thread
698
+ owner.graceful_kill
699
+ end_time = Time.now + graceful_timeout
700
+ while thread.alive? && ((end_time - Time.now) > 0)
701
+ sleep(timeout_interval)
702
+ end
703
+ else
704
+ Logger.warn "Threads cannot graceful_kill themselves"
705
+ end
706
+ elsif owner
707
+ Logger.info "Thread owner #{owner.class} does not support graceful_kill"
708
+ end
709
+ if thread.alive?
710
+ # Graceful failed
711
+ Logger.warn "Failed to gracefully kill thread:\n Caller Backtrace:\n #{caller().join("\n ")}\n \n Thread Backtrace:\n #{thread.backtrace.join("\n ")}\n\n"
712
+ thread.kill
713
+ end_time = Time.now + hard_timeout
714
+ while thread.alive? && ((end_time - Time.now) > 0)
715
+ sleep(timeout_interval)
716
+ end
717
+ end
718
+ if thread.alive?
719
+ Logger.error "Failed to kill thread"
720
+ end
721
+ end
722
+ end
723
+
724
+ # Close a socket in a manner that ensures that any reads blocked in select
725
+ # will unblock across platforms
726
+ # @param socket The socket to close
727
+ def self.close_socket(socket)
728
+ if socket
729
+ # Calling shutdown and then sleep seems to be required
730
+ # to get select to reliably unblock on linux
731
+ begin
732
+ socket.shutdown(:RDWR)
733
+ sleep(0)
734
+ rescue Exception
735
+ # Oh well we tried
736
+ end
737
+ begin
738
+ socket.close unless socket.closed?
739
+ rescue Exception
740
+ # Oh well we tried
741
+ end
742
+ end
743
+ end
744
+
745
+ # Play a wav file
746
+ # @param wav_filename filename of the wav file
747
+ def self.play_wav_file(wav_filename)
748
+ if defined? Qt and wav_filename
749
+ Qt.execute_in_main_thread(true) do
750
+ if Qt::CoreApplication.instance and Qt::Sound.isAvailable
751
+ Cosmos.set_working_dir do
752
+ Qt::Sound.play(wav_filename.to_s)
753
+ end
754
+ end
755
+ end
756
+ end
757
+ end
758
+
759
+ end