fuse_gmock_files.py (googletest-release-1.10.0) | : | fuse_gmock_files.py (googletest-release-1.11.0) | ||
---|---|---|---|---|
skipping to change at line 31 | skipping to change at line 31 | |||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
"""fuse_gmock_files.py v0.1.0. | ||||
"""fuse_gmock_files.py v0.1.0 | ||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file. | Fuses Google Mock and Google Test source code into two .h files and a .cc file. | |||
SYNOPSIS | SYNOPSIS | |||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR | fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR | |||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source | Scans GMOCK_ROOT_DIR for Google Mock and Google Test source | |||
code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest | code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest | |||
directory, and generates three files: | directory, and generates three files: | |||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and | OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and | |||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests | OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests | |||
skipping to change at line 58 | skipping to change at line 58 | |||
GMOCK_ROOT_DIR can be omitted and defaults to the parent | GMOCK_ROOT_DIR can be omitted and defaults to the parent | |||
directory of the directory holding this script. | directory of the directory holding this script. | |||
EXAMPLES | EXAMPLES | |||
./fuse_gmock_files.py fused_gmock | ./fuse_gmock_files.py fused_gmock | |||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock | ./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock | |||
This tool is experimental. In particular, it assumes that there is no | This tool is experimental. In particular, it assumes that there is no | |||
conditional inclusion of Google Mock or Google Test headers. Please | conditional inclusion of Google Mock or Google Test headers. Please | |||
report any problems to googlemock@googlegroups.com. You can read | report any problems to googlemock@googlegroups.com. You can read | |||
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md fo | https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md | |||
r more | for more | |||
information. | information. | |||
""" | """ | |||
__author__ = 'wan@google.com (Zhanyong Wan)' | from __future__ import print_function | |||
import os | import os | |||
import re | import re | |||
import sets | ||||
import sys | import sys | |||
__author__ = 'wan@google.com (Zhanyong Wan)' | ||||
# We assume that this file is in the scripts/ directory in the Google | # We assume that this file is in the scripts/ directory in the Google | |||
# Mock root directory. | # Mock root directory. | |||
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') | DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') | |||
# We need to call into googletest/scripts/fuse_gtest_files.py. | # We need to call into googletest/scripts/fuse_gtest_files.py. | |||
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts')) | sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts')) | |||
import fuse_gtest_files | import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top | |||
gtest = fuse_gtest_files | ||||
# Regex for matching '#include "gmock/..."'. | # Regex for matching | |||
# '#include "gmock/..."'. | ||||
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"') | INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"') | |||
# Where to find the source seed files. | # Where to find the source seed files. | |||
GMOCK_H_SEED = 'include/gmock/gmock.h' | GMOCK_H_SEED = 'include/gmock/gmock.h' | |||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc' | GMOCK_ALL_CC_SEED = 'src/gmock-all.cc' | |||
# Where to put the generated files. | # Where to put the generated files. | |||
GTEST_H_OUTPUT = 'gtest/gtest.h' | GTEST_H_OUTPUT = 'gtest/gtest.h' | |||
GMOCK_H_OUTPUT = 'gmock/gmock.h' | GMOCK_H_OUTPUT = 'gmock/gmock.h' | |||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc' | GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc' | |||
def GetGTestRootDir(gmock_root): | def GetGTestRootDir(gmock_root): | |||
"""Returns the root directory of Google Test.""" | """Returns the root directory of Google Test.""" | |||
return os.path.join(gmock_root, '../googletest') | return os.path.join(gmock_root, '../googletest') | |||
def ValidateGMockRootDir(gmock_root): | def ValidateGMockRootDir(gmock_root): | |||
"""Makes sure gmock_root points to a valid gmock root directory. | """Makes sure gmock_root points to a valid gmock root directory. | |||
The function aborts the program on failure. | The function aborts the program on failure. | |||
Args: | ||||
gmock_root: A string with the mock root directory. | ||||
""" | """ | |||
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root)) | gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root)) | |||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED) | gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED) | |||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED) | gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED) | |||
def ValidateOutputDir(output_dir): | def ValidateOutputDir(output_dir): | |||
"""Makes sure output_dir points to a valid output directory. | """Makes sure output_dir points to a valid output directory. | |||
The function aborts the program on failure. | The function aborts the program on failure. | |||
Args: | ||||
output_dir: A string representing the output directory. | ||||
""" | """ | |||
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT) | gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT) | |||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT) | gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT) | |||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT) | gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT) | |||
def FuseGMockH(gmock_root, output_dir): | def FuseGMockH(gmock_root, output_dir): | |||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir.""" | """Scans folder gmock_root to generate gmock/gmock.h in output_dir.""" | |||
output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w') | output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w') | |||
processed_files = sets.Set() # Holds all gmock headers we've processed. | processed_files = set() # Holds all gmock headers we've processed. | |||
def ProcessFile(gmock_header_path): | def ProcessFile(gmock_header_path): | |||
"""Processes the given gmock header file.""" | """Processes the given gmock header file.""" | |||
# We don't process the same header twice. | # We don't process the same header twice. | |||
if gmock_header_path in processed_files: | if gmock_header_path in processed_files: | |||
return | return | |||
processed_files.add(gmock_header_path) | processed_files.add(gmock_header_path) | |||
# Reads each line in the given gmock header. | # Reads each line in the given gmock header. | |||
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'): | ||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line) | with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh: | |||
if m: | for line in fh: | |||
# It's '#include "gmock/..."' - let's process it recursively. | m = INCLUDE_GMOCK_FILE_REGEX.match(line) | |||
ProcessFile('include/' + m.group(1)) | ||||
else: | ||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) | ||||
if m: | if m: | |||
# It's '#include "gtest/foo.h"'. We translate it to | # '#include "gmock/..."' | |||
# "gtest/gtest.h", regardless of what foo is, since all | # - let's process it recursively. | |||
# gtest headers are fused into gtest/gtest.h. | ProcessFile('include/' + m.group(1)) | |||
# There is no need to #include gtest.h twice. | ||||
if not gtest.GTEST_H_SEED in processed_files: | ||||
processed_files.add(gtest.GTEST_H_SEED) | ||||
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,)) | ||||
else: | else: | |||
# Otherwise we copy the line unchanged to the output file. | m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) | |||
output_file.write(line) | if m: | |||
# '#include "gtest/foo.h"' | ||||
# We translate it to "gtest/gtest.h", regardless of what foo is, | ||||
# since all gtest headers are fused into gtest/gtest.h. | ||||
# There is no need to #include gtest.h twice. | ||||
if gtest.GTEST_H_SEED not in processed_files: | ||||
processed_files.add(gtest.GTEST_H_SEED) | ||||
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,)) | ||||
else: | ||||
# Otherwise we copy the line unchanged to the output file. | ||||
output_file.write(line) | ||||
ProcessFile(GMOCK_H_SEED) | ProcessFile(GMOCK_H_SEED) | |||
output_file.close() | output_file.close() | |||
def FuseGMockAllCcToFile(gmock_root, output_file): | def FuseGMockAllCcToFile(gmock_root, output_file): | |||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file.""" | """Scans folder gmock_root to fuse gmock-all.cc into output_file.""" | |||
processed_files = sets.Set() | processed_files = set() | |||
def ProcessFile(gmock_source_file): | def ProcessFile(gmock_source_file): | |||
"""Processes the given gmock source file.""" | """Processes the given gmock source file.""" | |||
# We don't process the same #included file twice. | # We don't process the same #included file twice. | |||
if gmock_source_file in processed_files: | if gmock_source_file in processed_files: | |||
return | return | |||
processed_files.add(gmock_source_file) | processed_files.add(gmock_source_file) | |||
# Reads each line in the given gmock source file. | # Reads each line in the given gmock source file. | |||
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'): | ||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line) | with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh: | |||
if m: | for line in fh: | |||
# It's '#include "gmock/foo.h"'. We treat it as '#include | m = INCLUDE_GMOCK_FILE_REGEX.match(line) | |||
# "gmock/gmock.h"', as all other gmock headers are being fused | ||||
# into gmock.h and cannot be #included directly. | ||||
# There is no need to #include "gmock/gmock.h" more than once. | ||||
if not GMOCK_H_SEED in processed_files: | ||||
processed_files.add(GMOCK_H_SEED) | ||||
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,)) | ||||
else: | ||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) | ||||
if m: | if m: | |||
# It's '#include "gtest/..."'. | # '#include "gmock/foo.h"' | |||
# There is no need to #include gtest.h as it has been | # We treat it as '#include "gmock/gmock.h"', as all other gmock | |||
# #included by gtest-all.cc. | # headers are being fused into gmock.h and cannot be | |||
pass | # included directly. No need to | |||
# #include "gmock/gmock.h" | ||||
# more than once. | ||||
if GMOCK_H_SEED not in processed_files: | ||||
processed_files.add(GMOCK_H_SEED) | ||||
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,)) | ||||
else: | else: | |||
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line) | m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) | |||
if m: | if m: | |||
# It's '#include "src/foo"' - let's process it recursively. | # '#include "gtest/..."' | |||
ProcessFile(m.group(1)) | # There is no need to #include gtest.h as it has been | |||
# #included by gtest-all.cc. | ||||
pass | ||||
else: | else: | |||
# Otherwise we copy the line unchanged to the output file. | m = gtest.INCLUDE_SRC_FILE_REGEX.match(line) | |||
output_file.write(line) | if m: | |||
# It's '#include "src/foo"' - let's process it recursively. | ||||
ProcessFile(m.group(1)) | ||||
else: | ||||
# Otherwise we copy the line unchanged to the output file. | ||||
output_file.write(line) | ||||
ProcessFile(GMOCK_ALL_CC_SEED) | ProcessFile(GMOCK_ALL_CC_SEED) | |||
def FuseGMockGTestAllCc(gmock_root, output_dir): | def FuseGMockGTestAllCc(gmock_root, output_dir): | |||
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir.""" | """Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir.""" | |||
output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w') | with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), | |||
# First, fuse gtest-all.cc into gmock-gtest-all.cc. | 'w') as output_file: | |||
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file) | # First, fuse gtest-all.cc into gmock-gtest-all.cc. | |||
# Next, append fused gmock-all.cc to gmock-gtest-all.cc. | gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file) | |||
FuseGMockAllCcToFile(gmock_root, output_file) | # Next, append fused gmock-all.cc to gmock-gtest-all.cc. | |||
output_file.close() | FuseGMockAllCcToFile(gmock_root, output_file) | |||
def FuseGMock(gmock_root, output_dir): | def FuseGMock(gmock_root, output_dir): | |||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h.""" | """Fuses gtest.h, gmock.h, and gmock-gtest-all.h.""" | |||
ValidateGMockRootDir(gmock_root) | ValidateGMockRootDir(gmock_root) | |||
ValidateOutputDir(output_dir) | ValidateOutputDir(output_dir) | |||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir) | gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir) | |||
FuseGMockH(gmock_root, output_dir) | FuseGMockH(gmock_root, output_dir) | |||
FuseGMockGTestAllCc(gmock_root, output_dir) | FuseGMockGTestAllCc(gmock_root, output_dir) | |||
def main(): | def main(): | |||
argc = len(sys.argv) | argc = len(sys.argv) | |||
if argc == 2: | if argc == 2: | |||
# fuse_gmock_files.py OUTPUT_DIR | # fuse_gmock_files.py OUTPUT_DIR | |||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1]) | FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1]) | |||
elif argc == 3: | elif argc == 3: | |||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR | # fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR | |||
FuseGMock(sys.argv[1], sys.argv[2]) | FuseGMock(sys.argv[1], sys.argv[2]) | |||
else: | else: | |||
print __doc__ | print(__doc__) | |||
sys.exit(1) | sys.exit(1) | |||
if __name__ == '__main__': | if __name__ == '__main__': | |||
main() | main() | |||
End of changes. 22 change blocks. | ||||
57 lines changed or deleted | 72 lines changed or added |