cosmos 3.8.3 → 3.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/Manifest.txt +14 -0
  4. data/Rakefile +35 -2
  5. data/autohotkey/config/targets/INST/screens/_footer.txt +4 -0
  6. data/autohotkey/config/targets/INST/screens/hs.txt +1 -4
  7. data/autohotkey/config/tools/table_manager/OldOneDimensionalTable_def.txt +19 -0
  8. data/autohotkey/config/tools/table_manager/OldTwoDimensionalTable_def.txt +248 -0
  9. data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +27 -15
  10. data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +12 -232
  11. data/autohotkey/procedures/example_test.rb +4 -0
  12. data/autohotkey/tools/TableManagerAHK +4 -9
  13. data/autohotkey/tools/TableManagerAHK2 +18 -0
  14. data/autohotkey/tools/TableManagerAHK3 +18 -0
  15. data/autohotkey/tools/TableManagerAHK4 +24 -0
  16. data/autohotkey/tools/TlmViewerAHK +1 -1
  17. data/autohotkey/tools/autohotkey.rb +2 -1
  18. data/autohotkey/tools/open_gl_builder.ahk +1 -1
  19. data/autohotkey/tools/table_manager.ahk +141 -70
  20. data/cosmos.gemspec +3 -3
  21. data/data/crc.txt +70 -68
  22. data/data/legal.txt +4 -5
  23. data/demo/config/data/crc.txt +10 -9
  24. data/demo/config/targets/INST/screens/_footer.txt +4 -0
  25. data/demo/config/targets/INST/screens/hs.txt +1 -6
  26. data/demo/config/targets/INST/screens/limits.txt +3 -11
  27. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
  28. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +33 -22
  29. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +30 -22
  30. data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -7
  31. data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +13 -13
  32. data/demo/lib/example_background_task.rb +6 -12
  33. data/demo/procedures/example_test.rb +5 -0
  34. data/lib/cosmos/conversions/conversion.rb +3 -7
  35. data/lib/cosmos/core_ext/class.rb +3 -1
  36. data/lib/cosmos/core_ext/file.rb +1 -0
  37. data/lib/cosmos/core_ext/io.rb +18 -0
  38. data/lib/cosmos/core_ext/range.rb +1 -5
  39. data/lib/cosmos/core_ext/time.rb +3 -3
  40. data/lib/cosmos/gui/dialogs/about_dialog.rb +60 -36
  41. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +10 -14
  42. data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +4 -5
  43. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +31 -17
  44. data/lib/cosmos/gui/dialogs/details_dialog.rb +63 -47
  45. data/lib/cosmos/gui/dialogs/exception_dialog.rb +77 -68
  46. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +6 -5
  47. data/lib/cosmos/gui/dialogs/legal_dialog.rb +34 -21
  48. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +19 -43
  49. data/lib/cosmos/gui/dialogs/progress_dialog.rb +79 -42
  50. data/lib/cosmos/gui/dialogs/pry_dialog.rb +9 -5
  51. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +6 -4
  52. data/lib/cosmos/gui/dialogs/select_dialog.rb +23 -18
  53. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +34 -10
  54. data/lib/cosmos/gui/dialogs/splash.rb +18 -8
  55. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +38 -43
  56. data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +51 -53
  57. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +1 -1
  58. data/lib/cosmos/gui/line_graph/lines.rb +1 -1
  59. data/lib/cosmos/gui/qt.rb +9 -2
  60. data/lib/cosmos/gui/qt_tool.rb +50 -8
  61. data/lib/cosmos/gui/widgets/packet_log_frame.rb +53 -27
  62. data/lib/cosmos/interfaces/linc_interface.rb +103 -62
  63. data/lib/cosmos/io/json_drb_object.rb +3 -3
  64. data/lib/cosmos/io/raw_logger.rb +4 -8
  65. data/lib/cosmos/io/tcpip_server.rb +2 -2
  66. data/lib/cosmos/packets/binary_accessor.rb +1 -1
  67. data/lib/cosmos/packets/limits.rb +2 -5
  68. data/lib/cosmos/packets/packet.rb +1 -1
  69. data/lib/cosmos/packets/packet_config.rb +54 -19
  70. data/lib/cosmos/packets/parsers/packet_item_parser.rb +7 -1
  71. data/lib/cosmos/script/scripting.rb +4 -5
  72. data/lib/cosmos/system/system.rb +2 -1
  73. data/lib/cosmos/system/target.rb +4 -0
  74. data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +13 -5
  75. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +37 -27
  76. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +6 -2
  77. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +7 -5
  78. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +21 -10
  79. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +11 -11
  80. data/lib/cosmos/tools/script_runner/script_runner.rb +2 -18
  81. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +6 -6
  82. data/lib/cosmos/tools/table_manager/table.rb +32 -41
  83. data/lib/cosmos/tools/table_manager/table_config.rb +140 -729
  84. data/lib/cosmos/tools/table_manager/table_item.rb +20 -36
  85. data/lib/cosmos/tools/table_manager/table_item_parser.rb +46 -0
  86. data/lib/cosmos/tools/table_manager/table_manager.rb +754 -691
  87. data/lib/cosmos/tools/table_manager/table_manager_core.rb +172 -358
  88. data/lib/cosmos/tools/table_manager/table_parser.rb +75 -0
  89. data/lib/cosmos/tools/test_runner/results_writer.rb +1 -1
  90. data/lib/cosmos/tools/test_runner/test_runner.rb +11 -0
  91. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +2 -2
  92. data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +2 -2
  93. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +2 -2
  94. data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +4 -4
  95. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +13 -13
  96. data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +9 -9
  97. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +9 -9
  98. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +4 -4
  99. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1 -1
  100. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +8 -18
  101. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +7 -4
  102. data/lib/cosmos/top_level.rb +12 -0
  103. data/lib/cosmos/version.rb +5 -5
  104. data/run_gui_tests.bat +6 -0
  105. data/spec/core_ext/array_spec.rb +1 -1
  106. data/spec/interfaces/linc_interface_spec.rb +4 -4
  107. data/spec/io/json_drb_spec.rb +2 -2
  108. data/spec/io/json_rpc_spec.rb +1 -1
  109. data/spec/io/raw_logger_spec.rb +5 -1
  110. data/spec/packet_logs/packet_log_writer_spec.rb +1 -1
  111. data/spec/packets/packet_config_spec.rb +144 -0
  112. data/spec/packets/parsers/packet_item_parser_spec.rb +60 -0
  113. data/spec/spec_helper.rb +11 -0
  114. data/spec/system/target_spec.rb +5 -1
  115. data/spec/tools/cmd_tlm_server/background_task_spec.rb +15 -3
  116. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +117 -31
  117. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +4 -0
  118. data/spec/tools/launcher/launcher_config_spec.rb +1 -1
  119. data/spec/tools/table_manager/table_config_spec.rb +226 -0
  120. data/spec/tools/table_manager/table_item_spec.rb +57 -0
  121. data/spec/tools/table_manager/table_parser_spec.rb +96 -0
  122. data/spec/tools/table_manager/table_spec.rb +90 -0
  123. data/spec/tools/table_manager/tablemanager_core_spec.rb +557 -0
  124. data/spec/top_level/top_level_spec.rb +9 -0
  125. data/spec/utilities/csv_spec.rb +3 -3
  126. metadata +30 -11
