require 'voodoo/config'
require 'voodoo/generators/command_postprocessor'

module Voodoo
  # Class that generates ELF object files by invoking nasm on
  # the output of a code generator that generates NASM assembly.
  class NasmELFGenerator
    def initialize nasmgenerator, nasm_extra_args
      @nasmgenerator = nasmgenerator
      @nasm_extra_args = nasm_extra_args
      @output_file_suffix = '.o'
    end

    include CommandPostProcessor

    def output_file_name input_name
      input_name.sub(/\.voo$/, '') + @output_file_suffix
    end

    def output_file_suffix
      @output_file_suffix
    end

    # Writes the generated code to the given IO handle
    def write io
      # Create temporary file to write NASM code to
      if io.respond_to? :path
        base = File.basename(io.path).sub(/([^.]*).*/, "\\1")
      else
        base = self.class.name
      end
      
      Tempfile.open(base + '.asm') do |nasmfile|
        Tempfile.open(base + '.o') do |elffile|
          elffile.close
          # Write NASM code to nsamfile
          @nasmgenerator.write nasmfile
          nasmfile.close
          # Find out the name of the nasm executable
          if ENV.has_key? 'NASM'
            nasm = ENV['NASM']
          elsif ENV.has_key? 'YASM'
            nasm = ENV['YASM']
          else
            nasm = Voodoo::Config.nasm_command
          end
          # Invoke nasm on nasmfile
          command = "#{nasm} #{@nasm_extra_args}" +
            " -o #{shell_encode elffile.path}" +
            " #{shell_encode nasmfile.path}"
          if system(command)
            write_file_to_io elffile.path, io
          end
          elffile.unlink
        end
        nasmfile.unlink
      end
    end
  end
end
