#!/usr/bin/ruby

# Scan
symbols = File.readlines(ARGV[0]).collect do |line|
 if line =~ /^(#MISSING:.*#)? (\([^\)]+\))?(.*) ([^ ]+)$/ then
   $~.captures
 else
   [line]
 end
end

# c++filt
symbols.collect! do |symbol|
 # if mangled c++ symbol
 if symbol.length > 1 and symbol[2] =~ /^_Z/ then
   # unmangle
   symbol[2] = '"' + `echo #{symbol[2]} | c++filt`.chomp! + '"'
   # add (optional|c++) if not present
   if symbol[1] then
     flags = symbol[1][1...-1].split("|")
     flags = (flags + ["optional", "c++"]).uniq
     symbol[1] = "(" + flags.join("|") + ")"
   else
     symbol[1] = "(optional|c++)"
   end
 end
 symbol
end

# Bubble sort
symbols.length.times do |index|
  (symbols.length - 1).downto(index) do |i|
    if symbols[i-1].length > 1 and symbols[i].length > 1 then
      symbols[i-1], symbols[i] = symbols[i], symbols[i-1] unless symbols[i-1][2] < symbols[i][2]
    end
  end
end

# Uniq
(symbols.length - 1).downto(1) do |i|
  symbols.delete_at(i) if symbols[i-1].length > 1 and symbols[i].length > 1 and not symbols[i-1][0] and not symbols[i][0] and symbols[i-1][2] == symbols[i][2]
end

# Output
symbols.each do |symbol|
  if symbol.length > 1 then
    puts "#{symbol[0]} #{symbol[1]}#{symbol[2]} #{symbol[3]}"
  else
    puts "#{symbol[0]}"
  end
end