@@ -12,278 +12,169 @@ require 'cosmos'
12
12
  require 'cosmos/tools/table_manager/table_config'
13
13
 
14
14
  module Cosmos
15
-
15
+ # Provides the low level Table Manager methods which do not require a GUI.
16
16
  class TableManagerCore
17
- # the currently opened definition file
18
- attr_reader :current_def
19
-
20
- # the currently opened binary file
21
- attr_reader :current_bin
17
+ # Generic error raised when a more specific error doesn't work
18
+ class CoreError < StandardError; end
19
+ # Raised when opening a file that is either larger or smaller than its definition
20
+ class MismatchError < CoreError; end
21
+ # Raised when there is no current table configuration
22
+ class NoConfigError < CoreError
23
+ # @return [String] Error message
24
+ def message
25
+ "No current table configuration"
26
+ end
27
+ end
28
+ # Raised when there is no table in the current configuration
29
+ class NoTableError < CoreError
30
+ # @return [String] Error message
31
+ def message
32
+ "Table does not exist in current configuration"
33
+ end
34
+ end
22
35
 
23
- # an instance of TableDefinition
24
- attr_reader :table_def
36
+ # @return [TableConfig] Configuration instance
37
+ attr_reader :config
25
38
 
39
+ # Create the instance
26
40
  def initialize
