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

module Voodoo
  # Class that generates ELF object files by invoking the GNU assembler on
  # the output of a code generator that generates GNU assembly.
  class GasELFGenerator
    def initialize asmgenerator, extra_args
      @asmgenerator = asmgenerator
      @extra_args = 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 assembly code to
      if io.respond_to? :path
        base = File.basename(io.path).sub(/([^.]*).*/, "\\1")
      else
        base = self.class.name
      end
      
      Tempfile.open(base + '.s') do |asmfile|
        Tempfile.open(base + '.o') do |elffile|
          elffile.close
          # Write assembly code to nsamfile
          @asmgenerator.write asmfile
          asmfile.close
          # Find out the name of the GNU assembler
          gas = Voodoo::Config.gas_command
          # Invoke gas on asmfile
          command = "#{gas} #{@extra_args}" +
            " -o #{shell_encode elffile.path}" +
            " #{shell_encode asmfile.path}"
          if system(command)
            write_file_to_io elffile.path, io
          end
          elffile.unlink
        end
        asmfile.unlink
      end
    end
  end
end
