blob: e0788b28a12553efe0d2520f27d69e692ea10355 [file] [log] [blame]
#!/bin/bash
# Parses Kconfig lines like
# CONFIG_DEBUG=y >=6.1
# # CONFIG_DEBUG is not set <6.1
# and only adds them to the build if the kernel is 6.1 or greater
# Regular lines are unchanged
version="$1"
shift
declare -A plats
for plat in $1; do
plats["$plat"]=1
done
shift
files=("$@")
# Disallow "x.y" versions as they don't sort correctly
is_xy_ver() {
[[ "$1" =~ ^[0-9]+[.][0-9]+$ ]]
}
if is_xy_ver "$version"; then
echo "Linux version is unsupported $version" >&2
exit 1
fi
declare -A config=()
fail=
for file in "${files[@]}"; do
echo "Trimming $file to $version" >&2
fdone=0
while (( fdone == 0 )); do
read -r line || fdone=$?
if [[ $line =~ ^'# '(CONFIG_[_A-Za-z0-9]*)' is not set'( (.*))?$ ]]; then
# Match options that unset configuration options equivalent to CONFIG_*=n
# - # CONFIG_I2C_MUX_PCA9541 is not set
# - # CONFIG_DEVPORT is not set
key="${BASH_REMATCH[1]}"
op='='
val='n'
larr=(${BASH_REMATCH[3]})
elif [[ $line =~ ^(CONFIG_[_A-Za-z0-9]*)(=|'+=')('"'.*'"'|[^ ]*)(' '(.*))? ]]; then
# Match options that set configuration options equivalent to CONFIG_*=<val>
# - CONFIG_I2C_MUX_PCA954x=y
# - CONFIG_DEVMEM=y armv7,armv8
#
# Also match append operations (can only be used on strings)
# - CONFIG_CMDLINE+=" opt1"
# - CONFIG_CMDLINE+=" opt2" armv8
key="${BASH_REMATCH[1]}"
op="${BASH_REMATCH[2]}"
val="${BASH_REMATCH[3]}"
larr=(${BASH_REMATCH[5]})
elif [[ $line =~ ^' '*(#.*)?$ ]]; then
continue
else
echo "Unrecognized line: $line" >&2
fail=1
fi
skip=
for const in "${larr[@]}"; do
if [[ "${const:0:1}" == '#' ]]; then
break
elif [[ ${const:0:2} == '>=' ]]; then
if is_xy_ver "${const:2}"; then
echo "Constraint version is unsupported ${const:2}: $line" >&2
fail=1
fi
expected="${const:2}"$'\n'"$version"
if [[ $expected != $(echo "$expected" | sort -V) ]]; then
skip=1
break
fi
elif [[ ${const:0:1} == '>' ]]; then
if is_xy_ver "${const:1}"; then
echo "Constraint version is unsupported ${const:1}: $line" >&2
fail=1
fi
expected="${const:1}"$'\n'"$version"
if [[ ${const:1} == $version || $expected != $(echo "$expected" | sort -V) ]]; then
skip=1
break
fi
elif [[ ${const:0:2} == '<=' ]]; then
if is_xy_ver "${const:2}"; then
echo "Constraint version is unsupported ${const:2}: $line" >&2
fail=1
fi
expected="$version"$'\n'"${const:2}"
if [[ $expected != $(echo "$expected" | sort -V) ]]; then
skip=1
break
fi
elif [[ ${const:0:1} == '<' ]]; then
if is_xy_ver "${const:1}"; then
echo "Constraint version is unsupported ${const:1}: $line" >&2
fail=1
fi
expected="$version"$'\n'"${const:1}"
if [[ ${const:1} == $version || $expected != $(echo "$expected" | sort -V) ]]; then
skip=1
break
fi
elif [[ $const =~ ^[a-zA-Z0-9] ]]; then
OLDIFS="$IFS"
IFS=','
match=
for plat in $const; do
if [[ -v plats["$plat"] ]]; then
match=1
break
fi
done
IFS="$OLDIFS"
if [[ -z "$match" ]]; then
skip=1
break
fi
else
echo "Unexpected constraint '$const' at line: $line" >&2
fail=1
fi
done
if [[ -z $skip ]]; then
if [[ $op == '=' ]]; then
config["$key"]="$val"
elif [[ $op == '+=' ]]; then
if [[ ${val:0:1} != '"' || "${val: -1}" != '"' ]]; then
echo "Only know how to append strings: $line"
fail=1
fi
oldval="${config["$key"]}"
if [[ -z "$oldval" ]]; then
config["$key"]="$val"
else
config["$key"]="${oldval:0:-1}${val:1}"
fi
else
echo "Unrecognized operator '$op': $line" >&2
fi
fi
done <"$file"
done
if [[ -n "$fail" ]]; then
exit 1
fi
written=
for file in "${files[@]}"; do
exec {nfile}<>"$file.tmp"
# Only write to the first file in the list of files, so that our merged
# values definitely only take effect once. We leave empty tombstones for
# the old files, so that any build structure depending on them still works.
if [[ -z "$written" ]]; then
echo "Writing fuill config to $file" >&2
for key in "${!config[@]}"; do
echo "$key=${config["$key"]}" >&$nfile
done
written=1
fi
exec {nfile}>&-
mv "$file.tmp" "$file"
done