| #!/usr/bin/env python3 |
| # Copyright 2014 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Create files with copyright boilerplate and header include guards. |
| |
| Usage: tools/boilerplate.py path/to/file.{h,cc} |
| """ |
| |
| from __future__import print_function, unicode_literals |
| |
| from datetimeimport date |
| import io |
| import os |
| import os.path |
| import sys |
| |
| LINES=[ |
| f'Copyright {date.today().year} The Chromium Authors', |
| 'Use of this source code is governed by a BSD-style license that can be', |
| 'found in the LICENSE file.' |
| ] |
| |
| NO_COMPILE_LINES=[ |
| 'This is a "No Compile Test" suite.', |
| 'https://dev.chromium.org/developers/testing/no-compile-tests' |
| ] |
| |
| EXTENSIONS_TO_COMMENTS={ |
| 'cc':'//', |
| 'gn':'#', |
| 'gni':'#', |
| 'h':'//', |
| 'js':'//', |
| 'mm':'//', |
| 'mojom':'//', |
| 'nc':'//', |
| 'proto':'//', |
| 'py':'#', |
| 'swift':'//', |
| 'ts':'//', |
| 'typemap':'#', |
| } |
| |
| |
| def_GetHeaderImpl(filename, lines): |
| _, ext= os.path.splitext(filename) |
| ext= ext[1:] |
| comment= EXTENSIONS_TO_COMMENTS[ext]+' ' |
| return'\n'.join([comment+ linefor linein lines]) |
| |
| |
| def_GetHeader(filename): |
| return_GetHeaderImpl(filename, LINES) |
| |
| |
| def_GetNoCompileHeader(filename): |
| assert(filename.endswith(".nc")) |
| return'\n'+_GetHeaderImpl(filename, NO_COMPILE_LINES) |
| |
| |
| def_CppHeader(filename): |
| guard= filename.upper()+'_' |
| for charin'/\\.+': |
| guard= guard.replace(char,'_') |
| return'\n'.join([ |
| '', |
| '#ifndef '+ guard, |
| '#define '+ guard, |
| '', |
| '#endif // '+ guard, |
| '' |
| ]) |
| |
| |
| def_RemoveCurrentDirectoryPrefix(filename): |
| current_dir_prefixes=[os.curdir+ os.sep] |
| if os.altsepisnotNone: |
| current_dir_prefixes.append(os.curdir+ os.altsep) |
| for prefixin current_dir_prefixes: |
| if filename.startswith(prefix): |
| return filename[len(prefix):] |
| return filename |
| |
| |
| def_RemoveTestSuffix(filename): |
| base, _= os.path.splitext(filename) |
| suffixes=['_test','_unittest','_browsertest'] |
| for suffixin suffixes: |
| l= len(suffix) |
| if base[-l:]== suffix: |
| return base[:-l] |
| return base |
| |
| |
| def_IsIOSFile(filename): |
| if os.path.splitext(os.path.basename(filename))[0].endswith('_ios'): |
| returnTrue |
| if'ios'in filename.split(os.path.sep): |
| returnTrue |
| returnFalse |
| |
| |
| def_FilePathSlashesToCpp(filename): |
| return filename.replace('\\','/') |
| |
| |
| def_CppImplementation(filename): |
| return'\n#include "'+_FilePathSlashesToCpp(_RemoveTestSuffix(filename)) \ |
| +'.h"\n' |
| |
| |
| def_ObjCppImplementation(filename): |
| return'\n#import "'+_FilePathSlashesToCpp(_RemoveTestSuffix(filename)) \ |
| +'.h"\n' |
| |
| |
| def_CreateFile(filename): |
| filename=_RemoveCurrentDirectoryPrefix(filename) |
| |
| contents=_GetHeader(filename)+'\n' |
| |
| if filename.endswith('.h'): |
| contents+=_CppHeader(filename) |
| elif filename.endswith('.cc'): |
| contents+=_CppImplementation(filename) |
| elif filename.endswith('.nc'): |
| contents+=_GetNoCompileHeader(filename)+'\n' |
| contents+=_CppImplementation(filename) |
| elif filename.endswith('.mm'): |
| contents+=_ObjCppImplementation(filename) |
| |
| with io.open(filename, mode='w', newline='\n')as fd: |
| fd.write(contents) |
| |
| |
| # A file is safe to overwrite if it's an empty file we can write to. |
| def_IsSafeToOverwrite(path): |
| return os.path.isfile(path)and os.path.getsize(path)==0and os.access( |
| path, os.W_OK) |
| |
| |
| defMain(): |
| files= sys.argv[1:] |
| if len(files)<1: |
| print( |
| 'Usage: boilerplate.py path/to/file.h path/to/file.cc', file=sys.stderr) |
| return1 |
| |
| # Perform checks first so that the entire operation is atomic. |
| for fin files: |
| _, ext= os.path.splitext(f) |
| ifnot ext[1:]in EXTENSIONS_TO_COMMENTS: |
| print('Unknown file type for %s'% f, file=sys.stderr) |
| return2 |
| |
| if os.path.exists(f)andnot_IsSafeToOverwrite(f): |
| print('A file at path %s already exists'% f, file=sys.stderr) |
| return2 |
| |
| for fin files: |
| _CreateFile(f) |
| |
| |
| if __name__=='__main__': |
| sys.exit(Main()) |