1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#!/usr/bin/env python
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Copyright (C) 2009 Google Inc. All rights reserved.
4d0825bca7fe65beaee391d30da42e937db621564Steve Block# Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com)
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Redistribution and use in source and binary forms, with or without
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# modification, are permitted provided that the following conditions are
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# met:
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    * Redistributions of source code must retain the above copyright
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# notice, this list of conditions and the following disclaimer.
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    * Redistributions in binary form must reproduce the above
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# copyright notice, this list of conditions and the following disclaimer
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# in the documentation and/or other materials provided with the
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# distribution.
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    * Neither the name of Google Inc. nor the names of its
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# contributors may be used to endorse or promote products derived from
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# this software without specific prior written permission.
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
32d0825bca7fe65beaee391d30da42e937db621564Steve Block"""Does WebKit-lint on C/C++ or text files.
33d0825bca7fe65beaee391d30da42e937db621564Steve Block
34d0825bca7fe65beaee391d30da42e937db621564Steve BlockThe goal of this script is to identify places in the code that *may*
35d0825bca7fe65beaee391d30da42e937db621564Steve Blockbe in non-compliance with WebKit style.  It does not attempt to fix
36d0825bca7fe65beaee391d30da42e937db621564Steve Blockup these problems -- the point is to educate.  It does also not
37d0825bca7fe65beaee391d30da42e937db621564Steve Blockattempt to find all problems, or to ensure that everything it does
38d0825bca7fe65beaee391d30da42e937db621564Steve Blockfind is legitimately a problem.
39d0825bca7fe65beaee391d30da42e937db621564Steve Block
40d0825bca7fe65beaee391d30da42e937db621564Steve BlockIn particular, we can get very confused by /* and // inside strings!
41d0825bca7fe65beaee391d30da42e937db621564Steve BlockWe do a small hack, which is to ignore //'s with "'s after them on the
42d0825bca7fe65beaee391d30da42e937db621564Steve Blocksame line, but it is far from perfect (in either direction).
43d0825bca7fe65beaee391d30da42e937db621564Steve Block"""
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport codecs
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport os
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport os.path
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport sys
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
50d0825bca7fe65beaee391d30da42e937db621564Steve Blockimport webkitpy.style.checker as checker
51d0825bca7fe65beaee391d30da42e937db621564Steve Blockfrom webkitpy.style_references import SimpleScm
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef main():
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    # Change stderr to write with replacement characters so we don't die
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    # if we try to print something containing non-ASCII characters.
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    sys.stderr = codecs.StreamReaderWriter(sys.stderr,
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                           codecs.getreader('utf8'),
580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                           codecs.getwriter('utf8'),
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                           'replace')
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
61d0825bca7fe65beaee391d30da42e937db621564Steve Block    defaults = checker.webkit_argument_defaults()
62d0825bca7fe65beaee391d30da42e937db621564Steve Block
63d0825bca7fe65beaee391d30da42e937db621564Steve Block    parser = checker.ArgumentParser(defaults)
64d0825bca7fe65beaee391d30da42e937db621564Steve Block    (files, options) = parser.parse(sys.argv[1:])
65d0825bca7fe65beaee391d30da42e937db621564Steve Block
66d0825bca7fe65beaee391d30da42e937db621564Steve Block    style_checker = checker.StyleChecker(options)
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if files:
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for filename in files:
70d0825bca7fe65beaee391d30da42e937db621564Steve Block            style_checker.check_file(filename)
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else:
73d0825bca7fe65beaee391d30da42e937db621564Steve Block        scm = SimpleScm()
74d0825bca7fe65beaee391d30da42e937db621564Steve Block
75d0825bca7fe65beaee391d30da42e937db621564Steve Block        os.chdir(scm.checkout_root())
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
77d0825bca7fe65beaee391d30da42e937db621564Steve Block        if options.git_commit:
78d0825bca7fe65beaee391d30da42e937db621564Steve Block            commit = options.git_commit
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if '..' in commit:
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                # FIXME: If the range is a "...", the code should find the common ancestor and
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                # start there (see git diff --help for information about how ... usually works).
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                commit = commit[:commit.find('..')]
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                print >> sys.stderr, "Warning: Ranges are not supported for --git-commit. Checking all changes since %s.\n" % commit
84d0825bca7fe65beaee391d30da42e937db621564Steve Block            patch = scm.create_patch_since_local_commit(commit)
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else:
86d0825bca7fe65beaee391d30da42e937db621564Steve Block            patch = scm.create_patch()
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        style_checker.check_patch(patch)
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
89d0825bca7fe65beaee391d30da42e937db621564Steve Block    error_count = style_checker.error_count
90d0825bca7fe65beaee391d30da42e937db621564Steve Block    sys.stderr.write('Total errors found: %d\n' % error_count)
91d0825bca7fe65beaee391d30da42e937db621564Steve Block    sys.exit(error_count > 0)
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochif __name__ == "__main__":
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    main()
96