27
41
  reset()
28
42
  end
29
43
 
44
+ # Clears the configuration
30
45
  def reset
31
- @current_bin = nil
32
- @current_def = nil
33
- @table_def = nil
46
+ @config = nil
34
47
  end
35
48
 
49
+ # @param filename [String] Create a new TableConfig instance and process the filename
36
50
  def process_definition(filename)
37
- @table_def = TableConfig.new()
38
- @table_def.process(filename)
51
+ @config = TableConfig.new()
52
+ @config.process_file(filename)
39
53
  end
40
54
 
41
- # INTERFACE METHODS
42
-
43
- # Creates new binary files based on a list of definition files and an destination directory
44
- def file_new(def_files, output_dir, bar = nil)
45
- bin_files = []
46
- begin
47
- progress = 0.0
48
- progress_increment = 100.0 / def_files.length.to_f / 4.0
55
+ # @param def_path [String] Definition file to process
56
+ # @param output_dir [String] Output directory to create the new file
57
+ # @return [String] Binary file path
58
+ def file_new(def_path, output_dir)
59
+ progress = 0.0
60
+ process_definition(def_path)
61
+ yield 0.3 if block_given?
49
62
 
50
- def_files.each do |def_file|
51
- @current_def = def_file
63
+ @config.table_names.each {|table_name| set_binary_data_to_default(table_name) }
64
+ yield 0.7 if block_given?
52
65
 
53
- process_definition(def_file)
54
- if bar
55
- progress += progress_increment
56
- bar.progress = progress.to_i
57
- end
58
-
59
- # Initialize all values to defaults
60
- @table_def.get_all_tables.each do |table|
61
- set_binary_data_to_default(table.name)
62
- end
63
-
64
- if bar
65
- progress += progress_increment
66
- bar.progress = progress.to_i
67
- end
68
-
69
- # Now verify the tables makes sense as defined by the table definition.
70
- # It's possible to have a definition file with default values outside
71
- # the allowable range so we check for that here.
72
- result = file_check()
73
- unless result.empty?
74
- reset()
75
- raise "The table definition file has incompatibilities. Please fix the following errors:\n\n" << result
76
- end
77
-
78
- if bar
79
- progress += progress_increment
80
- bar.progress = progress.to_i
81
- end
82
-
83
- if File.basename(def_file) =~ /_def\.txt/
84
- basename = File.basename(def_file)[0...-8] # Get the basename without the _def.txt
85
- else
86
- basename = File.basename(def_file).split('.')[0...-1].join('.') # Get the basename without the extension
87
- end
88
-
89
- # Set the current_bin so the file_report function works correctly
90
- @current_bin = File.join(output_dir, "#{basename}.dat")
91
- file_save(@current_bin)
92
- bin_files << @current_bin
93
- if bar
94
- progress += progress_increment
95
- bar.progress = progress.to_i
96
- end
97
- file_report()
98
- end
99
-
100
- bar.progress = 100 if bar
101
- sleep(0.5)
102
- ensure
103
- reset()
104
- end
105
- bin_files
66
+ bin_path = File.join(output_dir, def_to_bin_filename(def_path))
67
+ file_save(bin_path)
68
+ bin_path
106
69
  end
107
70
 
108
- # Opens a specified binary file using a specified definition file as the interpreter
109
- def file_open(def_file, bin_file)
110
- @current_bin = bin_file
111
- @current_def = def_file
112
- process_definition(def_file)
113
- open_and_load_binary_file(bin_file)
71
+ # @param bin_path [String] Binary file to open
72
+ # @param def_path [String] Definition file to use when opening
73
+ def file_open(bin_path, def_path)
74
+ process_definition(def_path)
75
+ open_and_load_binary_file(bin_path)
114
76
  end
