github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/third_party/googlemock/scripts/fuse_gmock_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_gmock_files.py v0.1.0
    33  Fuses Google Mock and Google Test source code into two .h files and a .cc file.
    34  
    35  SYNOPSIS
    36         fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
    37  
    38         Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
    39         code, assuming Google Test is in the GMOCK_ROOT_DIR/gtest
    40         sub-directory, and generates three files:
    41         OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
    42         OUTPUT_DIR/gmock-gtest-all.cc.  Then you can build your tests
    43         by adding OUTPUT_DIR to the include search path and linking
    44         with OUTPUT_DIR/gmock-gtest-all.cc.  These three files contain
    45         everything you need to use Google Mock.  Hence you can
    46         "install" Google Mock by copying them to wherever you want.
    47  
    48         GMOCK_ROOT_DIR can be omitted and defaults to the parent
    49         directory of the directory holding this script.
    50  
    51  EXAMPLES
    52         ./fuse_gmock_files.py fused_gmock
    53         ./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
    54  
    55  This tool is experimental.  In particular, it assumes that there is no
    56  conditional inclusion of Google Mock or Google Test headers.  Please
    57  report any problems to googlemock@googlegroups.com.  You can read
    58  http://code.google.com/p/googlemock/wiki/CookBook for more
    59  information.
    60  """
    61  
    62  __author__ = 'wan@google.com (Zhanyong Wan)'
    63  
    64  import os
    65  import re
    66  import sets
    67  import sys
    68  
    69  # We assume that this file is in the scripts/ directory in the Google
    70  # Mock root directory.
    71  DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
    72  
    73  # We need to call into gtest/scripts/fuse_gtest_files.py.
    74  sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, 'gtest/scripts'))
    75  import fuse_gtest_files
    76  gtest = fuse_gtest_files
    77  
    78  # Regex for matching '#include "gmock/..."'.
    79  INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
    80  
    81  # Where to find the source seed files.
    82  GMOCK_H_SEED = 'include/gmock/gmock.h'
    83  GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
    84  
    85  # Where to put the generated files.
    86  GTEST_H_OUTPUT = 'gtest/gtest.h'
    87  GMOCK_H_OUTPUT = 'gmock/gmock.h'
    88  GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
    89  
    90  
    91  def GetGTestRootDir(gmock_root):
    92    """Returns the root directory of Google Test."""
    93  
    94    return os.path.join(gmock_root, 'gtest')
    95  
    96  
    97  def ValidateGMockRootDir(gmock_root):
    98    """Makes sure gmock_root points to a valid gmock root directory.
    99  
   100    The function aborts the program on failure.
   101    """
   102  
   103    gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
   104    gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
   105    gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
   106  
   107  
   108  def ValidateOutputDir(output_dir):
   109    """Makes sure output_dir points to a valid output directory.
   110  
   111    The function aborts the program on failure.
   112    """
   113  
   114    gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
   115    gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
   116    gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
   117  
   118  
   119  def FuseGMockH(gmock_root, output_dir):
   120    """Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
   121  
   122    output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
   123    processed_files = sets.Set()  # Holds all gmock headers we've processed.
   124  
   125    def ProcessFile(gmock_header_path):
   126      """Processes the given gmock header file."""
   127  
   128      # We don't process the same header twice.
   129      if gmock_header_path in processed_files:
   130        return
   131  
   132      processed_files.add(gmock_header_path)
   133  
   134      # Reads each line in the given gmock header.
   135      for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
   136        m = INCLUDE_GMOCK_FILE_REGEX.match(line)
   137        if m:
   138          # It's '#include "gmock/..."' - let's process it recursively.
   139          ProcessFile('include/' + m.group(1))
   140        else:
   141          m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
   142          if m:
   143            # It's '#include "gtest/foo.h"'.  We translate it to
   144            # "gtest/gtest.h", regardless of what foo is, since all
   145            # gtest headers are fused into gtest/gtest.h.
   146  
   147            # There is no need to #include gtest.h twice.
   148            if not gtest.GTEST_H_SEED in processed_files:
   149              processed_files.add(gtest.GTEST_H_SEED)
   150              output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
   151          else:
   152            # Otherwise we copy the line unchanged to the output file.
   153            output_file.write(line)
   154  
   155    ProcessFile(GMOCK_H_SEED)
   156    output_file.close()
   157  
   158  
   159  def FuseGMockAllCcToFile(gmock_root, output_file):
   160    """Scans folder gmock_root to fuse gmock-all.cc into output_file."""
   161  
   162    processed_files = sets.Set()
   163  
   164    def ProcessFile(gmock_source_file):
   165      """Processes the given gmock source file."""
   166  
   167      # We don't process the same #included file twice.
   168      if gmock_source_file in processed_files:
   169        return
   170  
   171      processed_files.add(gmock_source_file)
   172  
   173      # Reads each line in the given gmock source file.
   174      for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
   175        m = INCLUDE_GMOCK_FILE_REGEX.match(line)
   176        if m:
   177          # It's '#include "gmock/foo.h"'.  We treat it as '#include
   178          # "gmock/gmock.h"', as all other gmock headers are being fused
   179          # into gmock.h and cannot be #included directly.
   180  
   181          # There is no need to #include "gmock/gmock.h" more than once.
   182          if not GMOCK_H_SEED in processed_files:
   183            processed_files.add(GMOCK_H_SEED)
   184            output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
   185        else:
   186          m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
   187          if m:
   188            # It's '#include "gtest/..."'.
   189            # There is no need to #include gtest.h as it has been
   190            # #included by gtest-all.cc.
   191            pass
   192          else:
   193            m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
   194            if m:
   195              # It's '#include "src/foo"' - let's process it recursively.
   196              ProcessFile(m.group(1))
   197            else:
   198              # Otherwise we copy the line unchanged to the output file.
   199              output_file.write(line)
   200  
   201    ProcessFile(GMOCK_ALL_CC_SEED)
   202  
   203  
   204  def FuseGMockGTestAllCc(gmock_root, output_dir):
   205    """Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
   206  
   207    output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w')
   208    # First, fuse gtest-all.cc into gmock-gtest-all.cc.
   209    gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
   210    # Next, append fused gmock-all.cc to gmock-gtest-all.cc.
   211    FuseGMockAllCcToFile(gmock_root, output_file)
   212    output_file.close()
   213  
   214  
   215  def FuseGMock(gmock_root, output_dir):
   216    """Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
   217  
   218    ValidateGMockRootDir(gmock_root)
   219    ValidateOutputDir(output_dir)
   220  
   221    gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
   222    FuseGMockH(gmock_root, output_dir)
   223    FuseGMockGTestAllCc(gmock_root, output_dir)
   224  
   225  
   226  def main():
   227    argc = len(sys.argv)
   228    if argc == 2:
   229      # fuse_gmock_files.py OUTPUT_DIR
   230      FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
   231    elif argc == 3:
   232      # fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
   233      FuseGMock(sys.argv[1], sys.argv[2])
   234    else:
   235      print __doc__
   236      sys.exit(1)
   237  
   238  
   239  if __name__ == '__main__':
   240    main()