# encoding: ascii-8bit # Copyright 2014 Ball Aerospace & Technologies Corp. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it # under the terms of the GNU General Public License # as published by the Free Software Foundation; version 3 with # attribution addendums as found in the LICENSE.txt require 'cosmos/config/config_parser' require 'cosmos/packets/packet_config' require 'cosmos/tools/table_manager/table' require 'cosmos/tools/table_manager/table_parser' require 'cosmos/tools/table_manager/table_item_parser' module Cosmos # Processes the Table Manager configuration files which define tables. Since # this class inherits from {PacketConfig} it only needs to implement Table # Manager specific keywords. All tables are accessed through the table # and tables methods. class TableConfig < PacketConfig # @return [String] Table configuration filename attr_reader :filename # Create the table configuration def initialize super # Override commands with the Table::TARGET name to store tables @commands[Table::TARGET] = {} end # @return [Array] All tables defined in the configuration file def tables @commands[Table::TARGET] end # @return [Array] All the table names def table_names tables.keys end # @param table_name [String] Table name to return # @return [Table] def table(table_name) tables[table_name.upcase] end # Processes a COSMOS table configuration file and uses the keywords to build up # knowledge of the tables. # # @param filename [String] The name of the configuration file def process_file(filename) # Partial files are included into another file and thus aren't directly processed return if File.basename(filename)[0] == '_' # Partials start with underscore @filename = filename @converted_type = nil @converted_bit_size = nil @proc_text = '' @building_generic_conversion = false parser = ConfigParser.new("http://cosmosrb.com/docs/tools/#table-manager-configuration") parser.parse_file(filename) do |keyword, params| if @building_generic_conversion case keyword # Complete a generic conversion when 'GENERIC_READ_CONVERSION_END', 'GENERIC_WRITE_CONVERSION_END' parser.verify_num_parameters(0, 0, keyword) @current_item.read_conversion = GenericConversion.new(@proc_text, @converted_type, @converted_bit_size) if keyword.include? "READ" @current_item.write_conversion = GenericConversion.new(@proc_text, @converted_type, @converted_bit_size) if keyword.include? "WRITE" @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 when 'TABLEFILE' usage = "#{keyword} " parser.verify_num_parameters(1, 1, usage) filename = File.join(File.dirname(filename), params[0]) raise parser.error("Table file #{filename} not found", usage) unless File.exist?(filename) process_file(filename) when 'TABLE' finish_packet() @current_packet = TableParser.parse_table(parser, @commands, @warnings) @current_cmd_or_tlm = COMMAND # Select an existing table for editing when 'SELECT_TABLE' usage = "#{keyword}
" finish_packet() parser.verify_num_parameters(1, 1, usage) table_name = params[0].upcase @current_packet = table(table_name) raise parser.error("Table #{table_name} not found", usage) unless @current_packet ####################################################################### # All the following keywords must have a current packet defined ####################################################################### when 'SELECT_PARAMETER', 'PARAMETER', 'ID_PARAMETER', 'ARRAY_PARAMETER', 'APPEND_PARAMETER', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_PARAMETER', 'ALLOW_SHORT', 'HAZARDOUS', 'PROCESSOR', 'META', 'DISABLE_MESSAGES', 'DISABLED' raise parser.error("No current packet for #{keyword}") unless @current_packet process_current_packet(parser, keyword, params) ####################################################################### # All the following keywords must have a current item defined ####################################################################### when 'STATE', 'READ_CONVERSION', 'WRITE_CONVERSION', 'POLY_READ_CONVERSION', 'POLY_WRITE_CONVERSION', 'SEG_POLY_READ_CONVERSION', 'SEG_POLY_WRITE_CONVERSION', 'GENERIC_READ_CONVERSION_START', 'GENERIC_WRITE_CONVERSION_START', 'REQUIRED', 'LIMITS', 'LIMITS_RESPONSE', 'UNITS', 'FORMAT_STRING', 'DESCRIPTION', 'MINIMUM_VALUE', 'MAXIMUM_VALUE', 'DEFAULT_VALUE', 'OVERFLOW', 'UNEDITABLE', 'HIDDEN' raise parser.error("No current item for #{keyword}") unless @current_item process_current_item(parser, keyword, params) else # blank config.lines will have a nil keyword and should not raise an exception raise parser.error("Unknown keyword '#{keyword}'") if keyword end # case keyword end end # Complete the last defined packet finish_packet() end # (see PacketConfig#process_current_packet) def process_current_packet(parser, keyword, params) super(parser, keyword, params) rescue => err if err.message.include?("not found") raise parser.error("#{params[0]} not found in table #{@current_packet.table_name}", "SELECT_PARAMETER ") else raise err end end # Overridden method to handle the unique table item parameters: UNEDITABLE # and HIDDEN. # (see PacketConfig#process_current_item) def process_current_item(parser, keyword, params) super(parser, keyword, params) case keyword when 'UNEDITABLE' usage = "#{keyword}" parser.verify_num_parameters(0, 0, usage) @current_item.editable = false when 'HIDDEN' usage = "#{keyword}" parser.verify_num_parameters(0, 0, usage) @current_item.hidden = true end end # (see PacketConfig#start_item) def start_item(parser) finish_item() @current_item = TableItemParser.parse(parser, @current_packet) end # If the table is TWO_DIMENSIONAL all currently defined items are # duplicated until the specified number of rows are created. def finish_packet if @current_packet if @current_packet.type == :TWO_DIMENSIONAL items = @current_packet.sorted_items.clone (@current_packet.num_rows - 1).times do |row| items.each do |item| new_item = item.clone new_item.name = "#{new_item.name[0...-1]}#{row + 1}" @current_packet.append(new_item) end end end end super() end end end