1#! /bin/sh 2# Copyright 2011 The Kyua Authors. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# * Neither the name of Google Inc. nor the names of its contributors 15# may be used to endorse or promote products derived from this software 16# without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30# \file admin/check-style.sh 31# 32# Sanity checks the coding style of all source files in the project tree. 33 34ProgName="${0##*/}" 35 36 37# Prints an error message and exits. 38# 39# \param ... Parts of the error message; concatenated using a space as the 40# separator. 41err() { 42 echo "${ProgName}:" "${@}" 1>&2 43 exit 1 44} 45 46 47# Locates all source files within the project directory. 48# 49# We require the project to have been configured in a directory that is separate 50# from the source tree. This is to allow us to easily filter out build 51# artifacts from our search. 52# 53# \param srcdir Absolute path to the source directory. 54# \param builddir Absolute path to the build directory. 55# \param tarname Basename of the project's tar file, to skip possible distfile 56# directories. 57find_sources() { 58 local srcdir="${1}"; shift 59 local builddir="${1}"; shift 60 local tarname="${1}"; shift 61 62 ( 63 cd "${srcdir}" 64 find . -type f -a \ 65 \! -path "*/.git/*" \ 66 \! -path "*/.deps/*" \ 67 \! -path "*/autom4te.cache/*" \ 68 \! -path "*/${tarname}-[0-9]*/*" \ 69 \! -path "*/${builddir##*/}/*" \ 70 \! -name "Makefile.in" \ 71 \! -name "aclocal.m4" \ 72 \! -name "config.h.in" \ 73 \! -name "configure" \ 74 \! -name "testsuite" 75 ) 76} 77 78 79# Prints the style rules applicable to a given file. 80# 81# \param file Path to the source file. 82guess_rules() { 83 local file="${1}"; shift 84 85 case "${file}" in 86 */ax_cxx_compile_stdcxx.m4) ;; 87 */ltmain.sh) ;; 88 *Makefile*) echo common make ;; 89 *.[0-9]) echo common man ;; 90 *.cpp|*.hpp) echo common cpp ;; 91 *.sh) echo common shell ;; 92 *) echo common ;; 93 esac 94} 95 96 97# Validates a given file against the rules that apply to it. 98# 99# \param srcdir Absolute path to the source directory. 100# \param file Name of the file to validate relative to srcdir. 101# 102# \return 0 if the file is valid; 1 otherwise, in which case the style 103# violations are printed to the output. 104check_file() { 105 local srcdir="${1}"; shift 106 local file="${1}"; shift 107 108 local err=0 109 for rule in $(guess_rules "${file}"); do 110 awk -f "${srcdir}/admin/check-style-${rule}.awk" \ 111 "${srcdir}/${file}" || err=1 112 done 113 114 return ${err} 115} 116 117 118# Entry point. 119main() { 120 local builddir=. 121 local srcdir=. 122 local tarname=UNKNOWN 123 124 local arg 125 while getopts :b:s:t: arg; do 126 case "${arg}" in 127 b) 128 builddir="${OPTARG}" 129 ;; 130 131 s) 132 srcdir="${OPTARG}" 133 ;; 134 135 t) 136 tarname="${OPTARG}" 137 ;; 138 139 \?) 140 err "Unknown option -${OPTARG}" 141 ;; 142 esac 143 done 144 shift $(expr ${OPTIND} - 1) 145 146 srcdir="$(cd "${srcdir}" && pwd -P)" 147 builddir="$(cd "${builddir}" && pwd -P)" 148 [ "${srcdir}" != "${builddir}" ] || \ 149 err "srcdir and builddir cannot match; reconfigure the package" \ 150 "in a separate directory" 151 152 local sources 153 if [ ${#} -gt 0 ]; then 154 sources="${@}" 155 else 156 sources="$(find_sources "${srcdir}" "${builddir}" "${tarname}")" 157 fi 158 159 local ok=0 160 for file in ${sources}; do 161 local file="$(echo ${file} | sed -e "s,\\./,,")" 162 163 check_file "${srcdir}" "${file}" || ok=1 164 done 165 166 return "${ok}" 167} 168 169 170main "${@}" 171