Class: IDL::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/ridl/runner.rb

Defined Under Namespace

Classes: ProductionStack

Instance Method Summary collapse

Constructor Details

#initialize(backend, options) ⇒ Engine

Returns a new instance of Engine.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ridl/runner.rb', line 88

def initialize(backend, options)
  @backend = backend ? Backend.load(backend) : Backend.null_be
  @initopts = options.merge({
    backend: @backend.name,
    macros: options[:macros].merge({
       __RIDL__: "#{RIDL_VERSION}",
       __RIDLBE__: @backend.name.to_s,
       __RIDLBE_VER__: @backend.version,
       __RIDL_IDL_VERSION__: options[:idlversion].to_s
    })
  })
  @optparser = init_optparser
  @inputstack = []
  @productionstack = ProductionStack.new
  @options = nil
end

Instance Method Details

#backendObject



105
106
107
# File 'lib/ridl/runner.rb', line 105

def backend
  @backend
end

#has_input?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/ridl/runner.rb', line 127

def has_input?
  !@inputstack.empty?
end

#has_production?(id) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/ridl/runner.rb', line 155

def has_production?(id)
  @productionstack.has?(id)
end

#has_productions?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/ridl/runner.rb', line 151

def has_productions?
  !@productionstack.empty?
end

#optionsObject



109
110
111
# File 'lib/ridl/runner.rb', line 109

def options
  @options || @initopts
end

#parse(io, opts) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/ridl/runner.rb', line 272

def parse(io, opts)
  # parse IDL source
  _parser = ::IDL::Parser.new(opts)
  _parser.yydebug = opts[:debug]

  begin
    _parser.parse(io)
  rescue => e
    IDL.error(e.inspect)
    IDL.error(e.backtrace.join("\n")) unless e.is_a? IDL::ParseError
    return nil
  ensure
    io.close unless String === io || io == $stdin
  end
  _parser
end

#peek_inputObject



123
124
125
# File 'lib/ridl/runner.rb', line 123

def peek_input
  @inputstack.first
end

#peek_productionObject



143
144
145
# File 'lib/ridl/runner.rb', line 143

def peek_production
  @productionstack.peek
end

#pop_inputObject



119
120
121
# File 'lib/ridl/runner.rb', line 119

def pop_input
  @inputstack.shift
end

#pop_productionObject



139
140
141
# File 'lib/ridl/runner.rb', line 139

def pop_production
  @productionstack.pop
end

#production(id) ⇒ Object



159
160
161
# File 'lib/ridl/runner.rb', line 159

def production(id)
  @productionstack[id]
end

#push_input(idlfile, opts) ⇒ Object

Input management



115
116
117
# File 'lib/ridl/runner.rb', line 115

def push_input(idlfile, opts)
  @inputstack << [idlfile, opts]
end

#push_production(id, producer) ⇒ Object

Production management



133
134
135
136
137
# File 'lib/ridl/runner.rb', line 133

def push_production(id, producer)
  raise "Producer #{id} already queued" if @productionstack.has?(id)

  @productionstack.push(id, producer)
end

#remove_production(id) ⇒ Object



147
148
149
# File 'lib/ridl/runner.rb', line 147

def remove_production(id)
  @productionstack.remove(id)
end

#run(argv, runopts = {}) ⇒ Object



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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/ridl/runner.rb', line 173

def run(argv, runopts = {})

  # initialize options
  @options = @initopts.merge(runopts)

  # mark current (clean) state
  @options.mark

  # backup current engine (if any)
  cur_engine = Thread.current[:ridl_engine]
  # store currently running engine for current thread
  Thread.current[:ridl_engine] = self

  begin
    # parse arguments
    begin
      @optparser.parse!(argv)
    rescue ArgumentError => e
      IDL.error(e.inspect)
      IDL.error(e.backtrace.join("\n")) if IDL.verbose_level.positive?
      return false
    end

    if options[:preprocess]

      ## PREPROCESSING
      o = if options[:output].nil?
            $stdout
          else
            File.open(options[:output], 'w+')
          end
      options[:output] = o

      input_base = File.basename(argv.first)
      if input_base != argv.first
        options[:xincludepaths] << (File.dirname(argv.first) + '/')
      end

      return !parse("#include \"#{input_base}\"", options).nil?
    else
      ## collect input files from commandline
      collect_input(argv)

      ## CODE GENERATION
      while has_input?
        # get input from stack
        _idlfile, _opts = pop_input

        _fio = if IO === _idlfile || StringIO === _idlfile
                 _idlfile
               else
                 File.open(_idlfile, 'r')
               end
        raise 'cannot read from STDOUT' if $stdout == _fio

        # parse IDL source
        IDL.log(1, "RIDL - parsing #{IO === _idlfile ? 'from STDIN' : (StringIO === _idlfile ? 'from string' : _idlfile)}")

        unless _parser = parse(_fio, _opts)
          return false
        end

        # process parse result -> code generation
        IDL.log(2, 'RIDL - processing input')

        GenFile.transaction do
          begin

            backend.process_input(_parser, _opts)

            # handle productions
            while has_productions?
              IDL.log(2, "RIDL - running production #{peek_production}")

              # get next-in-line producer
              producer = pop_production

              # execute the producer
              producer.run(_parser)
            end

          rescue Backend::ProcessStop
            IDL.log(2, "RIDL - processing #{IO === _idlfile ? 'from STDIN' : (StringIO === _idlfile ? 'from string' : _idlfile)} stopped with \"#{$!.message}\"")

          rescue => e
            IDL.error(e)
            IDL.error(e.backtrace.join("\n")) unless e.is_a? IDL::ParseError
            return false
          end
        end
      end
    end
  ensure
    # restore previous state
    Thread.current[:ridl_engine] = cur_engine
  end
  true
end

#verbose_levelObject

Verbosity control



165
166
167
# File 'lib/ridl/runner.rb', line 165

def verbose_level
  options[:verbose]
end

#verbose_level=(l) ⇒ Object



169
170
171
# File 'lib/ridl/runner.rb', line 169

def verbose_level=(l)
  options[:verbose] = l
end