#! /bin/sh
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# \file admin/check-style.sh
#
# Sanity checks the coding style of all source files in the project tree.
ProgName="${0##*/}"
# Prints an error message and exits.
#
# \param ... Parts of the error message; concatenated using a space as the
# separator.
err() {
echo "${ProgName}:" "${@}" 1>&2
exit 1
}
# Locates all source files within the project directory.
#
# We require the project to have been configured in a directory that is separate
# from the source tree. This is to allow us to easily filter out build
# artifacts from our search.
#
# \param srcdir Absolute path to the source directory.
# \param builddir Absolute path to the build directory.
# \param tarname Basename of the project's tar file, to skip possible distfile
# directories.
find_sources() {
local srcdir="${1}"; shift
local builddir="${1}"; shift
local tarname="${1}"; shift
(
cd "${srcdir}"
find . -type f -a \
\! -path "*/.git/*" \
\! -path "*/.deps/*" \
\! -path "*/autom4te.cache/*" \
\! -path "*/${tarname}-[0-9]*/*" \
\! -path "*/${builddir##*/}/*" \
\! -name "Makefile.in" \
\! -name "aclocal.m4" \
\! -name "config.h.in" \
\! -name "configure" \
\! -name "testsuite"
)
}
# Prints the style rules applicable to a given file.
#
# \param file Path to the source file.
guess_rules() {
local file="${1}"; shift
case "${file}" in
*/ax_cxx_compile_stdcxx.m4) ;;
*/ltmain.sh) ;;
*Makefile*) echo common make ;;
*.[0-9]) echo common man ;;
*.cpp|*.hpp) echo common cpp ;;
*.sh) echo common shell ;;
*) echo common ;;
esac
}
# Validates a given file against the rules that apply to it.
#
# \param srcdir Absolute path to the source directory.
# \param file Name of the file to validate relative to srcdir.
#
# \return 0 if the file is valid; 1 otherwise, in which case the style
# violations are printed to the output.
check_file() {
local srcdir="${1}"; shift
local file="${1}"; shift
local err=0
for rule in $(guess_rules "${file}"); do
awk -f "${srcdir}/admin/check-style-${rule}.awk" \
"${srcdir}/${file}" || err=1
done
return ${err}
}
# Entry point.
main() {
local builddir=.
local srcdir=.
local tarname=UNKNOWN
local arg
while getopts :b:s:t: arg; do
case "${arg}" in
b)
builddir="${OPTARG}"
;;
s)
srcdir="${OPTARG}"
;;
t)
tarname="${OPTARG}"
;;
\?)
err "Unknown option -${OPTARG}"
;;
esac
done
shift $(expr ${OPTIND} - 1)
srcdir="$(cd "${srcdir}" && pwd -P)"
builddir="$(cd "${builddir}" && pwd -P)"
[ "${srcdir}" != "${builddir}" ] || \
err "srcdir and builddir cannot match; reconfigure the package" \
"in a separate directory"
local sources
if [ ${#} -gt 0 ]; then
sources="${@}"
else
sources="$(find_sources "${srcdir}" "${builddir}" "${tarname}")"
fi
local ok=0
for file in ${sources}; do
local file="$(echo ${file} | sed -e "s,\\./,,")"
check_file "${srcdir}" "${file}" || ok=1
done
return "${ok}"
}
main "${@}"