Updated NasmELFGenerator to raise an exception if running the
[voodoo-lang.git] / lib / voodoo / generators / nasm_elf_generator.rb
blob02e802c5215667eb7b7fb80a8d6226ac021fbc55
1 require 'voodoo/config'
2 require 'voodoo/generators/command_postprocessor'
4 module Voodoo
5   # Class that generates ELF object files by invoking nasm on
6   # the output of a code generator that generates NASM assembly.
7   class NasmELFGenerator
8     def initialize nasmgenerator, nasm_extra_args
9       @nasmgenerator = nasmgenerator
10       @nasm_extra_args = nasm_extra_args
11       @output_file_suffix = '.o'
12     end
14     include CommandPostProcessor
16     def output_file_name input_name
17       input_name.sub(/\.voo$/, '') + @output_file_suffix
18     end
20     def output_file_suffix
21       @output_file_suffix
22     end
24     # Writes the generated code to the given IO handle
25     def write io
26       # Create temporary file to write NASM code to
27       if io.respond_to? :path
28         base = File.basename(io.path).sub(/([^.]*).*/, "\\1")
29       else
30         base = self.class.name
31       end
32       
33       Tempfile.open(base + '.asm') do |nasmfile|
34         begin
35           Tempfile.open(base + '.o') do |elffile|
36             begin
37               elffile.close
38               # Write NASM code to nsamfile
39               @nasmgenerator.write nasmfile
40               nasmfile.close
41               # Find out the name of the nasm executable
42               if ENV.has_key? 'NASM'
43                 nasm = ENV['NASM']
44               elsif ENV.has_key? 'YASM'
45                 nasm = ENV['YASM']
46               else
47                 nasm = Voodoo::Config.nasm_command
48               end
49               # Invoke nasm on nasmfile
50               command = "#{nasm} #{@nasm_extra_args}" +
51                 " -o #{shell_encode elffile.path}" +
52                 " #{shell_encode nasmfile.path}"
53               if system(command)
54                 write_file_to_io elffile.path, io
55               else
56                 raise "Command (#{command}) failed " +
57                   " with status #{$?.exitstatus}"
58               end
59             ensure
60               elffile.unlink
61             end
62           end
63         ensure
64           nasmfile.unlink
65         end
66       end
67     end
68   end
69 end