#!/usr/bin/env python
# Copyright (c) 2012 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.

"""This script should be run manually on occasion to make sure all PPAPI types
have appropriate size checking.
"""

import optparse
import os
import subprocess
import sys


# The string that the PrintNamesAndSizes plugin uses to indicate a type is
# expected to have architecture-dependent size.
ARCH_DEPENDENT_STRING = "ArchDependentSize"


COPYRIGHT_STRING_C = (
"""/* Copyright (c) %s 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.
 *
 * This file has compile assertions for the sizes of types that are dependent
 * on the architecture for which they are compiled (i.e., 32-bit vs 64-bit).
 */

""") % datetime.date.today().year


class SourceLocation(object):
  """A class representing the source location of a definiton."""

  def __init__(self, filename="", start_line=-1, end_line=-1):
    self.filename = os.path.normpath(filename)
    self.start_line = start_line
    self.end_line = end_line


class TypeInfo(object):
  """A class representing information about a C++ type.  It contains the
  following fields:
   - kind:  The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
   - name:  The unmangled string name of the type.
   - size:  The size in bytes of the type.
   - arch_dependent:  True if the type may have architecture dependent size
                      according to PrintNamesAndSizes.  False otherwise.  Types
                      which are considered architecture-dependent from 32-bit
                      to 64-bit are pointers, longs, unsigned longs, and any
                      type that contains an architecture-dependent type.
   - source_location:  A SourceLocation describing where the type is defined.
   - target:  The target Clang was compiling when it found the type definition.
              This is used only for diagnostic output.
   - parsed_line:  The line which Clang output which was used to create this
                   TypeInfo (as the info_string parameter to __init__).  This is
                   used only for diagnostic output.
  """

  def __init__(self, info_string, target):
    """Create a TypeInfo from a given info_string.  Also store the name of the
    target for which the TypeInfo was first created just so we can print useful
    error information.
    info_string is a comma-delimited string of the following form:
    kind,name,size,arch_dependent,source_file,start_line,end_line
    Where:
   - kind:  The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
   - name:  The unmangled string name of the type.
   - size:  The size in bytes of the type.
   - arch_dependent:  'ArchDependentSize' if the type has architecture-dependent
                      size, NotArchDependentSize otherwise.
   - source_file:  The source file in which the type is defined.
   - first_line:  The first line of the definition (counting from 0).
   - last_line:  The last line of the definition (counting from 0).
   This should match the output of the PrintNamesAndSizes plugin.
   """
    [self.kind, self.name, self.size, arch_dependent_string, source_file,
        start_line, end_line] = info_string.split(',')
    self.target = target
    self.parsed_line = info_string
    # Note that Clang counts line numbers from 1, but we want to count from 0.
    self.source_location = SourceLocation(source_file,
                                          int(start_line)-1,
                                          int(end_line)-1)
    self.arch_dependent = (arch_dependent_string == ARCH_DEPENDENT_STRING)


class FilePatch(object):
  """A class representing a set of line-by-line changes to a particular file.
  None of the changes are applied until Apply is called.  All line numbers are
  counted from 0.
  """

  def __init__(self, filename):
    self.filename = filename
    self.linenums_to_delete = set()
    # A dictionary from line number to an array of strings to be inserted at
    # that line number.
    self.lines_to_add = {}

  def Delete(self, start_line, end_line):
    """Make the patch delete the lines starting with |start_line| up to but not
    including |end_line|.
    """
    self.linenums_to_delete |= set(range(start_line, end_line))

  def Add(self, text, line_number):
    """Add the given text before the text on the given line number."""
    if line_number in self.lines_to_add:
      self.lines_to_add[line_number].append(text)
    else:
      self.lines_to_add[line_number] = [text]

  def Apply(self):
    """Apply the patch by writing it to self.filename."""
    # Read the lines of the existing file in to a list.
    sourcefile = open(self.filename, "r")
    file_lines = sourcefile.readlines()
    sourcefile.close()
    # Now apply the patch.  Our strategy is to keep the array at the same size,
    # and just edit strings in the file_lines list as necessary.  When we delete
    # lines, we just blank the line and keep it in the list.  When we add lines,
    # we just prepend the added source code to the start of the existing line at
    # that line number.  This way, all the line numbers we cached from calls to
    # Add and Delete remain valid list indices, and we don't have to worry about
    # maintaining any offsets.  Each element of file_lines at the end may
    # contain any number of lines (0 or more) delimited by carriage returns.
    for linenum_to_delete in self.linenums_to_delete:
      file_lines[linenum_to_delete] = "";
    for linenum, sourcelines in self.lines_to_add.items():
      # Sort the lines we're adding so we get relatively consistent results.
      sourcelines.sort()
      # Prepend the new lines.  When we output
      file_lines[linenum] = "".join(sourcelines) + file_lines[linenum]
    newsource = open(self.filename, "w")
    for line in file_lines:
      newsource.write(line)
    newsource.close()


