class Andromeda::Cmd::Cmd::Reader

Attributes

comment_matcher[R]
end_matcher[R]
line_matcher[R]
start_matcher[R]

Public Class Methods

new(config = {}) click to toggle source
Calls superclass method
# File lib/andromeda/cmd.rb, line 158
def initialize(config = {})
  super config
  @start_matcher   = /<<< ANDROMEDA START :(\w+) TIME (\d+) LEN (\d+) >>>/
  @end_matcher     = /<<< ANDROMEDA END :(\w+) >>>/
  @comment_matcher = /#(.*)/
  # remember to change the offset for :line, too whenever you change this
  @line_matcher    = /... (.*)/
end

Public Instance Methods

match_line(state, line) { |:start, state, ({ cmd: to_sym, tim: to_i, len: to_i })| ... } click to toggle source
# File lib/andromeda/cmd.rb, line 167
def match_line(state, line)
  m = @start_matcher.match line
  return yield :start, state, ({ cmd: m[1].to_sym, tim: m[2].to_i, len: m[3].to_i }) if m
  m = @end_matcher.match line
  return yield :end, state, m[1].to_sym if m
  m = @comment_matcher.match line
  return yield :comment, state, m[1] if m
  m = @line_matcher.match line
  return yield :line, state, m[1] if m
  yield :garbage, state, line
end
on_enter(key, val) click to toggle source
Calls superclass method
# File lib/andromeda/cmd.rb, line 179
def on_enter(key, val)
  super key, val do |file|
    fst = tags[:first]
    lst = tags[:last]

    state = { :comment => true, :start => true, :cont => true }
    while (line = file.gets) && state[:cont]
      line = line.chomp
      match_line(state, line) do |token, state, parts|
        signal_error ArgumentError.new("Skipping unexpected token #{token} in line '#{line}' (state: #{state})") unless state[token]
        case token
        when :comment
          if state[:comment_str]
            then state[:comment_str] << parts
            else state[:comment_str]  = parts end
        when :start
          state.delete :comment
          state.delete :start
          state[:line]    = true
          state[:end]     = true
          parts[:data]    = ''
          state[:len]     = 0
          state[:cur]     = parts
          parts[:comment] = state[:comment_str]
          state.delete :comment_str
        when :line
          state[:len] += parts.length + 5
          state[:cur][:data] << "#{parts}\n"
        when :end
          state.delete :line
          state.delete :end
          state[:start]   = true
          state[:comment] = true
          cur             = state[:cur]
          data            = cur[:data]
          signal_error ArgumentError.new("Start (#{cur[:cmd]}) and end (#{parts})cmd mismatch") unless cur[:cmd] == parts
          signal_error ArgumentError.new("Length mismatch (expected: #{cur[:len]}, found: #{state[:len]})") unless cur[:len] == state[:len]
          exit << cur if exit
          state[:cont] = false unless file.pos <= lst
        else
          signal_error ArgumentError.new("Garbage encountered (line: '#{line}')")
          return
        end
      end
    end
  end
end