115
77
 
116
- def file_save(filename = nil)
117
- raise "Please open a table first." unless @table_def
118
- @current_bin = filename if filename
119
-
120
- result = file_check()
121
- unless result.empty?
122
- raise "Please fix the following errors before saving:\n\n" << result
123
- end
124
-
125
- # Call the user defined function on_save to allow additional processing
126
- # before the file is written out
127
- on_save()
128
-
129
- File.open(@current_bin, "wb") do |file|
130
- @table_def.get_all_tables.each do |table|
78
+ # Saves the current tables in the config instance to the given filename.
79
+ #
80
+ # @param filename [String] Filename to write, overwritten if it exists.
81
+ def file_save(filename)
82
+ raise NoConfigError unless @config
83
+ file_check()
84
+ File.open(filename, "wb") do |file|
85
+ @config.tables.each do |table_name, table|
131
86
  file.write(table.buffer)
132
87
  end
133
88
  end
89
+ file_report(filename, @config.filename)
134
90
  end
135
91
 
92
+ # @return [String] Success string if parameters all check. Raises
93
+ # a CoreError if errors are found.
136
94
  def file_check
137
- raise "Please open a table first." unless @table_def
138
-
95
+ raise NoConfigError unless @config
139
96
  result = ""
140
- @table_def.get_all_tables.each do |table|
141
- table_result = table_check(table.name)
97
+ @config.table_names.each do |name|
98
+ table_result = table_check(name)
142
99
  unless table_result.empty?
143
- result << "Error(s) in #{table.name}:\n" + table_result
100
+ result << "Errors in #{name}:\n" + table_result
144
101
  end
145
102
  end
146
- result
147
- end
148
-
149
- def file_hex
150
- raise "Please open a table first." unless @table_def
151
-
152
- data = ""
153
- # collect the data from each table
154
- @table_def.get_all_tables.each do |table|
155
- data << table.buffer
156
- end
157
-
158
- "#{data.formatted}\n\nTotal Bytes Read: #{data.length}"
103
+ raise CoreError, result unless result.empty?
104
+ "All parameters are within their constraints."
159
105
  end
160
106
 
161
- # Generate the RPT file for the currently opened file
162
- def file_report
163
- raise "Please open a table first." unless @table_def
164
-
165
- result = file_check()
166
- unless result.empty?
167
- raise "Please fix the following errors before generating the report:\n\n" << result
168
- end
169
-
170
- filename = File.basename(@current_bin, ".dat")
171
- File.open(File.join(File.dirname(@current_bin), "#{filename}.rpt"), 'w+') do |file|
172
- file.write("File Definition: #{@current_def}\n")
173
- file.write("File Binary: #{@current_bin}\n\n")
174
- @table_def.get_all_tables.each do |table|
107
+ # Create a CSV report file based on the file contents.
108
+ #
109
+ # @param bin_path [String] Binary filename currently open. Used to generate the
110
+ # report name such that it matches the binary filename.
111
+ # @param def_path [String] Definition filename currently open
112
+ # @return [String] Report filename path
113
+ def file_report(bin_path, def_path)
114
+ raise NoConfigError unless @config
115
+ file_check()
116
+
117
+ basename = File.basename(bin_path, ".dat")
118
+ report_path = File.join(File.dirname(bin_path), "#{basename}.csv")
119
+ File.open(report_path, 'w+') do |file|
120
+ file.write("File Definition, #{def_path}\n")
121
+ file.write("File Binary, #{bin_path}\n\n")
122
+ @config.tables.values.each do |table|
175
123
  items = table.sorted_items
176
- file.puts(table.name)
177
-
178
- column_lengths = []
124
+ file.puts(table.table_name)
179
125
 
126
+ # Write the column headers
180
127
  if table.type == :TWO_DIMENSIONAL
