Module: LangScan::Perl

Defined in:
lib/langscan/perl.rb

Constant Summary collapse

PERLTOKENIZER_PATH =
$LOAD_PATH.map {|path|
  File.join(path, "langscan/perl/tokenizer.pl")
}.find {|path| File.file?(path) }

Class Method Summary collapse

Class Method Details

.abbrevObject



28
29
30
# File 'lib/langscan/perl.rb', line 28

def abbrev
  "perl"
end

.extnamesObject



32
33
34
# File 'lib/langscan/perl.rb', line 32

def extnames
  [".pl", ".PL", ".pm", ".t" ] # XXX remove ".t"
end

.nameObject



24
25
26
# File 'lib/langscan/perl.rb', line 24

def name
  "Perl"
end

.open_tokenizerObject



45
46
47
48
49
# File 'lib/langscan/perl.rb', line 45

def open_tokenizer 
  command_line = sprintf("perl %s 2>/dev/null", 
                         shell_escape(PERLTOKENIZER_PATH))
  @io = IO.popen(command_line, "r+")
end

.scan(input) ⇒ Object

LangScan::Perl.scan iterates over Perl program. It yields for each Fragment.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/langscan/perl.rb', line 53

def scan(input)
  open_tokenizer if @io.nil? or @io.closed? # in case of Perl error
  @io.puts(input.length)
  @io.write(input)
  inputlen = input.length
  buflen   = 0
  begin
    while (buflen < inputlen)
      type    = @io.readline.chomp.intern
      lineno  = @io.readline.chomp.to_i
      byteno  = @io.readline.chomp.to_i
      bodylen = @io.readline.chomp.to_i
      text    = @io.read(bodylen)
      if type.nil? or text.nil? or lineno.nil? or byteno.nil?
        raise ScanFailed.new("Unexpected output from tokenizer.pl")
      end
      yield Fragment.new(type, text, lineno, byteno)
      @io.read(1) # newline
      buflen += bodylen
    end
  rescue EOFError
    @io.close
    raise  ScanFailed.new("tokenizer.pl failed to parse")
  end
end

.shell_escape(file_name) ⇒ Object



41
42
43
# File 'lib/langscan/perl.rb', line 41

def shell_escape(file_name)
  '"' + file_name.gsub(/([$"\\`])/, "\\\\\\1") + '"'
end