165 lines
5.3 KiB
Bash
Executable file
165 lines
5.3 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
|
|
TXRED="$(tput setaf 1 bold)"
|
|
TXGREEN="$(tput setaf 2 bold)"
|
|
TXYELLOW="$(tput setaf 3 bold)"
|
|
TXBLUE="$(tput setaf 4 bold)"
|
|
TXMAGENTA="$(tput setaf 5 bold)"
|
|
TXCYAN="$(tput setaf 6 bold)"
|
|
TXRESET="$(tput sgr0)"
|
|
TXCLR="$(tput el)"
|
|
|
|
log() {
|
|
local filename="$1" lc=$2 level="$3" msg="$4" data="$5"
|
|
local txcolour flc colw
|
|
|
|
[ "${level}" = "FAIL" ] && txcolour="${TXRED}" || txcolour="${TXYELLOW}"
|
|
[[ ${filename} =~ ^\./ ]] && filename="${filename:2}"
|
|
[ ${lc} -eq 0 ] && flc="---" || flc="$(printf "%03d" ${lc})"
|
|
[[ ${filename} =~ packages/addons/addon-depends ]] && colw=80 || colw=50
|
|
|
|
printf "[%s] %3s: %-*s: %-25s: %s\n" "${txcolour}${level}${TXRESET}" "${flc}" ${colw} "${filename}" "${msg}" "${data}"
|
|
}
|
|
|
|
process_line() {
|
|
local filename="$1" lc="$2" line="$3" inassign="$4" funcname="$5"
|
|
local var matches assignallowed=Y
|
|
|
|
if [ -n "${funcname}" -a "${funcname}" != "configure_package" -a "${inassign}" = "Y" ]; then
|
|
if [[ ${line} =~ PKG_DEPENDS_.*= ]]; then
|
|
log "${filename}" ${lc} "WARN" "ignored depends assign" "${funcname}() => ${line//[[:space:]]*PKG_DEPENDS_/PKG_DEPENDS_}"
|
|
fi
|
|
fi
|
|
|
|
[ -n "${funcname}" ] && return 0
|
|
|
|
rightside="${line#*=}"
|
|
|
|
for var in PKG_SHORTDESC PKG_LONGDESC PKG_IS_ADDON PKG_NEED_UNPACK PKG_SOURCE_NAME PKG_ADDON_IS_STANDALONE \
|
|
PKG_CONFIGURE_SCRIPT PKG_CMAKE_SCRIPT PKG_MESON_SCRIPT \
|
|
PKG_DIR PKG_ADDON_ID PKG_BUILD \
|
|
DESTIMAGE CC CXX CPP LD AS AR NM \
|
|
RANLIB OBJCOPY OBJDUMP STRIP \
|
|
CPPFLAGS CFLAGS CXXFLAGS LDFLAGS \
|
|
PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR PKG_CONFIG_ALLOW_SYSTEM_CFLAGS PKG_CONFIG_ALLOW_SYSTEM_LIBS \
|
|
CMAKE_CONF CMAKE \
|
|
HOST_CC HOST_CXX HOSTCC HOSTCXX \
|
|
CC_FOR_BUILD CXX_FOR_BUILD BUILD_CC BUILD_CXX \
|
|
_python_sysroot _python_prefix _python_exec_prefix \
|
|
TARGET_CONFIGURE_OPTS CMAKE_GENERATOR_NINJA TARGET_CMAKE_OPTS TARGET_MESON_OPTS \
|
|
HOST_CONFIGURE_OPTS HOST_CMAKE_OPTS HOST_MESON_OPTS \
|
|
INIT_CONFIGURE_OPTS INIT_CMAKE_OPTS INIT_MESON_OPTS \
|
|
BOOTSTRAP_CONFIGURE_OPTS BOOTSTRAP_CMAKE_OPTS BOOTSTRAP_MESON_OPTS \
|
|
; do
|
|
|
|
# After PKG_DIR, treat assigns to var as invalid
|
|
[ "${var}" = "PKG_DIR" ] && assignallowed=N
|
|
|
|
if [ "${assignallowed}" = "N" ]; then
|
|
if [[ ${line} =~ (^|[[:space:]])${var}= ]]; then
|
|
[ "${inassign}" = "N" ] && matches+=", assign to ${var}"
|
|
fi
|
|
fi
|
|
|
|
if [[ ${line} =~ \$\{${var}} ]] || [[ ${line} =~ \$${var}[^A-Za-z0-9_] ]]; then
|
|
matches+=", ref ${var}"
|
|
fi
|
|
|
|
if [[ ${line} =~ (^|[[:space:]])unset\ ${var}($|[[:space:]]) ]]; then
|
|
matches+=", unset ${var}"
|
|
fi
|
|
done
|
|
|
|
[ -n "${matches}" ] && log "${filename}" ${lc} "FAIL" "late binding violation" "${matches:2}"
|
|
}
|
|
|
|
init_target_funcs() {
|
|
local f t funcs
|
|
|
|
for t in target host init bootstrap; do
|
|
for f in pre_build \
|
|
pre_configure configure post_configure \
|
|
pre_make make post_make \
|
|
pre_makeinstall makeinstall post_makeinstall \
|
|
; do
|
|
funcs+=" ${f}_${t}"
|
|
done
|
|
done
|
|
echo "${funcs:1}"
|
|
}
|
|
|
|
check_func_name() {
|
|
local filename="$1" lc="$2" line="$3"
|
|
local f
|
|
|
|
for f in configure_package \
|
|
pre_unpack unpack post_unpack \
|
|
pre_patch post_patch \
|
|
pre_configure \
|
|
${TARGET_FUNCS} \
|
|
pre_install post_install \
|
|
addon \
|
|
; do
|
|
[[ ${line} =~ ^${f} ]] && return 0
|
|
done
|
|
|
|
log "${filename}" ${lc} "WARN" "unknown function" "${line// *{*/}"
|
|
}
|
|
|
|
process_pkg() {
|
|
local filename="$1"
|
|
local lc=0 isassign=N funcname= fc=0 intertwined=N
|
|
|
|
while IFS= read -r line; do
|
|
lc=$((lc + 1))
|
|
[[ ${line} =~ ^[[:space:]]*$ ]] && continue
|
|
[[ ${line} =~ ^(|[[:space:]]*)# ]] && continue
|
|
|
|
if [[ "${line}" =~ ^[^#]*\(\)[[:space:]]*$ ]]; then
|
|
log "${filename}" ${lc} "FAIL" "bad func - missing brace" "${line}"
|
|
fi
|
|
|
|
if [[ "${line}" =~ \(\)[[:space:]]*\{ ]]; then
|
|
funcname="${line//(*/}"
|
|
fc=$((fc+1))
|
|
check_func_name "${filename}" "${lc}" "${line}"
|
|
fi
|
|
|
|
if [ "${intertwined}" = "N" -a -z "${funcname}" -a ${fc} -ge 1 ]; then
|
|
log "${filename}" ${lc} "WARN" "intertwined vars & funcs" "${line}"
|
|
intertwined=Y
|
|
fi
|
|
|
|
[[ "${line}" =~ ^[[:space:]]*PKG_.*=\" ]] && isassign=Y
|
|
|
|
process_line "$1" "${lc}" "${line}" "${isassign}" "${funcname}"
|
|
|
|
[[ "${line}" =~ (\"$|\"[[:space:]]*$|\"[[:space:]]*#.*$) ]] && isassign=N
|
|
[[ "${line}" =~ (^}|^[[:space:]]*}) ]] && funcname=
|
|
done < "${filename}"
|
|
|
|
# Duplicate function check
|
|
while read -r count line; do
|
|
[ -n "${line}" ] && log "${filename}" 0 "FAIL" "duplicate function def" "${line}"
|
|
done <<< "$(grep -E ".*() {" "${filename}" | sed 's/[[:space:]]*{.*//' | sort | uniq -c | grep -v ^[[:space:]]*1[[:space:]])"
|
|
}
|
|
|
|
TARGET_FUNCS="$(init_target_funcs)"
|
|
|
|
if [ $# -ne 0 ]; then
|
|
for arg in ${@}; do
|
|
for p in $(find packages projects -type f -path */${arg}/package.mk | sort); do
|
|
echo -en "${TXCLR}${p}...\r" >&2
|
|
process_pkg "${p}"
|
|
done
|
|
done
|
|
else
|
|
for p in $(find packages projects -type f -name package.mk | sort); do
|
|
echo -en "${TXCLR}${p}...\r" >&2
|
|
process_pkg "${p}"
|
|
done
|
|
fi
|
|
echo -en "${TXCLR}" >&2
|