class IDL::Engine
Public Class Methods
new(backend, options)
click to toggle source
# File lib/ridl/runner.rb, line 87 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 }) }) @optparser = init_optparser @inputstack = [] @productionstack = ProductionStack.new @options = nil end
Public Instance Methods
backend()
click to toggle source
# File lib/ridl/runner.rb, line 103 def backend @backend end
has_input?()
click to toggle source
# File lib/ridl/runner.rb, line 125 def has_input? !@inputstack.empty? end
has_production?(id)
click to toggle source
# File lib/ridl/runner.rb, line 153 def has_production?(id) @productionstack.has?(id) end
has_productions?()
click to toggle source
# File lib/ridl/runner.rb, line 149 def has_productions? !@productionstack.empty? end
options()
click to toggle source
# File lib/ridl/runner.rb, line 107 def options @options || @initopts end
parse(io, opts)
click to toggle source
# File lib/ridl/runner.rb, line 270 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_input()
click to toggle source
# File lib/ridl/runner.rb, line 121 def peek_input @inputstack.first end
peek_production()
click to toggle source
# File lib/ridl/runner.rb, line 141 def peek_production @productionstack.peek end
pop_input()
click to toggle source
# File lib/ridl/runner.rb, line 117 def pop_input @inputstack.shift end
pop_production()
click to toggle source
# File lib/ridl/runner.rb, line 137 def pop_production @productionstack.pop end
production(id)
click to toggle source
# File lib/ridl/runner.rb, line 157 def production(id) @productionstack[id] end
push_input(idlfile, opts)
click to toggle source
Input management
# File lib/ridl/runner.rb, line 113 def push_input(idlfile, opts) @inputstack << [idlfile, opts] end
push_production(id, producer)
click to toggle source
Production management
# File lib/ridl/runner.rb, line 131 def push_production(id, producer) raise "Producer #{id} already queued" if @productionstack.has?(id) @productionstack.push(id, producer) end
remove_production(id)
click to toggle source
# File lib/ridl/runner.rb, line 145 def remove_production(id) @productionstack.remove(id) end
run(argv, runopts = {})
click to toggle source
# File lib/ridl/runner.rb, line 171 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_level()
click to toggle source
Verbosity control
# File lib/ridl/runner.rb, line 163 def verbose_level options[:verbose] end
verbose_level=(l)
click to toggle source
# File lib/ridl/runner.rb, line 167 def verbose_level=(l) options[:verbose] = l end
Private Instance Methods
collect_input(argv)
click to toggle source
# File lib/ridl/runner.rb, line 289 def collect_input(argv) ## collect input files from commandline argv.each do |_arg| _opts = options.dup _opts[:idlfile] = _arg if _opts[:no_input] # do not parse specified file (only used as template for output names) # instead push an empty StringIO object _arg = StringIO.new('') else if _opts[:search_incpath] _fname = _arg _fpath = if File.file?(_fname) && File.readable?(_fname) _fname else _fp = _opts[:includepaths].find do |_p| _f = _p + _fname File.file?(_f) && File.readable?(_f) end _opts[:outputdir] = _fp unless _fp.nil? || !_opts[:outputdir].nil? _fp += '/' + _fname unless _fp.nil? _fp end _arg = _fpath unless _fpath.nil? end _opts[:xincludepaths] << (File.dirname(_arg) + '/') end _opts[:outputdir] ||= '.' push_input(_arg, _opts) end ## if no IDL input file specified read from STDIN unless has_input? _opts = options.dup _opts[:outputdir] ||= '.' push_input($stdin, _opts) end end
init_optparser()
click to toggle source
# File lib/ridl/runner.rb, line 331 def init_optparser script_name = File.basename($0, '.*') unless script_name =~ /ridlc/ script_name = 'ruby ' + $0 end # set up option parser with common options opts = OptionParser.new opts.banner = "Usage: #{script_name} [:backend] [options] [<idlfile> [<idlfile> ...]]\n\n" + " backend\t\tSpecifies the IDL language mapping backend to use.\n" + " \t\tDefault = :null\n\n" + " Active language mapping = :#{backend.name}" opts.separator '' opts.on('-I PATH', '--include=PATH', String, 'Adds include searchpath.', 'Default: none') { |v| self.options[:includepaths] << (v.end_with?('\\', '/') ? v : v + '/') } opts.on('-Dmacro=[value]', String, 'defines preprocessor macro') { |v| name, value = v.split('=') self.options[:macros][name] = (value ? value : true) } opts.on('-n NAMESPACE', '--namespace=NAMESPACE', String, 'Defines rootlevel enclosing namespace.', 'Default: nil') { |v| self.options[:namespace] = v } opts.on('-v', '--verbose', 'Set verbosity level. Repeat to increment.', 'Default: 0') { |_| self.options[:verbose] += 1 } opts.on('--debug', 'Set parser debug mode. Do NOT do this at home!', 'Default: off') { |_| self.options[:debug] = true } opts.on('--search-includepath', 'Use include paths to find main IDL source.', 'Default: off') { |_| self.options[:search_incpath] = true } opts.on('--no-input', 'Do not parse specified file(s) as input IDL.', 'Default: off') { |_| self.options[:no_input] = true } if @initopts[:preprocess] opts.on('--output=FILE', String, 'Specifies filename to generate output in.', 'Default: basename(idlfile)-\'.idl\'+<postfix>+<ext>') { |v| self.options[:output] = v } end # setup language mapping specific options be_options = OptionList.new @backend.setup_be(be_options, @initopts) be_options.to_option_parser(opts, self) opts.on('-V', '--version', 'Show version information and exit.') { puts "RIDL compiler #{RIDL_VERSION}" puts RIDL_COPYRIGHT puts '---' @backend.print_version exit } opts.separator "" opts.on('-h', '--help', 'Show this help message.') { puts opts puts exit } opts end