def CheckAndInsert(typeinfo, typeinfo_map):
  """Check if a TypeInfo exists already in the given map with the same name.  If
  so, make sure the size is consistent.
  - If the name exists but the sizes do not match, print a message and
    exit with non-zero exit code.
  - If the name exists and the sizes match, do nothing.
  - If the name does not exist, insert the typeinfo in to the map.

  """
  # If the type is unnamed, ignore it.
  if typeinfo.name == "":
    return
  # If the size is 0, ignore it.
  elif int(typeinfo.size) == 0:
    return
  # If the type is not defined under ppapi, ignore it.
  elif typeinfo.source_location.filename.find("ppapi") == -1:
    return
  # If the type is defined under GLES2, ignore it.
  elif typeinfo.source_location.filename.find("GLES2") > -1:
    return
  # If the type is an interface (by convention, starts with PPP_ or PPB_),
  # ignore it.
  elif (typeinfo.name[:4] == "PPP_") or (typeinfo.name[:4] == "PPB_"):
    return
  elif typeinfo.name in typeinfo_map:
    if typeinfo.size != typeinfo_map[typeinfo.name].size:
      print "Error: '" + typeinfo.name + "' is", \
          typeinfo_map[typeinfo.name].size, \
          "bytes on target '" + typeinfo_map[typeinfo.name].target + \
          "', but", typeinfo.size, "on target '" + typeinfo.target + "'"
      print typeinfo_map[typeinfo.name].parsed_line
      print typeinfo.parsed_line
      sys.exit(1)
    else:
      # It's already in the map and the sizes match.
      pass
  else:
    typeinfo_map[typeinfo.name] = typeinfo


def ProcessTarget(clang_command, target, types):
  """Run clang using the given clang_command for the given target string.  Parse
  the output to create TypeInfos for each discovered type.  Insert each type in
  to the 'types' dictionary.  If the type already exists in the types
  dictionary, make sure that the size matches what's already in the map.  If
  not, exit with an error message.
  """
  p = subprocess.Popen(clang_command + " -triple " + target,
                       shell=True,
                       stdout=subprocess.PIPE)
  lines = p.communicate()[0].split()
  for line in lines:
    typeinfo = TypeInfo(line, target)
    CheckAndInsert(typeinfo, types)


def ToAssertionCode(typeinfo):
  """Convert the TypeInfo to an appropriate C compile assertion.
  If it's a struct (Record in Clang terminology), we want a line like this:
    PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(<name>, <size>);\n
  Enums:
    PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(<name>, <size>);\n
  Typedefs:
    PP_COMPILE_ASSERT_SIZE_IN_BYTES(<name>, <size>);\n

  """
  line = "PP_COMPILE_ASSERT_"
  if typeinfo.kind == "Enum":
    line += "ENUM_"
  elif typeinfo.kind == "Record":
    line += "STRUCT_"
  line += "SIZE_IN_BYTES("
  line += typeinfo.name
  line += ", "
  line += typeinfo.size
  line += ");\n"
  return line


def IsMacroDefinedName(typename):
  """Return true iff the given typename came from a PPAPI compile assertion."""
  return typename.find("PP_Dummy_Struct_For_") == 0


