Class: Andromeda::Cmd::Reader

Inherits:
Kit::FileReader show all
Defined in:
lib/andromeda/cmd.rb

Instance Attribute Summary collapse

Attributes inherited from Kit::FileReader

#mode, #path

Attributes inherited from Plan

#error_level, #log, #marker, #nick, #trace_enter, #trace_exit

Attributes inherited from Impl::ProtoPlan

#guide, #id

Instance Method Summary collapse

Methods inherited from Kit::FileReader

#data_tag, #init_mode

Methods inherited from Plan

#initialize_copy, #pool, #tap, #to_short_s

Methods inherited from Impl::ProtoPlan

#>>, #current_name, #current_scope, #data_key, #data_tag, #data_val, #dest, #entry, #init_guide, #initialize_copy, #key_label, #key_spot, #map_data, #mute, name_spot, #post_data, #post_to, #public_spot, #selects?, #signal_name?, signal_names, #signal_names, signal_spot, spot_attr, #spot_attr_name?, spot_attr_names, #spot_attr_names, spot_meth, #spot_meth_name?, #spot_meth_names, spot_meth_names, #spot_name?, spot_names, #spot_names, #tags, #to_short_s, #via

Methods included from Impl::To_S

short_s, #to_s, #to_short_s

Methods inherited from Impl::ConnectorBase

#post, #post_local, #start

Constructor Details

#initialize(config = {}) ⇒ Reader

Returns a new instance of Reader.



158
159
160
161
162
163
164
165
# 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

Instance Attribute Details

#comment_matcherObject (readonly)

Returns the value of attribute comment_matcher.



156
157
158
# File 'lib/andromeda/cmd.rb', line 156

def comment_matcher
  @comment_matcher
end

#end_matcherObject (readonly)

Returns the value of attribute end_matcher.



156
157
158
# File 'lib/andromeda/cmd.rb', line 156

def end_matcher
  @end_matcher
end

#line_matcherObject (readonly)

Returns the value of attribute line_matcher.



156
157
158
# File 'lib/andromeda/cmd.rb', line 156

def line_matcher
  @line_matcher
end

#start_matcherObject (readonly)

Returns the value of attribute start_matcher.



156
157
158
# File 'lib/andromeda/cmd.rb', line 156

def start_matcher
  @start_matcher
end

Instance Method Details

#match_line(state, line) {|:garbage, state, line| ... } ⇒ Object

Yields:

  • (:garbage, state, line)


167
168
169
170
171
172
173
174
175
176
177
# 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) ⇒ Object



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
224
225
# 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