#!/usr/bin/env python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Prints a report of symbols stripped by the linker due to being unused.

To use, build with these linker flags:
  -Wl,--gc-sections
  -Wl,--print-gc-sections
the first one is the default in Release; search build/common.gypi for it
and to see where to add the other.

Then build, saving the output into a file:
  make chrome 2>&1 | tee buildlog
and run this script on it:
  ./tools/unused-symbols-report.py buildlog > report.html
"""

import cgi
import optparse
import os
import re
import subprocess
import sys

cppfilt_proc = None
def Demangle(sym):
  """Demangle a C++ symbol by passing it through c++filt."""
  global cppfilt_proc
  if cppfilt_proc is None:
    cppfilt_proc = subprocess.Popen(['c++filt'], stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE)
  print >>cppfilt_proc.stdin, sym
  return cppfilt_proc.stdout.readline().strip()


def Unyuck(sym):
  """Attempt to prettify a C++ symbol by some basic heuristics."""
  sym = sym.replace('std::basic_string<char, std::char_traits<char>, '
                    'std::allocator<char> >', 'std::string')
  sym = sym.replace('std::basic_string<wchar_t, std::char_traits<wchar_t>, '
                    'std::allocator<wchar_t> >', 'std::wstring')
  sym = sym.replace('std::basic_string<unsigned short, '
                    'base::string16_char_traits, '
                    'std::allocator<unsigned short> >', 'string16')
  sym = re.sub(r', std::allocator<\S+\s+>', '', sym)
  return sym


def Parse(input, skip_paths=None, only_paths=None):
  """Parse the --print-gc-sections build output.

  Args:
    input: iterable over the lines of the build output

  Yields:
    (target name, path to .o file, demangled symbol)
  """
  symbol_re = re.compile(r"'\.text\.(\S+)' in file '(\S+)'$")
  path_re = re.compile(r"^out/[^/]+/[^/]+/([^/]+)/(.*)$")
  for line in input:
    match = symbol_re.search(line)
    if not match:
      continue
    symbol, path = match.groups()
    symbol = Unyuck(Demangle(symbol))
    path = os.path.normpath(path)
    if skip_paths and skip_paths in path:
      continue
    if only_paths and only_paths not in path:
      continue
    match = path_re.match(path)
    if not match:
      print >>sys.stderr, "Skipping weird path", path
      continue
    target, path = match.groups()
    yield target, path, symbol


# HTML header for our output page.
TEMPLATE_HEADER = """<!DOCTYPE html>
<head>
<style>
body {
  font-family: sans-serif;
  font-size: 0.8em;
}
h1, h2 {
  font-weight: normal;
  margin: 0.5em 0;
}
h2 {
  margin-top: 1em;
}
tr:hover {
  background: #eee;
}
.permalink {
  padding-left: 1ex;
  font-size: 80%;
  text-decoration: none;
  color: #ccc;
}
.symbol {
  font-family: WebKitWorkAround, monospace;
  margin-left: 4ex;
  text-indent: -4ex;
  padding: 0.5ex 1ex;
}
.file {
  padding: 0.5ex 1ex;
  padding-left: 2ex;
  font-family: WebKitWorkAround, monospace;
  font-size: 90%;
  color: #777;
}
</style>
</head>
<body>
<h1>chrome symbols deleted at link time</h1>
"""


def Output(iter):
  """Print HTML given an iterable of (target, path, symbol) tuples."""
  targets = {}
  for target, path, symbol in iter:
    entries = targets.setdefault(target, [])
    entries.append((symbol, path))

  print TEMPLATE_HEADER
  print "<p>jump to target:"
  print "<select onchange='document.location.hash = this.value'>"
  for target in sorted(targets.keys()):
    print "<option>%s</option>" % target
  print "</select></p>"

  for target in sorted(targets.keys()):
    print "<h2>%s" % target
    print "<a class=permalink href='#%s' name='%s'>#</a>" % (target, target)
    print "</h2>"
    print "<table width=100% cellspacing=0>"
    for symbol, path in sorted(targets[target]):
      htmlsymbol = cgi.escape(symbol).replace('::', '::<wbr>')
      print "<tr><td><div class=symbol>%s</div></td>" % htmlsymbol
      print "<td valign=top><div class=file>%s</div></td></tr>" % path
    print "</table>"


def main():
  parser = optparse.OptionParser(usage='%prog [options] buildoutput\n\n' +
                                 __doc__)
  parser.add_option("--skip-paths", metavar="STR", default="third_party",
                    help="skip paths matching STR [default=%default]")
  parser.add_option("--only-paths", metavar="STR",
                    help="only include paths matching STR [default=%default]")
  opts, args = parser.parse_args()

  if len(args) < 1:
    parser.print_help()
    sys.exit(1)

  iter = Parse(open(args[0]),
               skip_paths=opts.skip_paths,
               only_paths=opts.only_paths)
  Output(iter)


if __name__ == '__main__':
  main()
