cosmos 3.8.3 → 3.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/Manifest.txt +14 -0
- data/Rakefile +35 -2
- data/autohotkey/config/targets/INST/screens/_footer.txt +4 -0
- data/autohotkey/config/targets/INST/screens/hs.txt +1 -4
- data/autohotkey/config/tools/table_manager/OldOneDimensionalTable_def.txt +19 -0
- data/autohotkey/config/tools/table_manager/OldTwoDimensionalTable_def.txt +248 -0
- data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +27 -15
- data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +12 -232
- data/autohotkey/procedures/example_test.rb +4 -0
- data/autohotkey/tools/TableManagerAHK +4 -9
- data/autohotkey/tools/TableManagerAHK2 +18 -0
- data/autohotkey/tools/TableManagerAHK3 +18 -0
- data/autohotkey/tools/TableManagerAHK4 +24 -0
- data/autohotkey/tools/TlmViewerAHK +1 -1
- data/autohotkey/tools/autohotkey.rb +2 -1
- data/autohotkey/tools/open_gl_builder.ahk +1 -1
- data/autohotkey/tools/table_manager.ahk +141 -70
- data/cosmos.gemspec +3 -3
- data/data/crc.txt +70 -68
- data/data/legal.txt +4 -5
- data/demo/config/data/crc.txt +10 -9
- data/demo/config/targets/INST/screens/_footer.txt +4 -0
- data/demo/config/targets/INST/screens/hs.txt +1 -6
- data/demo/config/targets/INST/screens/limits.txt +3 -11
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +33 -22
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +30 -22
- data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -7
- data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +13 -13
- data/demo/lib/example_background_task.rb +6 -12
- data/demo/procedures/example_test.rb +5 -0
- data/lib/cosmos/conversions/conversion.rb +3 -7
- data/lib/cosmos/core_ext/class.rb +3 -1
- data/lib/cosmos/core_ext/file.rb +1 -0
- data/lib/cosmos/core_ext/io.rb +18 -0
- data/lib/cosmos/core_ext/range.rb +1 -5
- data/lib/cosmos/core_ext/time.rb +3 -3
- data/lib/cosmos/gui/dialogs/about_dialog.rb +60 -36
- data/lib/cosmos/gui/dialogs/calendar_dialog.rb +10 -14
- data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +4 -5
- data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +31 -17
- data/lib/cosmos/gui/dialogs/details_dialog.rb +63 -47
- data/lib/cosmos/gui/dialogs/exception_dialog.rb +77 -68
- data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +6 -5
- data/lib/cosmos/gui/dialogs/legal_dialog.rb +34 -21
- data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +19 -43
- data/lib/cosmos/gui/dialogs/progress_dialog.rb +79 -42
- data/lib/cosmos/gui/dialogs/pry_dialog.rb +9 -5
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +6 -4
- data/lib/cosmos/gui/dialogs/select_dialog.rb +23 -18
- data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +34 -10
- data/lib/cosmos/gui/dialogs/splash.rb +18 -8
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +38 -43
- data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +51 -53
- data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +1 -1
- data/lib/cosmos/gui/line_graph/lines.rb +1 -1
- data/lib/cosmos/gui/qt.rb +9 -2
- data/lib/cosmos/gui/qt_tool.rb +50 -8
- data/lib/cosmos/gui/widgets/packet_log_frame.rb +53 -27
- data/lib/cosmos/interfaces/linc_interface.rb +103 -62
- data/lib/cosmos/io/json_drb_object.rb +3 -3
- data/lib/cosmos/io/raw_logger.rb +4 -8
- data/lib/cosmos/io/tcpip_server.rb +2 -2
- data/lib/cosmos/packets/binary_accessor.rb +1 -1
- data/lib/cosmos/packets/limits.rb +2 -5
- data/lib/cosmos/packets/packet.rb +1 -1
- data/lib/cosmos/packets/packet_config.rb +54 -19
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +7 -1
- data/lib/cosmos/script/scripting.rb +4 -5
- data/lib/cosmos/system/system.rb +2 -1
- data/lib/cosmos/system/target.rb +4 -0
- data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +13 -5
- data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +37 -27
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +6 -2
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +7 -5
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +21 -10
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +11 -11
- data/lib/cosmos/tools/script_runner/script_runner.rb +2 -18
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +6 -6
- data/lib/cosmos/tools/table_manager/table.rb +32 -41
- data/lib/cosmos/tools/table_manager/table_config.rb +140 -729
- data/lib/cosmos/tools/table_manager/table_item.rb +20 -36
- data/lib/cosmos/tools/table_manager/table_item_parser.rb +46 -0
- data/lib/cosmos/tools/table_manager/table_manager.rb +754 -691
- data/lib/cosmos/tools/table_manager/table_manager_core.rb +172 -358
- data/lib/cosmos/tools/table_manager/table_parser.rb +75 -0
- data/lib/cosmos/tools/test_runner/results_writer.rb +1 -1
- data/lib/cosmos/tools/test_runner/test_runner.rb +11 -0
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +4 -4
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +13 -13
- data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +9 -9
- data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +9 -9
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +4 -4
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +8 -18
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +7 -4
- data/lib/cosmos/top_level.rb +12 -0
- data/lib/cosmos/version.rb +5 -5
- data/run_gui_tests.bat +6 -0
- data/spec/core_ext/array_spec.rb +1 -1
- data/spec/interfaces/linc_interface_spec.rb +4 -4
- data/spec/io/json_drb_spec.rb +2 -2
- data/spec/io/json_rpc_spec.rb +1 -1
- data/spec/io/raw_logger_spec.rb +5 -1
- data/spec/packet_logs/packet_log_writer_spec.rb +1 -1
- data/spec/packets/packet_config_spec.rb +144 -0
- data/spec/packets/parsers/packet_item_parser_spec.rb +60 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/system/target_spec.rb +5 -1
- data/spec/tools/cmd_tlm_server/background_task_spec.rb +15 -3
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +117 -31
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +4 -0
- data/spec/tools/launcher/launcher_config_spec.rb +1 -1
- data/spec/tools/table_manager/table_config_spec.rb +226 -0
- data/spec/tools/table_manager/table_item_spec.rb +57 -0
- data/spec/tools/table_manager/table_parser_spec.rb +96 -0
- data/spec/tools/table_manager/table_spec.rb +90 -0
- data/spec/tools/table_manager/tablemanager_core_spec.rb +557 -0
- data/spec/top_level/top_level_spec.rb +9 -0
- data/spec/utilities/csv_spec.rb +3 -3
- 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
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
#
|
24
|
-
attr_reader :
|
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
|
-
@
|
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
|
-
@
|
38
|
-
@
|
51
|
+
@config = TableConfig.new()
|
52
|
+
@config.process_file(filename)
|
39
53
|
end
|
40
54
|
|
41
|
-
#
|
42
|
-
|
43
|
-
#
|
44
|
-
def file_new(
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
51
|
-
|
63
|
+
@config.table_names.each {|table_name| set_binary_data_to_default(table_name) }
|
64
|
+
yield 0.7 if block_given?
|
52
65
|
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
138
|
-
|
95
|
+
raise NoConfigError unless @config
|
139
96
|
result = ""
|
140
|
-
@
|
141
|
-
table_result = table_check(
|
97
|
+
@config.table_names.each do |name|
|
98
|
+
table_result = table_check(name)
|
142
99
|
unless table_result.empty?
|
143
|
-
result << "
|
100
|
+
result << "Errors in #{name}:\n" + table_result
|
144
101
|
end
|
145
102
|
end
|
146
|
-
result
|
147
|
-
|
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
|
-
#
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
File.
|
172
|
-
|
173
|
-
|
174
|
-
|
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.
|
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
|
-
|
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
|
-
|
133
|
+
file.puts "Label, Value"
|
184
134
|
end
|
185
135
|
|
186
|
-
#
|
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
|
-
|
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
|
-
|
147
|
+
table_item = items[c + r * table.num_columns]
|
220
148
|
else
|
221
|
-
|
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
|
-
|
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
|
157
|
+
end
|
276
158
|
end
|
159
|
+
report_path
|
277
160
|
end
|
278
161
|
|
279
|
-
|
280
|
-
|
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
|
-
|
283
|
-
|
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
|
-
|
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
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|
-
|
312
|
-
|
313
|
-
|
314
|
-
range_first =
|
315
|
-
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 =
|
319
|
-
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 << " #{
|
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
|
214
|
+
raise NoConfigError unless @config
|
332
215
|
set_binary_data_to_default(table_name)
|
333
216
|
end
|
334
217
|
|
335
|
-
#
|
218
|
+
# @param table_name [String] Create a hex formatted string of the given table data
|
336
219
|
def table_hex(table_name)
|
337
|
-
raise
|
338
|
-
table = @
|
339
|
-
raise
|
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
|
-
#
|
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
|
347
|
-
|
230
|
+
raise NoConfigError unless @config
|
348
231
|
result = table_check(table_name)
|
349
|
-
unless result.empty?
|
350
|
-
|
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
|
-
#
|
360
|
-
#
|
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
|
363
|
-
save_table = @
|
364
|
-
raise
|
242
|
+
raise NoConfigError unless @config
|
243
|
+
save_table = @config.table(table_name)
|
244
|
+
raise NoTableError unless save_table
|
365
245
|
|
366
|
-
result =
|
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
|
-
|
249
|
+
config = TableConfig.new
|
375
250
|
begin
|
376
|
-
|
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 !
|
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
|
-
|
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 =
|
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
|
-
|
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
|
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 = @
|
463
|
-
|
464
|
-
|
465
|
-
|
275
|
+
table = @config.table(table_name)
|
276
|
+
raise NoTableError unless table
|
277
|
+
table.restore_defaults
|
278
|
+
end
|
466
279
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
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
|
-
@
|
492
|
-
@
|
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.
|
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
|