[type/__uci_section] Improve --match support with existing named sections

Use section if named section exists without --match option (e.g. empty section).
This commit is contained in:
Dennis Camera 2020-10-25 21:10:27 +01:00
parent 4aebb1f127
commit 63d41a1053
1 changed files with 51 additions and 29 deletions

View File

@ -20,62 +20,84 @@
# This explorer determines the "prefix" of the --type section matching --match
# if set, or __object_id otherwise.
RS=$(printf '\036')
NL=$(printf '\n '); NL=${NL% }
squote_values() {
sed -e '/=".*"$/{s/="/='\''/;s/"$/'\''/}' \
-e "/='.*'$/"'!{s/=/='\''/;s/$/'\''/}'
}
count_lines() (
IFS=${NL?}
# shellcheck disable=SC2048,SC2086
set -f -- $*; echo $#
)
RS=$(printf '\036')
if ! test -e "${__object:?}/parameter/match"
then
if ! echo "${__object_id:?}" | grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$'
then
echo 'Section identifiers are a package and section name separated by a "." (period).' >&2
exit 1
fi
echo "${__object_id:?}" | grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$' || {
echo 'Section identifiers are a package and section name separated by a "." (period).' >&2
exit 1
}
test -s "${__object:?}/parameter/match" || {
# If no --match is given, we take the __object_id as the section identifier.
echo "${__object_id:?}"
exit 0
fi
# shellcheck disable=SC2015
test -s "${__object:?}/parameter/match" && test -s "${__object:?}/parameter/type" \
|| {
}
test -s "${__object:?}/parameter/type" || {
echo 'Parameters --match and --type must be used together.' >&2
exit 1
}
# Find by match
# NOTE: Apart from section types all values are printed in single quotes by UCI.
match=$(head -n 1 "${__object:?}/parameter/match" | squote_values)
if ! grep -q -e '^[^.]\{1,\}\.[^.]\{1,\}$' "${__object:?}/parameter/type"
then
sect_type_param=$(cat "${__object:?}/parameter/type")
expr "${sect_type_param}" : '[^.]\{1,\}\.[^.]\{1,\}$' >/dev/null 2>&1 || {
echo 'Section types are a package name and section type separated by a "." (period).' >&2
exit 1
}
package_filter=${sect_type_param%%.*}
section_filter=${sect_type_param#*.}
# Find by --match
# NOTE: Apart from section types all values are printed in single quotes by uci show.
match=$(head -n 1 "${__object:?}/parameter/match" | squote_values)
if uci -s -N get "${__object_id:?}" >/dev/null 2>&1
then
# Named section exists: ensure if --match applies to it
# if the "matched" option does not exist (e.g. empty section) we use the
# section unconditionally.
if match_value_is=$(uci -s -N get "${__object_id:?}.${match%%=*}" 2>/dev/null)
then
match_value_should=$(expr "${match}" : ".*='\\(.*\\)'$")
test "${match_value_is}" = "${match_value_should}" || {
printf 'Named section "%s" does not match --match "%s"\n' \
"${__object_id:?}" "${match}" >&2
exit 1
}
fi
echo "${__object_id:?}"
exit 0
fi
sect_type_filter=$(cat "${__object:?}/parameter/type")
package_filter=${sect_type_filter%%.*}
section_filter=${sect_type_filter#*.}
# FIXME: Does not work with named sections
regex="^${package_filter}\.@${section_filter}\[[0-9]\{1,\}\]\.${match%%=*}="
# No correctly named section exists already: find one to which --match applies
regex="^${package_filter}\\.@${section_filter}\\[[0-9]\\{1,\\}\\]\\.${match%%=*}="
matched_sections=$(
uci -s -N -d "${RS}" show "${package_filter}" 2>/dev/null \
| grep -e "${regex}" \
| while read -r _line
do
if test "${_line#*=}" = "${match#*=}"; then echo "${_line}"; fi
if test "${_line#*=}" = "${match#*=}"
then
echo "${_line}"
fi
done \
| sed -e 's/\.[^.]*=.*$//')
if test "$(echo "${matched_sections}" | wc -l)" -gt 1
then
test "$(count_lines "${matched_sections}")" -le 1 || {
printf 'Found multiple matching sections:\n%s\n' "${matched_sections}" >&2
exit 1
fi
}
echo "${matched_sections}"