1# Copyright 2020 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# Simple libcore patch-style checking based on http://go/libcore-patch-style. 16# 17# See sample-input.java for examples of matches and failures. 18# 19# Usage: 20# awk -f libcore-patch-style.awk <file0> [... fileN] 21# 22# This script ignores any files whose name does not end in the suffix ".java". 23# 24# To scan all source code in the libcore tree: 25# $ cd libcore 26# $ find . -type f | xargs awk -f tools/patch-style/libcore-patch-style.awk 27# 28# To find sources with the most issues: 29# $ cd libcore 30# $ find . -type f | xargs awk -f tools/patch-style/libcore-patch-style.awk \ 31# | grep -F ./ | sed -e 's/:.*//' | uniq -c | sort -n -r | head 32 33BEGIN { 34 g_errors = 0 # Number of errors accumulated. 35 g_expected_end = "" # Expected END line. 36 g_max_length = 100 # Maximum line length for markers (0 == no checking). 37 g_stop_oneline_interleaving = 0 # Error one-line comments between BEGIN and END markers. 38} 39 40BEGINFILE { 41 # Skip files whose names do not have a .java suffix. 42 if (FILENAME !~ /\.java$/) { 43 nextfile 44 } 45 46 # Reset the line number for reporting errors back to zero. 47 NR = 0 48 49 # Clear expected end marker as processing a new file. 50 g_expected_end = "" 51} 52 53function error(message) { 54 print(FILENAME ":" NR ":", message "\n") 55 g_errors += 1; 56} 57 58function expectationError(reason, expected, actual) { 59 error(reason "\n Expected: \"" expected "\"\n Actual: \"" actual "\"") 60} 61 62function inputError(reason, actual) { 63 error(reason "\n Input: \"" actual "\"") 64} 65 66function checkLineLength(line) { 67 if (g_max_length > 0 && length(line) > g_max_length) { 68 inputError("Line too long", line) 69 } 70} 71 72function leftTrim(message) { 73 return gensub(/^ */, "", 1, message) 74} 75 76function failIfEndExpected() { 77 if (g_expected_end != "") { 78 expectationError("Missing END marker.", g_expected_end, $0) 79 g_expected_end = "" 80 } 81} 82 83function expectEndFor(begin_line) { 84 g_expected_end = begin_line 85 sub("BEGIN", "END", g_expected_end) 86} 87 88function actualEndFor(actual_line) { 89 if (actual_line != g_expected_end) { 90 expectationError("Bad END marker.", g_expected_end, actual_line) 91 } 92 g_expected_end = "" 93} 94 95function processBeginMarker(line) { 96 failIfEndExpected() 97 expectEndFor(line) 98} 99 100function processEndMarker(line) { 101 actualEndFor(line) 102} 103 104# BEGIN marker ending in a period. 105/^ *\/\/ BEGIN Android-(added|changed|note|removed):.*\./ { 106 checkLineLength($0) 107 processBeginMarker($0) 108 next 109} 110 111# BEGIN marker ending in a period. 112/^ *\/\/ END Android-(added|changed|note|removed):.*\./ { 113 checkLineLength($0) 114 processEndMarker($0) 115 next 116} 117 118# BEGIN marker ending in a bug reference. 119/^ *\/\/ BEGIN Android-(added|changed|note|removed):.*[.](http:\/\/)?b\/[1-9][0-9]*/ { 120 checkLineLength($0) 121 processBeginMarker($0) 122 next 123} 124 125# BEGIN marker ending in anything else, oops! 126/^ *\/\/ BEGIN Android-(added|changed|note|removed)[^:].*/ { 127 inputError("BEGIN marker is missing colon or description.", $0) 128 next 129} 130 131# END marker, should be paired with last BEGIN marker. 132/^ *\/\/ END Android-(added|changed|note|removed):.*/ { 133 checkLineLength($0) 134 processEndMarker($0) 135 next 136} 137 138# One line change marker ending in a period. 139/^ *\/\/ Android-(added|changed|note|removed):.*[.]/ { 140 checkLineLength($0) 141 if (g_stop_oneline_interleaving) { 142 failIfEndExpected() 143 } 144 next 145} 146 147# One line change marker ending in a bug reference. 148/^ *\/\/ Android-(added|changed|note|removed):[.](http:\/\/)?b\/[1-9][0-9]*/ { 149 checkLineLength($0) 150 if (g_stop_oneline_interleaving) { 151 failIfEndExpected() 152 } 153 next 154} 155 156# One line change marker missing comment after colon. 157/^ *\/\/ BEGIN Android-(added|changed|note|removed).*/ { 158 inputError("Bad change marker: missing colon or description.", $0) 159 next 160} 161 162# Something that looks like a potential change marker. 163/^ *(\/\*|\/\/|\*) *(Android|ANDROID)-/ { 164 if (g_stop_oneline_interleaving) { 165 failIfEndExpected() 166 } 167 inputError("Bad change marker.", $0) 168 next 169} 170 171END { 172 failIfEndExpected() 173 printf("Found " g_errors " libcore patch style issues.\n") 174 exit g_errors == 0 175} 176