181
- column_lengths[0] = "Item".length
128
+ columns = ["Item"]
129
+ # Remove the '0' from the 'itemname0'
130
+ table.num_columns.times.each {|x| columns << items[x].name[0...-1] }
131
+ file.puts columns.join(", ")
182
132
  else
183
- column_lengths[0] = "Label".length
133
+ file.puts "Label, Value"
184
134
  end
185
135
 
186
- # Determine the maximum length of all the row header text in the table
187
- # Basically we're treating the row headers as column 0 when we output
188
- # the data which is why we set column_lengths[0] with the row text length
136
+ # Write the table item values
189
137
  (0...table.num_rows).each do |r|
190
138
  if table.type == :TWO_DIMENSIONAL
191
- rowtext = "#{r+1}"
139
+ rowtext = "#{r + 1}"
192
140
  else
193
141
  rowtext = items[r].name
194
142
  end
195
143
 
196
- if rowtext.length > column_lengths[0]
197
- column_lengths[0] = rowtext.length
198
- end
199
- end
200
-
201
- # Collect the column header text length in the table
202
- # Since the row headers were column 0 that is why we increment the column
203
- # header by 1 (column_lengths[c+1]) before setting the column text length
204
- (0...table.num_columns).each do |c|
205
- if table.type == :TWO_DIMENSIONAL
206
- columntext = items[c].name[0...-1]
207
- else
208
- columntext = "Value"
209
- end
210
- column_lengths[c+1] = columntext.length
211
- end
212
-
213
- # Determine the maximum length item in each column of the table
214
- # We can simply go throught the gui table by row and column looking for
215
- # the widest value
216
- (0...table.num_rows).each do |r|
144
+ file.write "#{rowtext}, "
217
145
  (0...table.num_columns).each do |c|
218
146
  if table.type == :TWO_DIMENSIONAL
219
- item_def = items[c + r * table.num_columns]
147
+ table_item = items[c + r * table.num_columns]
220
148
  else
221
- item_def = items[r]
222
- end
223
- value = item_to_report_string(table, item_def)
224
-
225
- if value.length > column_lengths[c+1]
226
- column_lengths[c+1] = value.length
149
+ table_item = items[r]
227
150
  end
228
151
 
229
- end
230
- end
231
-
232
- # Write out the first column header depending on the table type
233
- if table.type == :TWO_DIMENSIONAL
234
- file.printf("%-#{column_lengths[0]}s ", "Item")
235
- else
236
- file.printf("%-#{column_lengths[0]}s ", "Label")
237
- end
238
-
239
- # Write out all the column header text
240
- (0...table.num_columns).each do |c|
241
- if table.type == :TWO_DIMENSIONAL
242
- columntext = items[c].name[0...-1]
243
- else
244
- columntext = "Value"
245
- end
246
-
247
- file.printf("%-#{column_lengths[c+1]}s ", columntext)
248
- end
249
- file.write("\n")
250
-
251
- # Write out the table items
252
- (0...table.num_rows).each do |r|
253
- if table.type == :TWO_DIMENSIONAL
254
- rowtext = "#{r+1}"
255
- else
256
- rowtext = items[r].name
257
- end
258
-
259
- file.printf("%-#{column_lengths[0]}s ", rowtext)
260
- (0...table.num_columns).each do |c|
261
- if table.type == :TWO_DIMENSIONAL
262
- item_def = items[c + r * table.num_columns]
263
- else
264
- item_def = items[r]
265
- end
266
-
267
- value = item_to_report_string(table, item_def)
268
-
269
- file.printf("%-#{column_lengths[c+1]}s ", value)
270
-
152
+ file.write "#{table.read(table_item.name, :FORMATTED).to_s}, "
271
153
  end
272
154
  file.write("\n") # newline after each row
273
155
  end
274
156
  file.write("\n") # newline after each table
275
- end # end @table_def.get_all_tables.each do |table|
157
+ end
276
158
  end
159
+ report_path
277
160
  end
278
161
 