def WriteArchSpecificCode(types, root, filename):
  """Write a header file that contains a compile-time assertion for the size of
     each of the given typeinfos, in to a file named filename rooted at root.
  """
  assertion_lines = [ToAssertionCode(typeinfo) for typeinfo in types]
  assertion_lines.sort()
  outfile = open(os.path.join(root, filename), "w")
  header_guard = "PPAPI_TESTS_" + filename.upper().replace(".", "_") + "_"
  outfile.write(COPYRIGHT_STRING_C)
  outfile.write('#ifndef ' + header_guard + '\n')
  outfile.write('#define ' + header_guard + '\n\n')
  outfile.write('#include "ppapi/tests/test_struct_sizes.c"\n\n')
  for line in assertion_lines:
    outfile.write(line)
  outfile.write('\n#endif  /* ' + header_guard + ' */\n')


def main(argv):
  # See README file for example command-line invocation.  This script runs the
  # PrintNamesAndSizes Clang plugin with 'test_struct_sizes.c' as input, which
  # should include all C headers and all existing size checks.  It runs the
  # plugin multiple times;  once for each of a set of targets, some 32-bit and
  # some 64-bit.  It verifies that wherever possible, types have a consistent
  # size on both platforms.  Types that can't easily have consistent size (e.g.
  # ones that contain a pointer) are checked to make sure they are consistent
  # for all 32-bit platforms and consistent on all 64-bit platforms, but the
  # sizes on 32 vs 64 are allowed to differ.
  #
  # Then, if all the types have consistent size as expected, compile assertions
  # are added to the source code.  Types whose size is independent of
  # architectureacross have their compile assertions placed immediately after
  # their definition in the C API header.  Types whose size differs on 32-bit
  # vs 64-bit have a compile assertion placed in each of:
  # ppapi/tests/arch_dependent_sizes_32.h and
  # ppapi/tests/arch_dependent_sizes_64.h.
  #
  # Note that you should always check the results of the tool to make sure
  # they are sane.
  parser = optparse.OptionParser()
  parser.add_option(
      '-c', '--clang-path', dest='clang_path',
      default=(''),
      help='the path to the clang binary (default is to get it from your path)')
  parser.add_option(
      '-p', '--plugin', dest='plugin',
      default='tests/clang/libPrintNamesAndSizes.so',
      help='The path to the PrintNamesAndSizes plugin library.')
  parser.add_option(
      '--targets32', dest='targets32',
      default='i386-pc-linux,arm-pc-linux,i386-pc-win32',
      help='Which 32-bit target triples to provide to clang.')
  parser.add_option(
      '--targets64', dest='targets64',
      default='x86_64-pc-linux,x86_64-pc-win',
      help='Which 32-bit target triples to provide to clang.')
  parser.add_option(
      '-r', '--ppapi-root', dest='ppapi_root',
      default='.',
      help='The root directory of ppapi.')
  options, args = parser.parse_args(argv)
  if args:
    parser.print_help()
    print 'ERROR: invalid argument'
    sys.exit(1)

  clang_executable = os.path.join(options.clang_path, 'clang')
  clang_command = clang_executable + " -cc1" \
      + " -load " + options.plugin \
      + " -plugin PrintNamesAndSizes" \
      + " -I" + os.path.join(options.ppapi_root, "..") \
      + " " \
      + os.path.join(options.ppapi_root, "tests", "test_struct_sizes.c")

  # Dictionaries mapping type names to TypeInfo objects.
  # Types that have size dependent on architecture, for 32-bit
  types32 = {}
  # Types that have size dependent on architecture, for 64-bit
  types64 = {}
  # Note that types32 and types64 should contain the same types, but with
  # different sizes.

  # Types whose size should be consistent regardless of architecture.
  types_independent = {}

  # Now run clang for each target.  Along the way, make sure architecture-
  # dependent types are consistent sizes on all 32-bit platforms and consistent
  # on all 64-bit platforms.
  targets32 = options.targets32.split(',');
  for target in targets32:
    # For each 32-bit target, run the PrintNamesAndSizes Clang plugin to get
    # information about all types in the translation unit, and add a TypeInfo
    # for each of them to types32.  If any size mismatches are found,
    # ProcessTarget will spit out an error and exit.
    ProcessTarget(clang_command, target, types32)
  targets64 = options.targets64.split(',');
  for target in targets64:
    # Do the same as above for each 64-bit target;  put all types in types64.
    ProcessTarget(clang_command, target, types64)

  # Now for each dictionary, find types whose size are consistent regardless of
  # architecture, and move those in to types_independent.  Anywhere sizes
  # differ, make sure they are expected to be architecture-dependent based on
  # their structure.  If we find types which could easily be consistent but
  # aren't, spit out an error and exit.
  types_independent = {}
  for typename, typeinfo32 in types32.items():
    if (typename in types64):
      typeinfo64 = types64[typename]
      if (typeinfo64.size == typeinfo32.size):
        # The types are the same size, so we can treat it as arch-independent.
        types_independent[typename] = typeinfo32
        del types32[typename]
        del types64[typename]
      elif (typeinfo32.arch_dependent or typeinfo64.arch_dependent):
        # The type is defined in such a way that it would be difficult to make
        # its size consistent.  E.g., it has pointers.  We'll leave it in the
        # arch-dependent maps so that we can put arch-dependent size checks in
        # test code.
        pass
      else:
        # The sizes don't match, but there's no reason they couldn't.  It's
        # probably due to an alignment mismatch between Win32/NaCl vs Linux32/
        # Mac32.
        print "Error: '" + typename + "' is", typeinfo32.size, \
            "bytes on target '" + typeinfo32.target + \
            "', but", typeinfo64.size, "on target '" + typeinfo64.target + "'"
        print typeinfo32.parsed_line
        print typeinfo64.parsed_line
        sys.exit(1)
    else:
      print "WARNING:  Type '", typename, "' was defined for target '",
      print typeinfo32.target, ", but not for any 64-bit targets."

  # Now we have all the information we need to generate our static assertions.
  # Types that have consistent size across architectures will have the static
  # assertion placed immediately after their definition.  Types whose size
  # depends on 32-bit vs 64-bit architecture will have checks placed in
  # tests/arch_dependent_sizes_32/64.h.

  # This dictionary maps file names to FilePatch objects.  We will add items
  # to it as needed.  Each FilePatch represents a set of changes to make to the
  # associated file (additions and deletions).
  file_patches = {}

  # Find locations of existing macros, and just delete them all.  Note that
  # normally, only things in 'types_independent' need to be deleted, as arch-
  # dependent checks exist in tests/arch_dependent_sizes_32/64.h, which are
  # always completely over-ridden.  However, it's possible that a type that used
  # to be arch-independent has changed to now be arch-dependent (e.g., because
  # a pointer was added), and we want to delete the old check in that case.
  for name, typeinfo in \
      types_independent.items() + types32.items() + types64.items():
    if IsMacroDefinedName(name):
      sourcefile = typeinfo.source_location.filename
      if sourcefile not in file_patches:
        file_patches[sourcefile] = FilePatch(sourcefile)
      file_patches[sourcefile].Delete(typeinfo.source_location.start_line,
                                      typeinfo.source_location.end_line+1)

  # Add a compile-time assertion for each type whose size is independent of
  # architecture.  These assertions go immediately after the class definition.
  for name, typeinfo in types_independent.items():
    # Ignore dummy types that were defined by macros and also ignore types that
    # are 0 bytes (i.e., typedefs to void).
    if not IsMacroDefinedName(name) and typeinfo.size > 0:
      sourcefile = typeinfo.source_location.filename
      if sourcefile not in file_patches:
        file_patches[sourcefile] = FilePatch(sourcefile)
      # Add the assertion code just after the definition of the type.
      # E.g.:
      # struct Foo {
      #   int32_t x;
      # };
      # PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(Foo, 4); <---Add this line
      file_patches[sourcefile].Add(ToAssertionCode(typeinfo),
                                   typeinfo.source_location.end_line+1)

  # Apply our patches.  This actually edits the files containing the definitions
  # for the types in types_independent.
  for filename, patch in file_patches.items():
    patch.Apply()

  # Write out a file of checks for 32-bit architectures and a separate file for
  # 64-bit architectures.  These only have checks for types that are
  # architecture-dependent.
  c_source_root = os.path.join(options.ppapi_root, "tests")
  WriteArchSpecificCode(types32.values(),
                        c_source_root,
                        "arch_dependent_sizes_32.h")
  WriteArchSpecificCode(types64.values(),
                        c_source_root,
                        "arch_dependent_sizes_64.h")

  return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
