aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/check-headers-self-sufficient
diff options
context:
space:
mode:
Diffstat (limited to 'tools/check-headers-self-sufficient')
-rwxr-xr-xtools/check-headers-self-sufficient247
1 files changed, 148 insertions, 99 deletions
diff --git a/tools/check-headers-self-sufficient b/tools/check-headers-self-sufficient
index 8e5ced47dd..0513aeff47 100755
--- a/tools/check-headers-self-sufficient
+++ b/tools/check-headers-self-sufficient
@@ -1,107 +1,156 @@
-#!/bin/sh
+#!/usr/bin/env python
# Copyright 2017 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-cd "$(dirname "$0")/.."
+import fnmatch
+import multiprocessing
+import os
+import subprocess
+import sys
-compile_header() {
- # test each header for self-sufficiency and idempotency.
- printf '#include "%s"\n#include "%s"\n' "$1" "$1" | \
- c++ --std=c++11 \
- -Iinclude/core \
- -Iinclude/config \
- -Iinclude/android \
- -Iinclude/c \
- -Iinclude/codec \
- -Iinclude/effects \
- -Iinclude/gpu \
- -Iinclude/gpu/gl \
- -Iinclude/pathops \
- -Iinclude/ports \
- -Iinclude/private \
- -Iinclude/svg \
- -Iinclude/utils \
- -Iinclude/utils/mac \
- -Iinclude/views \
- -Iinclude/xml \
- -Isrc/codec \
- -Isrc/core \
- -Isrc/effects \
- -Isrc/effects/gradients \
- -Isrc/fonts \
- -Isrc/gpu \
- -Isrc/image \
- -Isrc/images \
- -Isrc/lazy \
- -Isrc/opts \
- -Isrc/pathops \
- -Isrc/ports \
- -Isrc/sfnt \
- -Isrc/sksl \
- -Isrc/utils \
- -Isrc/utils/win \
- -Igm \
- -Itests \
- -Itools \
- -Itools/debugger \
- -Itools/flags \
- -Itools/gpu \
- -Itools/timer \
- -Ithird_party/etc1 \
- -Ithird_party/externals/jsoncpp/include \
- -Ithird_party/externals/sfntly/cpp/src \
- -Ithird_party/externals/zlib \
- -Ithird_party/gif \
- -o /dev/null -c -x c++ -
-}
-FAIL=0
-for header in $(git ls-files | grep '\.h$'); do
- # The following headers don't pass this test for one reason or another.
- case $header in
- */osmesa_wrapper.h) continue;;
- debugger/QT/*) continue;;
- example/*) continue;;
- experimental/*) continue;;
- include/config/*) continue;;
- include/core/SkPostConfig.h) continue;;
- include/gpu/vk/*) continue;;
- include/ports/SkFontMgr_android.h) continue;;
- include/ports/SkFontMgr_fontconfig.h) continue;;
- include/ports/SkTypeface_win.h) continue;;
- include/private/*_impl.h) continue;;
- include/utils/mac/SkCGUtils.h) continue;;
- include/views/SkOSWindow_*.h) continue;;
- src/c/sk_c_from_to.h) continue;;
- src/codec/SkJpegDecoderMgr.h) continue;;
- src/codec/SkJpegUtility.h) continue;;
- src/core/*Template.h) continue;;
- src/core/SkBitmapProcState_*.h) continue;;
- src/core/SkFDot6Constants.h) continue;;
- src/core/SkLinearBitmapPipeline.h) continue;;
- src/core/SkLinearBitmapPipeline_*.h) continue;;
- src/core/SkUnPreMultiplyPriv.h) continue;;
- src/gpu/vk/*.h) continue;;
- src/images/SkJPEGWriteUtility.h) continue;;
- src/opts/*_SSE2.h) continue;;
- src/opts/*_SSSE3.h) continue;;
- src/opts/*_neon.h) continue;;
- src/opts/*_sse.h) continue;;
- src/opts/Sk4px_*.h) continue;;
- src/ports/*) continue;;
- src/utils/*_win.h) continue;;
- src/utils/win/*) continue;;
- src/views/*) continue;;
- third_party/*) continue;;
- tools/fiddle/*) continue;;
- tools/viewer/*) continue;;
- esac
- if ! compile_header "$header"; then
- echo "FAILURE: $header"
- FAIL=1
- fi
-done
-exit $FAIL
+public_header_args = [
+ '-Iinclude/core',
+ '-Iinclude/config',
+ '-Iinclude/android',
+ '-Iinclude/codec',
+ '-Iinclude/effects',
+ '-Iinclude/gpu',
+ '-Iinclude/gpu/gl',
+ '-Iinclude/pathops',
+ '-Iinclude/ports',
+ '-Iinclude/private',
+ '-Iinclude/svg',
+ '-Iinclude/utils',
+ '-Iinclude/utils/mac',
+ '-Iinclude/views',
+]
+
+all_header_args = [
+ '-Iinclude/core',
+ '-Iinclude/config',
+ '-Iinclude/android',
+ '-Iinclude/c',
+ '-Iinclude/codec',
+ '-Iinclude/effects',
+ '-Iinclude/gpu',
+ '-Iinclude/gpu/gl',
+ '-Iinclude/pathops',
+ '-Iinclude/ports',
+ '-Iinclude/private',
+ '-Iinclude/svg',
+ '-Iinclude/utils',
+ '-Iinclude/utils/mac',
+ '-Iinclude/views',
+ '-Isrc/codec',
+ '-Isrc/core',
+ '-Isrc/effects',
+ '-Isrc/effects/gradients',
+ '-Isrc/fonts',
+ '-Isrc/gpu',
+ '-Isrc/image',
+ '-Isrc/images',
+ '-Isrc/lazy',
+ '-Isrc/opts',
+ '-Isrc/pathops',
+ '-Isrc/ports',
+ '-Isrc/sfnt',
+ '-Isrc/sksl',
+ '-Isrc/utils',
+ '-Isrc/utils/win',
+ '-Isrc/xml',
+ '-Igm',
+ '-Itests',
+ '-Itools',
+ '-Itools/debugger',
+ '-Itools/flags',
+ '-Itools/gpu',
+ '-Itools/timer',
+ '-Ithird_party/etc1',
+ '-Ithird_party/externals/jsoncpp/include',
+ '-Ithird_party/externals/libjpeg-turbo',
+ '-Ithird_party/externals/sfntly/cpp/src',
+ '-Ithird_party/externals/zlib',
+ '-Ithird_party/gif',
+]
+
+ignore = [
+ '*/lex.*.h',
+ '*/osmesa_wrapper.h',
+ 'debugger/QT/*',
+ 'example/*',
+ 'experimental/*',
+ 'include/config/*',
+ 'include/core/SkPostConfig.h',
+ 'include/gpu/vk/*',
+ 'include/ports/SkFontMgr_android.h',
+ 'include/ports/SkFontMgr_fontconfig.h',
+ 'include/ports/SkTypeface_win.h',
+ 'include/private/*_impl.h',
+ 'include/utils/mac/SkCGUtils.h',
+ 'include/views/SkOSWindow_*.h',
+ 'src/c/sk_c_from_to.h',
+ 'src/core/*Template.h',
+ 'src/core/SkBitmapProcState_*.h',
+ 'src/core/SkFDot6Constants.h',
+ 'src/core/SkLinearBitmapPipeline.h',
+ 'src/core/SkLinearBitmapPipeline_*.h',
+ 'src/core/SkUnPreMultiplyPriv.h',
+ 'src/gpu/vk/*.h',
+ 'src/opts/*_SSE2.h',
+ 'src/opts/*_SSSE3.h',
+ 'src/opts/*_neon.h',
+ 'src/opts/*_sse.h',
+ 'src/opts/Sk4px_*.h',
+ 'src/ports/*',
+ 'src/utils/*_win.h',
+ 'src/utils/win/*',
+ 'src/views/*',
+ 'third_party/*',
+ 'tools/fiddle/*',
+ 'tools/viewer/*',
+]
+
+# test header for self-sufficiency and idempotency.
+# Returns a string containing errors, or None iff there are no errors.
+def compile_header(header):
+ args = ([] if fnmatch.fnmatch(header, 'include/c/*') else
+ public_header_args if fnmatch.fnmatch(header, 'include/*') else
+ all_header_args)
+ cmd = ['c++', '--std=c++11'] + args + [ '-o', '/dev/null', '-c', '-x', 'c++', '-']
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc.stdin.write('#include "%s"\n#include "%s"\n' % (header, header))
+ proc.stdin.close()
+ errors = proc.stdout.read().strip()
+ if proc.wait() != 0 or len(errors) > 0:
+ return '\n\033[7m ERROR: %s \033[0m\n%s\n\n' % (header, errors)
+ return None
+
+def main():
+ class N: good = True
+ # N.good is a global scoped to main() to make a print_and_exit_if() a closure
+ pool = multiprocessing.Pool()
+ def print_and_exit_if(r):
+ if r is not None:
+ sys.stdout.write(r)
+ N.good = False
+ pool.terminate()
+
+ os.chdir(os.path.join(os.path.dirname(__file__), os.pardir))
+ for path in subprocess.check_output(['git', 'ls-files']).splitlines():
+ if path.endswith('.h') and not any(fnmatch.fnmatch(path, pattern) for pattern in ignore):
+ pool.apply_async(compile_header, args=(path, ), callback=print_and_exit_if)
+ pool.close()
+ pool.join()
+ if N.good:
+ sys.stdout.write('all good :)\n')
+ else:
+ exit(1)
+
+if __name__ == '__main__':
+ main()
+