279
- def table_check(table_name)
280
- raise "Please open a table first." unless @table_def
162
+ # Create a hex formatted string of all the file data
163
+ def file_hex
164
+ raise NoConfigError unless @config
165
+ data = ""
166
+ @config.tables.values.each {|table| data << table.buffer }
167
+ "#{data.formatted}\n\nTotal Bytes Read: #{data.length}"
168
+ end
281
169
 
282
- table = @table_def.get_table(table_name)
283
- raise "Please open a table first." unless table
170
+ # @param table_name [String] Name of the table to check for out of range values
171
+ def table_check(table_name)
172
+ raise NoConfigError unless @config
173
+ table = @config.table(table_name)
174
+ raise NoTableError unless table
284
175
 
285
176
  result = ""
286
- item_defs = table.sorted_items
177
+ table_items = table.sorted_items
287
178
 
288
179
  # Check the ranges and constraints for each item in the table
289
180
  # We go through it this way (by row and columns) so we can grab the actual
@@ -291,35 +182,26 @@ module Cosmos
291
182
  (0...table.num_rows).each do |r|
292
183
  (0...table.num_columns).each do |c|
293
184
  # get the table item definition so we know how to save it
294
- item_def = item_defs[r * table.num_columns + c]
295
-
296
- # if a constraint was defined call it here
297
- # this should set the underlying constraints
298
- if (item_def.constraint != nil)
299
- item_def.constraint.call(item_def, table, table.buffer)
300
- end
301
-
302
- x = table.read(item_def.name, :RAW)
303
- if item_def.data_type == :STRING
304
- if x.length > item_def.bit_size / 8
305
- result << " #{item_def.name}: #{x} must be less than #{item_def.bit_size / 8} characters\n"
185
+ table_item = table_items[r * table.num_columns + c]
186
+
187
+ value = table.read(table_item.name)
188
+ unless table_item.range.nil?
189
+ # If the item has states which include the value, then convert
190
+ # the state back to the numeric value for range checking
191
+ if table_item.states && table_item.states.include?(value)
192
+ value = table_item.states[value]
306
193
  end
307
- end
308
-
309
- unless item_def.range.nil?
310
194
  # check to see if the value lies within its valid range
311
- if not item_def.range.include?(x)
312
- # if the value is displayed as hex, display the range as hex
313
- if item_def.display_type == :HEX
314
- range_first = "0x%X" % item_def.range.first
315
- range_last = "0x%X" % item_def.range.last
316
- x = "0x%X" % x
195
+ unless table_item.range.include?(value)
196
+ if table_item.format_string
197
+ value = table.read(table_item.name, :FORMATTED)
198
+ range_first = sprintf(table_item.format_string, table_item.range.first)
199
+ range_last = sprintf(table_item.format_string, table_item.range.last)
317
200
  else
318
- range_first = item_def.range.first
319
- range_last = item_def.range.last
320
- x = table.read(item_def.name)
201
+ range_first = table_item.range.first
202
+ range_last = table_item.range.last
321
203
  end
322
- result << " #{item_def.name}: #{x} outside valid range of #{range_first}..#{range_last}\n"
204
+ result << " #{table_item.name}: #{value} outside valid range of #{range_first}..#{range_last}\n"
323
205
  end
324
206
  end
325
207
  end # end each column
@@ -327,150 +209,84 @@ module Cosmos
327
209
  result
328
210
  end
329
211
 
212
+ # @param table_name [String] Name of the table to revert all values to default
330
213
  def table_default(table_name)
331
- raise "Please open a table first." unless @table_def
214
+ raise NoConfigError unless @config
332
215
  set_binary_data_to_default(table_name)
333
216
  end
334
217
 
335
- # option to display a dialog containing a hex dump of the current table values
218
+ # @param table_name [String] Create a hex formatted string of the given table data
336
219
  def table_hex(table_name)
337
- raise "Please open a table first." unless @table_def
338
- table = @table_def.get_table(table_name)
339
- raise "Please open a table first." unless table
340
-
220
+ raise NoConfigError unless @config
221
+ table = @config.table(table_name)
222
+ raise NoTableError unless table
341
223
  "#{table.buffer.formatted}\n\nTotal Bytes Read: #{table.buffer.length}"
342
224
  end
