require_relative "functions" require_relative "festwert" require_relative "festwerteblock" require_relative "kennlinie" require_relative "gruppenkennlinie" require_relative "festkennlinie" require_relative "kennfeld" require_relative "gruppenkennfeld" require_relative "festkennfeld" require_relative "stuetzstellenverteilung" require_relative "malformed_dcm_error" require_relative "buffer" class Ecu class LabelList DCM_HEADER = "KONSERVIERUNG_FORMAT 2.0" BLANKLINE_REGEX = /^\s*$/ COMMENT_REGEX = /^\*.*/ def self.from_dcm(str) buffer = DcmBuffer.new headers = [] subheaders = [] functions = [] labels = {} str.each_line.lazy.with_index(1).each do |line, n| line = normalize_whitespace(line) case line when BLANKLINE_REGEX then next when COMMENT_REGEX case buffer.header when :pre then headers << line[1..].strip when :after then subheaders << line[1..].strip when :done then # Header time over, do nothing end when DCM_HEADER then buffer.header_seen! when Functions.dcm_header then buffer.start!(Functions, [line]) when Festwert.dcm_header then buffer.start!(Festwert, [line]) when Festwerteblock.dcm_header then buffer.start!(Festwerteblock, [line]) when Kennlinie.dcm_header then buffer.start!(Kennlinie, [line]) when Gruppenkennlinie.dcm_header then buffer.start!(Gruppenkennlinie, [line]) when Festkennlinie.dcm_header then buffer.start!(Festkennlinie, [line]) when Kennfeld.dcm_header then buffer.start!(Kennfeld, [line]) when Gruppenkennfeld.dcm_header then buffer.start!(Gruppenkennfeld, [line]) when Festkennfeld.dcm_header then buffer.start!(Festkennfeld, [line]) when Stuetzstellenverteilung.dcm_header then buffer.start!(Stuetzstellenverteilung, [line]) when "END" then case obj = buffer.finish!(line) when Label fail "Duplicate label #{obj.name}" unless labels[obj.name].nil? labels[obj.name] = obj when Functions fail "Duplicate functions definition" unless functions.empty? functions = obj else fail "Unknown object #{obj}" end else buffer.append!(line) end rescue StandardError => e raise MalformedDcmError.new(e.message, n, str), e.message end new(labels.values, headers, subheaders, true) end def self.normalize_whitespace(line) line.chomp.gsub(/[[:space:]]/, " ").rstrip end def to_dcm(indented=false) out = [] unless headers.empty? out += headers.map { "* " + _1 }.push("") end out << DCM_HEADER << "" unless subheaders.empty? out += subheaders.map { "* " + _1 }.push("") end out += map { _1.to_dcm(indented) } out.join("\n") end end end