xref: /aosp_15_r20/external/coreboot/util/lint/lint-extended-015-final-newlines (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1#!/usr/bin/env sh
2#
3# SPDX-License-Identifier: GPL-2.0-only
4
5# DESCR: Check that files end with a single newline
6
7LINTDIR="$(
8  cd -- "$(dirname "$0")" > /dev/null 2>&1 || return
9  pwd -P
10)"
11
12# shellcheck source=helper_functions.sh
13. "${LINTDIR}/helper_functions.sh"
14
15PIDS=""
16INCLUDED_DIRS_AND_FILES='util/* src/* payloads/* configs/* Makefile *.inc'
17EXCLUDED_DIRS='src/vendorcode/\|cbfstool/lzma/\|cbfstool/lz4/\|Documentation/\|build/\|3rdparty/\|\.git/\|coreboot-builds/\|util/nvidia/cbootimage/\|^util/goswid/vendor'
18EXCLUDED_FILES='\.gif$\|\.jpg$\|\.cksum$\|\.bin$\|\.vbt$\|\.hex$\|\.ico$\|\.o$\|\.bz2$\|\.xz$\|^.tmpconfig\|\.pyc$\|_shipped$\|sha256$\|\.png$\|\.patch$\|\.apcb$'
19
20HAVE_FILE=$(command -v file 1>/dev/null 2>&1; echo $?)
21
22is_eligible_executable() {
23	if [ "$HAVE_FILE" -ne 0 ]; then
24		return 1
25	fi
26	if { LC_ALL=C; file --brief "$filename" | grep -Eqw \
27		"^(Bourne shell|POSIX shell|Perl|Python) script"; };
28	then
29		return 0
30	else
31		return 1
32	fi
33}
34
35test_for_final_newline() {
36	while read filename; do
37		# Only check regular files and script executables
38		if [ -f "$filename" ] && { [ ! -x "$filename" ] || \
39			is_eligible_executable "$filename"; };
40		then
41			# Verify that there is a newline at the end
42			# $() strips trailing newlines
43			if [ -n "$(tail -c 1 "$filename")" ]; then
44				echo "$filename has no final newline."
45
46			# Verify that the file ends with only a single newline
47			# and that the file isn't empty
48			elif [ -z "$(tail -c 2 "$filename")" ] && \
49			     [ -n "$(head -n 5 "$filename")" ]; then
50				echo "$filename has multiple final newlines."
51			fi
52		fi
53	done
54}
55
56for directory in $INCLUDED_DIRS_AND_FILES ; do
57	${FIND_FILES} "${directory}" | sed 's|^\./||' | sort | \
58		grep -v "$EXCLUDED_DIRS" | \
59		grep -v "$EXCLUDED_FILES" | \
60		test_for_final_newline &
61	PIDS="$PIDS $!"
62done
63
64# wait for tests to finish.
65for pid in $PIDS; do
66	wait "$pid"
67done
68