343
225
 
344
- # option to save the currently displayed table as a stand alone binary file
226
+ # @param table_name [String] Table name to write as a stand alone file
227
+ # @param filename [String] Filename to write the table data to. Existing
228
+ # files will be overwritten.
345
229
  def table_save(table_name, filename)
346
- raise "Please open a table first." unless @table_def
347
-
230
+ raise NoConfigError unless @config
348
231
  result = table_check(table_name)
349
- unless result.empty?
350
- raise "Please fix the following errors before saving:\n\n" << result
351
- end
352
-
353
- File.open(filename, 'wb') do |datafile|
354
- table = @table_def.get_table(table_name)
355
- datafile.write(table.buffer)
356
- end
232
+ raise CoreError, "Errors in #{table_name}:\n#{result}" unless result.empty?
233
+ File.open(filename, 'wb') {|file| file.write(@config.table(table_name).buffer) }
357
234
  end
358
235
 
359
- # option to save the currently displayed table to an existing table binary file
360
- # containing that table.
236
+ # Commit a table from the current configuration into a new binary
237
+ #
238
+ # @param table_name [String] Table name to commit to an existing binary
239
+ # @param bin_file [String] Binary file to open
240
+ # @param def_file [String] Definition file to use when opening
361
241
  def table_commit(table_name, bin_file, def_file)
362
- raise "Please open a table first." unless @table_def
363
- save_table = @table_def.get_table(table_name)
364
- raise "Please open a table first." unless save_table
242
+ raise NoConfigError unless @config
243
+ save_table = @config.table(table_name)
244
+ raise NoTableError unless save_table
365
245
 
366
- result = file_check()
367
- unless result.empty?
368
- raise "Please fix the following errors before saving:\n\n" << result
369
- end
370
-
371
- @current_bin = bin_file
372
- @current_def = def_file
246
+ result = table_check(table_name)
247
+ raise CoreError, "Errors in #{table_name}:\n#{result}" unless result.empty?
373
248
 
374
- parser = TableConfig.new
249
+ config = TableConfig.new
375
250
  begin
376
- parser.process(def_file)
251
+ config.process_file(def_file)
377
252
  rescue => err
378
- raise "The table definition file:#{def_file} has the following errors:\n#{err}"
253
+ raise CoreError, "The table definition file:#{def_file} has the following errors:\n#{err}"
379
254
  end
380
255
 
381
- if !parser.get_table_names.include?(table_name)
382
- raise "#{table_name} not found in #{def_file} table definition file."
256
+ if !config.table_names.include?(table_name.upcase)
257
+ raise NoTableError, "#{table_name} not found in #{def_file} table definition file."
383
258
  end
384
259
 
385
- @table_def = parser
260
+ saved_config = @config
261
+ @config = config
386
262
  open_and_load_binary_file(bin_file)
387
263
 
388
264
  # Store the saved table data in the new table definition
389
- table = @table_def.get_table(save_table.name)
265
+ table = config.table(save_table.table_name)
390
266
  table.buffer = save_table.buffer[0...table.length]
391
267
  file_save(bin_file)
268
+ @config = saved_config
392
269
  end
393
270
 
