Class: Cosmos::TableConfig
- Defined in:
- lib/cosmos/tools/table_manager/table_config.rb
Overview
TableConfig provides capabilities to read an ascii file that defines the table parameters in a system and create a set of Tables for each.
Instance Method Summary collapse
-
#commit_default_values(table) ⇒ Object
Update all default values in the definition file on disk with current values.
-
#format_hex(table, item_def) ⇒ Object
# Return the entire table_definition file for the given table name as a string def print_table(name) tdef = @tables tstr = “” if tdef.table_id.class != Array tstr << “TABLE "#tdeftdef.name" "#tdeftdef.description" #convert_table_type(tdefconvert_table_type(tdef.type) #convert_endianness(tdefconvert_endianness(tdef.get_endianness) #tdeftdef.table_idn” else tstr << “TABLE "#tdeftdef.name" "#tdeftdef.description" #convert_table_type(tdefconvert_table_type(tdef.type) #convert_endianness(tdefconvert_endianness(tdef.get_endianness) #’)n” end if tdef.type == :ONE_DIMENSIONAL tdef.sorted_items.each do |item| tstr << create_item_string(item, tdef.type) end else # TWO_DIMENSIONAL tdef.num_columns.times do |column| item_def = tdef.sorted_items tstr << create_item_string(item_def, tdef.type) end.
-
#get_all_tables ⇒ Object
Returns an array of all the Tables in the definition file.
-
#get_table(name) ⇒ Object
Returns a specific Table.
-
#get_table_names ⇒ Object
Returns an array of all the table names in the definition file.
-
#initialize ⇒ TableConfig
constructor
Constructor for a TableConfig.
-
#item_to_def_string(table, item_def) ⇒ Object
Returns a default-value representation of an item to be printed in a DEF file.
-
#process(filename) ⇒ Object
Processes a file and adds in the tables defined in the file.
-
#set_item_default_value(item_def, default = nil) ⇒ Object
Sets the given item definition’s default parameter to the default value given.
-
#unknown_keyword(parser, keyword, parameters) ⇒ Object
Classes extending table_definition should override this function to add new keyword processing.
Constructor Details
#initialize ⇒ TableConfig
Constructor for a TableConfig
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 21 def initialize @ordered_tables = nil @tables = nil @current_name = nil @current_table = nil @current_parameter = nil @cur_bit_offset = 0 @default_count = 0 @item_definitions = nil @table_names = nil end |
Instance Method Details
#commit_default_values(table) ⇒ Object
Update all default values in the definition file on disk with current values
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 294 def commit_default_values(table) new_file_data = "" table_found = false default_count = 0 table_parameters = [] parser = ConfigParser.new parser.parse_file(table.filename) do |keyword, parameters| line = parser.line case keyword when 'TABLE' name = parameters[0].remove_quotes if name == table.name table_found = true else table_found = false end when 'PARAMETER' if table_found name = parameters[0].remove_quotes if table.type == :ONE_DIMENSIONAL item = table.get_item(name) # update the default value (in case the user tries to reset default values) item.default = table.read(name, :RAW) # determine what the new default value will look like as printed in the DEF file new_default = item_to_def_string(table, item) # scan to the beginning of the default value line_index = line.index(keyword) # skip to start of keyword line_index = line.index(parameters[0], line_index+keyword.length) # skip to start of first param (1..7).each do |index| line_index = line.index(parameters[index], line_index+parameters[index-1].length) # skip to start of next param end # rebuild the line in 3 parts: # everything up to the old default value # the new default value # everything after the old default value line = line[0...line_index] + new_default + line[(line_index+parameters[7].length)..-1] else table_parameters << name end end when 'DEFAULT' if table_found line_index = line.index(keyword) previous_word = keyword table_parameters.each_with_index do |param_name, index| item_name = "#{param_name}#{default_count}" item = table.get_item(item_name) # update the default value (in case the user tries to reset default values) item.default = table.read(item_name, :RAW) # determine what the new default value will look like as printed in the DEF file new_default = item_to_def_string(table, item) if new_default.index(" ") new_default = '"' + new_default + '"' end # scan to the beginning of the default value line_index = line.index(parameters[index], line_index+previous_word.length) # rebuild the line in 3 parts: # everything up to the old default value # the new default value # everything after the old default value line = line[0...line_index] + new_default + line[(line_index+parameters[index].length)..-1] # update previous_word so that we can find the next value previous_word = new_default end # count the row so that we know what the item_name is next time we see DEFAULT default_count += 1 end end new_file_data << (line + "\n") end # end loop # ok, now replace the old def file with the new one File.open(table.filename, "w") do |file| file.puts new_file_data end end |
#format_hex(table, item_def) ⇒ Object
# Return the entire table_definition file for the given table name as a string
def print_table(name)
tdef = @tables[name]
tstr = ""
if tdef.table_id.class != Array
tstr << "TABLE \"#{tdef.name}\" \"#{tdef.description}\" #{convert_table_type(tdef.type)} #{convert_endianness(tdef.get_endianness)} #{tdef.table_id}\n"
else
tstr << "TABLE \"#{tdef.name}\" \"#{tdef.description}\" #{convert_table_type(tdef.type)} #{convert_endianness(tdef.get_endianness)} #{tdef.table_id.join(' ')}\n"
end
if tdef.type == :ONE_DIMENSIONAL
tdef.sorted_items.each do |item|
tstr << create_item_string(item, tdef.type)
end
else # TWO_DIMENSIONAL
tdef.num_columns.times do |column|
item_def = tdef.sorted_items[column]
tstr << create_item_string(item_def, tdef.type)
end
index = 0
tdef.sorted_items.each do |item|
if index % tdef.num_columns == 0
tstr << "\n DEFAULT "
end
case item.display_type
when :DEC
default = item.default
when :STATE
default = "\"#{item.default}\""
when :HEX
default = "0x#{item.default.to_s(16)}"
end
tstr << "#{default} "
index += 1
end
end # end else # TWO_DIMENSIONAL
tstr
end # end print_table(name)
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 425 def format_hex(table, item_def) case item_def.bit_size when 8 x = sprintf("%02X", table.read(item_def.name).to_s) # if the number was negative x will have .. and possibly another # F in the string which we remove by taking the last 4 digits x = /\w{2}$/.match(x)[0] when 16 x = sprintf("%04X", table.read(item_def.name).to_s) # if the number was negative x will have .. and possibly another # F in the string which we remove by taking the last 4 digits x = /\w{4}$/.match(x)[0] else x = sprintf("%08X", table.read(item_def.name).to_s) # if the number was negative x will have .. and possibly another # F in the string which we remove by taking the last 8 digits x = /\w{8}$/.match(x)[0] end return "0x%X" % Integer("0x#{x}") # convert to Integer end |
#get_all_tables ⇒ Object
Returns an array of all the Tables in the definition file
263 264 265 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 263 def get_all_tables @ordered_tables end |
#get_table(name) ⇒ Object
Returns a specific Table
258 259 260 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 258 def get_table(name) @tables[name] end |
#get_table_names ⇒ Object
Returns an array of all the table names in the definition file
268 269 270 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 268 def get_table_names @table_names end |
#item_to_def_string(table, item_def) ⇒ Object
Returns a default-value representation of an item to be printed in a DEF file
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 273 def item_to_def_string(table, item_def) result = "" case item_def.display_type when :STATE if table.type == :ONE_DIMENSIONAL result = table.read(item_def.name, :RAW).to_s else result = table.read(item_def.name).to_s end when :DEC, :STRING, :NONE result = table.read(item_def.name).to_s when :CHECK result = table.read(item_def.name, :RAW).to_s when :HEX result = format_hex(table, item_def) end return result end |
#process(filename) ⇒ Object
Processes a file and adds in the tables defined in the file
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 34 def process(filename) building_generic_conversion = false converted_type = nil converted_bit_size = nil proc_text = '' Logger.info "Processing table config in file '#{filename}'" unless test ?f, filename Logger.error "File does not exist" raise "ERROR! Table config file #{filename} does not exist!" end parser = ConfigParser.new parser.parse_file(filename) do |keyword, parameters| next unless keyword if building_generic_conversion case keyword # Complete a generic conversion when 'GENERIC_READ_CONVERSION_END', 'GENERIC_WRITE_CONVERSION_END', 'CONSTRAINT_END' parser.verify_num_parameters(0, 0, keyword) @current_parameter.read_conversion = GenericConversion.new(proc_text, converted_type, converted_bit_size) if keyword.include? "READ" @current_parameter.write_conversion = GenericConversion.new(proc_text, converted_type, converted_bit_size) if keyword.include? "WRITE" @current_parameter.constraint = GenericConversion.new(proc_text, converted_type, converted_bit_size) if keyword.include? "CONSTRAINT" building_generic_conversion = false # Add the current config.line to the conversion being built else proc_text << parser.line << "\n" end # case keyword else # not building generic conversion case keyword # Start the definition of a generic conversion. # All config.lines following this config.line are considered part # of the conversion until an end of conversion marker is found when 'GENERIC_READ_CONVERSION_START', 'GENERIC_WRITE_CONVERSION_START', 'CONSTRAINT_START' usage = "#{keyword} <Converted Type (optional)> <Converted Bit Size (optional)>" parser.verify_num_parameters(0, 2, usage) proc_text = '' building_generic_conversion = true converted_type = nil converted_bit_size = nil if parameters[0] converted_type = parameters[0].upcase.intern raise parser.error("Invalid converted_type: #{converted_type}.") unless [:INT, :UINT, :FLOAT, :STRING, :BLOCK].include? converted_type end converted_bit_size = Integer(parameters[1]) if parameters[1] when 'TABLEFILE' parser.verify_num_parameters(1, 1, "#{keyword} <File name>") process(File.join(File.dirname(filename), parameters[0])) when 'TABLE' usage = "TABLE <Table Name> <Table Description> <ONE_DIMENSIONAL or TWO_DIMENSIONAL> <BIG_ENDIAN or LITTLE_ENDIAN> <Identifier>" parser.verify_num_parameters(5, nil, usage) begin # locals declared for readability name = parameters[0] description = parameters[1] type = read_table_type(parameters[2]) endianness = read_endianness(parameters[3]) if parameters[5].nil? table_id = Integer(parameters[4]) else table_id = [] parameters[4..-1].each {|parameter| table_id << Integer(parameter)} end start_new_table(name, description, type, endianness, table_id, filename) rescue ArgumentError => err raise parser.error("#{err.} with #{keyword}.\nUSAGE: #{usage}") end when 'PARAMETER' usage = "PARAMETER <Parameter Name> <Parameter Description> <Data Type> <Bit Size> <Display Type> <Minimum Value> <Maximum Value> <Default Value - Only in ONE_DIMENTIONAL>" parser.verify_num_parameters(7, 8, usage) finish_parameter() if @current_table @current_table.num_rows += 1 begin if @current_table.type == :TWO_DIMENSIONAL parameters[0] = "#{parameters[0]}0" end # locals declared for readability name = parameters[0] if @current_table.items[name.upcase] raise ArgumentError, "The name \"#{name}\" was already defined" end description = parameters[1] type = read_item_type(parameters[2]) bit_size = parameters[3].to_i display_type, editable = read_display_type(parameters[4], type) if type == :BLOCK range = nil elsif type == :STRING range = convert_to_range(parameters[5], parameters[6], :UINT, 0) else range = convert_to_range(parameters[5], parameters[6], type, bit_size) end if @current_table.type == :ONE_DIMENSIONAL default = convert_to_type(parameters[7], type) else # TWO_DIMENSIONAL defaults are set by the DEFAULT keyword default = 0 end @current_parameter = @current_table.create_param(name, @cur_bit_offset, bit_size, type, description, range, default, display_type, editable) @cur_bit_offset += parameters[3].to_i rescue ArgumentError => err raise parser.error("#{err.} with #{keyword}.\nUSAGE: #{usage}") end end when 'STATE' usage = "STATE <Key> <Value>" parser.verify_num_parameters(2, 2, usage) begin # locals declared for readability state_name = parameters[0] state_value = convert_to_type(parameters[1], @current_parameter.data_type) @current_parameter.states ||= {} @current_parameter.states[state_name.upcase] = state_value rescue ArgumentError => err raise parser.error("#{err.} with #{keyword}.\nUSAGE: #{usage}") end when 'DEFAULT' usage = "DEFAULT <Value1> <Value2> ... <ValueN>" # if this is our first default value for a TWO_DIMENSIONAL table # then we redefine the default values if @default_count == 0 @item_definitions = Array.new(@current_table.sorted_items) index = 0 @item_definitions.each do |item_def| set_item_default_value(item_def, parameters[index]) index += 1 end @current_table.num_rows = 1 # more default values have been given so copy all the parameters from # the first row and reset the defaults else index = 0 @item_definitions.each do |item_def| new_item = @current_table.duplicate_item(item_def, @default_count, @cur_bit_offset) @cur_bit_offset += item_def.bit_size set_item_default_value(new_item, parameters[index]) index += 1 end @current_table.num_rows += 1 end # end else for if @default_count == 1 @default_count += 1 when 'POLY_READ_CONVERSION' parser.verify_num_parameters(2, nil, "#{keyword} <C0> ... <CX>") @current_parameter.read_conversion = PolynomialConversion.new(parameters[0..-1]) when 'POLY_WRITE_CONVERSION' parser.verify_num_parameters(2, nil, "#{keyword} <C0> ... <CX>") @current_parameter.write_conversion = PolynomialConversion.new(parameters[0..-1]) else unknown_keyword(parser, keyword, parameters) end # end case parameters[0] end # end else for generic conversion end # end loop # Handle last packet finish_table() ensure file.close if defined? file and file end |
#set_item_default_value(item_def, default = nil) ⇒ Object
Sets the given item definition’s default parameter to the default value given. This function does conversions based on the display_type of the item.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 227 def set_item_default_value(item_def, default = nil) begin # If no default was passed use the definition default if default == nil default = item_def.default end if item_def.display_type == :STATE begin val = item_def.states.key(Integer(default)) rescue val = default end @current_table.write(item_def.name, val) item_def.default = @current_table.read(item_def.name, :RAW) else item_def.default = convert_to_type(default, item_def.data_type) end rescue Logger.error "Setting #{item_def.name} to #{default} failed! Using #{item_def.range.first} for the default value." item_def.default = item_def.range.first end end |
#unknown_keyword(parser, keyword, parameters) ⇒ Object
Classes extending table_definition should override this function to add new keyword processing. Ensure super() is called after processing new keywords so the default behavior of raising an ArgumentError is maintained.
253 254 255 |
# File 'lib/cosmos/tools/table_manager/table_config.rb', line 253 def unknown_keyword(parser, keyword, parameters) raise parser.error("Unknown keyword '#{keyword}'.", nil) if keyword end |