class NetLinx::Compiler

A wrapper class for the AMX NetLinx compiler executable (nlrc.exe).

Public Class Methods

new(**kwargs) click to toggle source

Checks for the AMX NetLinx compiler (third-party software, nlrc.exe) at the default installation path.

@option kwargs [String] :compiler_exe ('nlrc.exe') @option kwargs [String] :compiler_path Recommend a directory to look for

the compiler_exe.

@option kwargs [String] :use_wine (false) Set to true to force `wine` at

the front of the compiler command. This is automatic if nlrc.exe is
installed at Wine's default Program Files path.

@raise [NetLinx::NoCompilerError] Compiler not found.

# File lib/netlinx/compiler.rb, line 21
def initialize(**kwargs)
  @compiler_exe = kwargs.fetch :compiler_exe, 'nlrc.exe'
  user_specified_path = kwargs.fetch :compiler_path, nil
  @use_wine = kwargs.fetch :use_wine, false
  
  default_paths = [
    user_specified_path,
    'C:\Program Files (x86)\Common Files\AMXShare\COM', # 64-bit O/S path
    'C:\Program Files\Common Files\AMXShare\COM',       # 32-bit O/S path
    '~/.wine/drive_c/Program Files/Common Files/AMXShare/COM', # Wine path
  ].compact
  
  # Check for NetLinx compiler.
  default_paths.each do |path|
    if File.exists? File.expand_path(@compiler_exe, path)
      @compiler_path = path
      break
    end
  end
  
  # ---------------------------------------------------------
  # TODO: Check if the compiler was added to the system path.
  #       Execute system(@compiler_exe).
  # ---------------------------------------------------------
  
  # Compiler not found.
  raise NetLinx::NoCompilerError, "The NetLinx compiler (#{@compiler_exe}) could not be found on the system." \
    unless @compiler_path
end

Public Instance Methods

compile(compilable) click to toggle source

Compile the specified object with the NetLinx compiler. @see Test::NetLinx::Compilable.

# File lib/netlinx/compiler.rb, line 53
def compile(compilable)
  compiler = File.expand_path @compiler_exe, @compiler_path
  result   = []
  
  compilable.compiler_target_files.each do |target_file|
    # Construct paths.
    include_paths = "-I#{compilable.compiler_include_paths.join ';'}" unless
      compilable.compiler_include_paths.empty?
      
    module_paths = "-M#{compilable.compiler_module_paths.join ';'}" unless
      compilable.compiler_module_paths.empty?
      
    library_paths = "-L#{compilable.compiler_library_paths.join ';'}" unless
      compilable.compiler_library_paths.empty?
    
    # Run the NetLinx compiler.
    # Note: NLRC.exe v2.1 freaks out if empty arguments ("") are in the command.
    cmd  = ''
    cmd += 'wine ' if @use_wine or compiler.include? '/.wine/'
    cmd += "\"#{compiler}\" \"#{target_file}\""
    cmd += " \"#{include_paths}\"" if include_paths
    cmd += " \"#{module_paths}\""  if module_paths
    cmd += " \"#{library_paths}\"" if library_paths
    
    io = IO.popen cmd
    stream = io.read
    io.close
    
    # Build the result.
    result << NetLinx::CompilerResult.new(
      compiler_target_files:  [target_file],
      compiler_include_paths: compilable.compiler_include_paths,
      compiler_module_paths:  compilable.compiler_module_paths,
      compiler_library_paths: compilable.compiler_library_paths,
      stream: stream
    )
  end
  
  result
end