#!/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_internals::'
                    '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()
