#!/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.
"""

from __future__ import print_function

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:]))
