cosmos 3.5.1 → 3.5.2

Sign up to get free protection for your applications and to get access to all the features.
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