github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/third_party/googlemock/gtest/scripts/fuse_gtest_files.py (about)

     1  #!/usr/bin/env python
     2  #
     3  # Copyright 2009, Google Inc.
     4  # All rights reserved.
     5  #
     6  # Redistribution and use in source and binary forms, with or without
     7  # modification, are permitted provided that the following conditions are
     8  # met:
     9  #
    10  #     * Redistributions of source code must retain the above copyright
    11  # notice, this list of conditions and the following disclaimer.
    12  #     * Redistributions in binary form must reproduce the above
    13  # copyright notice, this list of conditions and the following disclaimer
    14  # in the documentation and/or other materials provided with the
    15  # distribution.
    16  #     * Neither the name of Google Inc. nor the names of its
    17  # contributors may be used to endorse or promote products derived from
    18  # this software without specific prior written permission.
    19  #
    20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  """fuse_gtest_files.py v0.2.0
    33  Fuses Google Test source code into a .h file and a .cc file.
    34  
    35  SYNOPSIS
    36         fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR
    37  
    38         Scans GTEST_ROOT_DIR for Google Test source code, and generates
    39         two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc.
    40         Then you can build your tests by adding OUTPUT_DIR to the include
    41         search path and linking with OUTPUT_DIR/gtest/gtest-all.cc.  These
    42         two files contain everything you need to use Google Test.  Hence
    43         you can "install" Google Test by copying them to wherever you want.
    44  
    45         GTEST_ROOT_DIR can be omitted and defaults to the parent
    46         directory of the directory holding this script.
    47  
    48  EXAMPLES
    49         ./fuse_gtest_files.py fused_gtest
    50         ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest
    51  
    52  This tool is experimental.  In particular, it assumes that there is no
    53  conditional inclusion of Google Test headers.  Please report any
    54  problems to googletestframework@googlegroups.com.  You can read
    55  http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for
    56  more information.
    57  """
    58  
    59  __author__ = 'wan@google.com (Zhanyong Wan)'
    60  
    61  import os
    62  import re
    63  import sets
    64  import sys
    65  
    66  # We assume that this file is in the scripts/ directory in the Google
    67  # Test root directory.
    68  DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
    69  
    70  # Regex for matching '#include "gtest/..."'.
    71  INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"')
    72  
    73  # Regex for matching '#include "src/..."'.
    74  INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
    75  
    76  # Where to find the source seed files.
    77  GTEST_H_SEED = 'include/gtest/gtest.h'
    78  GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
    79  GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
    80  
    81  # Where to put the generated files.
    82  GTEST_H_OUTPUT = 'gtest/gtest.h'
    83  GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
    84  
    85  
    86  def VerifyFileExists(directory, relative_path):
    87    """Verifies that the given file exists; aborts on failure.
    88  
    89    relative_path is the file path relative to the given directory.
    90    """
    91  
    92    if not os.path.isfile(os.path.join(directory, relative_path)):
    93      print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
    94                                                        directory)
    95      print ('Please either specify a valid project root directory '
    96             'or omit it on the command line.')
    97      sys.exit(1)
    98  
    99  
   100  def ValidateGTestRootDir(gtest_root):
   101    """Makes sure gtest_root points to a valid gtest root directory.
   102  
   103    The function aborts the program on failure.
   104    """
   105  
   106    VerifyFileExists(gtest_root, GTEST_H_SEED)
   107    VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
   108  
   109  
   110  def VerifyOutputFile(output_dir, relative_path):
   111    """Verifies that the given output file path is valid.
   112  
   113    relative_path is relative to the output_dir directory.
   114    """
   115  
   116    # Makes sure the output file either doesn't exist or can be overwritten.
   117    output_file = os.path.join(output_dir, relative_path)
   118    if os.path.exists(output_file):
   119      # TODO(wan@google.com): The following user-interaction doesn't
   120      # work with automated processes.  We should provide a way for the
   121      # Makefile to force overwriting the files.
   122      print ('%s already exists in directory %s - overwrite it? (y/N) ' %
   123             (relative_path, output_dir))
   124      answer = sys.stdin.readline().strip()
   125      if answer not in ['y', 'Y']:
   126        print 'ABORTED.'
   127        sys.exit(1)
   128  
   129    # Makes sure the directory holding the output file exists; creates
   130    # it and all its ancestors if necessary.
   131    parent_directory = os.path.dirname(output_file)
   132    if not os.path.isdir(parent_directory):
   133      os.makedirs(parent_directory)
   134  
   135  
   136  def ValidateOutputDir(output_dir):
   137    """Makes sure output_dir points to a valid output directory.
   138  
   139    The function aborts the program on failure.
   140    """
   141  
   142    VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
   143    VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
   144  
   145  
   146  def FuseGTestH(gtest_root, output_dir):
   147    """Scans folder gtest_root to generate gtest/gtest.h in output_dir."""
   148  
   149    output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w')
   150    processed_files = sets.Set()  # Holds all gtest headers we've processed.
   151  
   152    def ProcessFile(gtest_header_path):
   153      """Processes the given gtest header file."""
   154  
   155      # We don't process the same header twice.
   156      if gtest_header_path in processed_files:
   157        return
   158  
   159      processed_files.add(gtest_header_path)
   160  
   161      # Reads each line in the given gtest header.
   162      for line in file(os.path.join(gtest_root, gtest_header_path), 'r'):
   163        m = INCLUDE_GTEST_FILE_REGEX.match(line)
   164        if m:
   165          # It's '#include "gtest/..."' - let's process it recursively.
   166          ProcessFile('include/' + m.group(1))
   167        else:
   168          # Otherwise we copy the line unchanged to the output file.
   169          output_file.write(line)
   170  
   171    ProcessFile(GTEST_H_SEED)
   172    output_file.close()
   173  
   174  
   175  def FuseGTestAllCcToFile(gtest_root, output_file):
   176    """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
   177  
   178    processed_files = sets.Set()
   179  
   180    def ProcessFile(gtest_source_file):
   181      """Processes the given gtest source file."""
   182  
   183      # We don't process the same #included file twice.
   184      if gtest_source_file in processed_files:
   185        return
   186  
   187      processed_files.add(gtest_source_file)
   188  
   189      # Reads each line in the given gtest source file.
   190      for line in file(os.path.join(gtest_root, gtest_source_file), 'r'):
   191        m = INCLUDE_GTEST_FILE_REGEX.match(line)
   192        if m:
   193          if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
   194            # It's '#include "gtest/gtest-spi.h"'.  This file is not
   195            # #included by "gtest/gtest.h", so we need to process it.
   196            ProcessFile(GTEST_SPI_H_SEED)
   197          else:
   198            # It's '#include "gtest/foo.h"' where foo is not gtest-spi.
   199            # We treat it as '#include "gtest/gtest.h"', as all other
   200            # gtest headers are being fused into gtest.h and cannot be
   201            # #included directly.
   202  
   203            # There is no need to #include "gtest/gtest.h" more than once.
   204            if not GTEST_H_SEED in processed_files:
   205              processed_files.add(GTEST_H_SEED)
   206              output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
   207        else:
   208          m = INCLUDE_SRC_FILE_REGEX.match(line)
   209          if m:
   210            # It's '#include "src/foo"' - let's process it recursively.
   211            ProcessFile(m.group(1))
   212          else:
   213            output_file.write(line)
   214  
   215    ProcessFile(GTEST_ALL_CC_SEED)
   216  
   217  
   218  def FuseGTestAllCc(gtest_root, output_dir):
   219    """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
   220  
   221    output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
   222    FuseGTestAllCcToFile(gtest_root, output_file)
   223    output_file.close()
   224  
   225  
   226  def FuseGTest(gtest_root, output_dir):
   227    """Fuses gtest.h and gtest-all.cc."""
   228  
   229    ValidateGTestRootDir(gtest_root)
   230    ValidateOutputDir(output_dir)
   231  
   232    FuseGTestH(gtest_root, output_dir)
   233    FuseGTestAllCc(gtest_root, output_dir)
   234  
   235  
   236  def main():
   237    argc = len(sys.argv)
   238    if argc == 2:
   239      # fuse_gtest_files.py OUTPUT_DIR
   240      FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
   241    elif argc == 3:
   242      # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
   243      FuseGTest(sys.argv[1], sys.argv[2])
   244    else:
   245      print __doc__
   246      sys.exit(1)
   247  
   248  
   249  if __name__ == '__main__':
   250    main()