394
- # Updates the definition file for a table.
395
- def table_update_def(table_name)
396
- raise "Please open a table first." unless @table_def
397
-
398
- # Check to see that the table definition file is writeable
399
- table = @table_def.get_table(table_name)
400
- raise "Please open a table first." unless table
401
-
402
- if !File.writable?(table.filename)
403
- raise "#{table.filename} is not writeable."
404
- end
405
-
406
- # Check for errors in the table before updating the defaults
407
- result = table_check(table_name)
408
- unless result.empty?
409
- raise "Please fix the following errors before updating the definition file:\n\n" << result
410
- end
411
-
412
- begin
413
- @table_def.commit_default_values(table)
414
- rescue => err
415
- raise "The table definition file could not be written due to the following error(s):\n#{err}"
416
- end
417
- end
418
-
419
- # Return a GenericTable given a String table name
420
- def get_table(table_name)
421
- @table_def.get_table(table_name)
422
- end
423
-
424
- # Retrieves a value from a table
425
- def get_table_item(table_name, item_name)
426
- @table_def.get_table(table_name).read(item_name)
427
- end
428
-
429
- # Updates a value in a table
430
- def set_table_item(table_name, item_name, value)
431
- @table_def.get_table(table_name).write(item_name, value)
432
- end
433
-
434
- # Override on_save to perform additional actions before the file is
435
- # saved to disk.
436
- def on_save
437
- end
438
-
439
- # Determines the string representation of an item as it should be printed in a RPT file
440
- def item_to_report_string(table, item_def)
441
- result = ""
442
- case item_def.display_type
443
- when :NONE
444
- result = "\n#{table.read(item_def.name).formatted}"
445
- when :STATE, :DEC, :STRING
446
- result = table.read(item_def.name).to_s
447
- when :CHECK
448
- value = table.read(item_def.name)
449
- if value == item_def.range.end
450
- result = "X (#{item_def.range.end.to_s})"
451
- else
452
- result = "- (#{item_def.range.begin.to_s})"
453
- end
454
- when :HEX
455
- result = @table_def.format_hex(table, item_def)
456
- end
457
- result
458
- end
271
+ protected
459
272
 
460
- # Set all the binary data in the table definition to the default values
273
+ # Set all the binary data in the table to the default values
461
274
  def set_binary_data_to_default(table_name)
462
- table = @table_def.get_table(table_name)
463
-
464
- # if we can't find the table do nothing
465
- return unless table
275
+ table = @config.table(table_name)
276
+ raise NoTableError unless table
277
+ table.restore_defaults
278
+ end
466
279
 
467
- table.sorted_items.each do |item_def|
468
- if item_def.data_type == :BLOCK
469
- table.write(item_def.name, item_def.default.hex_to_byte_string)
470
- else
471
- table.write(item_def.name, item_def.default)
472
- end
280
+ # Get the binary filename equivalent for the given definition filename
281
+ def def_to_bin_filename(def_path)
282
+ if File.basename(def_path) =~ /_def\.txt$/
283
+ # Remove _def.txt if present (should be)
284
+ basename = File.basename(def_path)[0...-8]
285
+ else
286
+ # Remove any extension if present
287
+ basename = File.basename(def_path, File.extname(def_path))
473
288
  end
289
+ "#{basename}.dat"
474
290
  end
475
291
 
476
292
  # Opens the given binary file and populates the table definition.
@@ -488,20 +304,18 @@ module Cosmos
488
304
 
489
305
  binary_data_index = 0
490
306
  total_table_length = 0
491
- @table_def.get_all_tables.each {|table| total_table_length += table.length }
492
- @table_def.get_all_tables.each do |table|
307
+ @config.tables.each {|table_name, table| total_table_length += table.length }
308
+ @config.tables.each do |table_name, table|
493
309
  if binary_data_index + table.length > data.length
494
310
  table.buffer = data[binary_data_index..-1]
495
- raise "Binary size of #{data.length} not large enough to fully represent table definition of length #{total_table_length}. The remaining table definition (starting with byte #{data.length - binary_data_index} in #{table.name}) will be filled with 0."
311
+ raise MismatchError, "Binary size of #{data.length} not large enough to fully represent table definition of length #{total_table_length}. The remaining table definition (starting with byte #{data.length - binary_data_index} in #{table.table_name}) will be filled with 0."
496
312
  end
497
- table.buffer = data[binary_data_index...binary_data_index+table.length]
313
+ table.buffer = data[binary_data_index...binary_data_index + table.length]
498
314
  binary_data_index += table.length
499
315
  end
500
316
  if binary_data_index < data.length
501
- raise "Binary size of #{data.length} larger than table definition of length #{total_table_length}. Discarding the remaing #{data.length - binary_data_index} bytes."
317
+ raise MismatchError, "Binary size of #{data.length} larger than table definition of length #{total_table_length}. Discarding the remaing #{data.length - binary_data_index} bytes."
502
318
  end
503
319
  end
504
-
505
320
  end
506
-
507
321
  end # module Cosmos