import re


def _normalize_samples(samples):
  """Normalizes the samples in the given function body.

  Normalization just means that we redact inlined function names. This is
  done so that a bit of templating doesn't make two function bodies look
  distinct. Namely:

  template <typename T>
  __attribute__((noinline))
  int getNumber() { return 1; }

  template <typename T>
  __attribute__((noinline))
  int getNumberIndirectly() { return getNumber<T>(); }

  int main() {
    return getNumber<int>() + getNumber<float>();
  }

  If the profile has the mangled name for getNumber<float> in
  getNumberIndirectly<float> (and similar for <int>), we'll consider them to
  be distinct when they're not.
  """

  # I'm not actually sure if this ends up being an issue in practice, but it's
  # simple enough to guard against.
  inlined_re = re.compile(r'(^\s*\d+): [^:]+:(\s*\d+)\s*$')
  result = []
  for s in samples:
    m = inlined_re.match(s)
    if m:
      result.append('%s: __REDACTED__:%s' % m.groups())
    else:
      result.append(s)
  return tuple(result)