diff --git a/scripts/srcinfo.sh b/scripts/srcinfo.sh index 7d88e3ea88..517777d1ee 100755 --- a/scripts/srcinfo.sh +++ b/scripts/srcinfo.sh @@ -304,41 +304,19 @@ function srcinfo._contains() { # @description Create array based on input # # @example -# srcinfo._create_array pkgbase var_name var_prefix +# srcinfo._create_array base var_name # -# @arg $1 string (optional) The pkgbase of the section +# @arg $1 string The pkgbase of the section # @arg $2 string The variable name -# @arg $3 string (optional) The variable prefix # # @stdout Name of array created. function srcinfo._create_array() { - local pkgbase="${1}" var_name="${2}" var_pref="${3}" - if [[ -n ${pkgbase} ]]; then - pkgbase="${pkgbase//./_}" var_name="${var_name//./_}" - if ! [[ -v "${var_pref}_${pkgbase}_array_${var_name}" ]]; then - declare -ag "${var_pref}_${pkgbase}_array_${var_name}" - fi - echo "${var_pref}_${pkgbase}_array_${var_name}" - else - if ! [[ -v "${var_pref}_array_${var_name}" ]]; then - declare -ag "${var_pref}_array_${var_name}" - fi - echo "${var_pref}_array_${var_name}" + local base="${1}" var_name="${2}" + base="${base//./_}" var_name="${var_name//./_}" + if ! [[ -v "srcinfo_${base}_array_${var_name}" ]]; then + declare -ag "srcinfo_${base}_array_${var_name}" fi -} - -# @description Promote array to variable -# -# @example -# foo=('bar') -# srcinfo._promote_to_variable foo -# -# @arg $1 string Name of array to promote -function srcinfo._promote_to_variable() { - local var_name="${1}" key value - key="${var_name}" - value="${!var_name[0]}" - declare -g "${key}=${value}" + echo "srcinfo_${base}_array_${var_name}" } function srcinfo.parse() { @@ -346,15 +324,14 @@ function srcinfo.parse() { # shellcheck disable=SC2064 trap "$(shopt -p extglob)" RETURN shopt -s extglob - local srcinfo_file var_prefix locbase temp_array ref total_list loop part i part_two split_up suffix - srcinfo_file="${1:?No .SRCINFO passed to srcinfo.parse}" - var_prefix="${2:?Variable prefix not passed to srcinfo.parse}" - srcinfo.cleanup "${var_prefix}" - [[ ! -s ${srcinfo_file} ]] && return 5 - while IFS= read -r line; do + srcinfo.cleanup + local srcfile locbase temp_array ref total_list loop part i suffix + srcfile="${1:?No .SRCINFO passed to srcinfo.parse}" + [[ ! -s ${srcfile} ]] && return 5 + mapfile -t srcinfo_data < "${srcfile}" + for line in "${srcinfo_data[@]}"; do # Skip blank lines - [[ -z ${line} ]] && continue - [[ ${line} =~ ^\s*#.* ]] && continue + [[ -z ${line} || ${line} =~ ^\s*#.* ]] && continue # Trim leading whitespace. line="${line##+([[:space:]])}" declare -A temp_line @@ -372,10 +349,10 @@ function srcinfo.parse() { # Do we have pkgbase first? if [[ ${temp_line[key]} == "pkgbase" ]]; then locbase="pkgbase_${temp_line[value]//-/_}" - export globase="${temp_line[value]//./_}" + globase="${temp_line[value]//./_}" else locbase="${temp_line[value]//-/_}" - export globase="temporary_pacstall_pkgbase" + globase="temporary_pacstall_pkgbase" fi elif [[ ${temp_line[key]} == *"pkgname" ]]; then # Bash can't have dashes in variable names @@ -385,162 +362,38 @@ function srcinfo.parse() { # So the strategy is to create arrays of every key and at the end, # we can promote array.len() == 1 to variables instead. After that we # can work back upwards. - temp_array="$(srcinfo._create_array "${locbase}" "${temp_line[key]}" "${var_prefix}")" + temp_array="$(srcinfo._create_array "${locbase}" "${temp_line[key]}" "srcinfo")" declare -n ref="${temp_array}" ref+=("${temp_line[value]}") - if [[ ${locbase} == "pkgbase_"* ]] || ! srcinfo._contains total_list "${temp_array}"; then + if ! srcinfo._contains total_list "${temp_array}"; then total_list+=("${temp_array}") fi - done < "${srcinfo_file}" - declare -Ag "${var_prefix}_access" + done + unset srcinfo_data + declare -Ag "srcinfo_access" for loop in "${total_list[@]}"; do declare -n part="${loop}" # Are we at a new pkgname (pkgbase)? if [[ ${loop} == *@(pkgname|pkgbase) ]]; then - declare -n var_name="${var_prefix}_access" - [[ ${loop} == "${var_prefix}_pkgbase"* ]] && global="pkgbase_" + declare -n var_name="srcinfo_access" + [[ ${loop} == "srcinfo_pkgbase"* ]] && global="pkgbase_" for i in "${!part[@]}"; do suffix="${global}${part[${i}]//-/_}" suffix="${suffix//./_}" # Create our inner part - declare -ga "${var_prefix}_${suffix}" + declare -ga "srcinfo_${suffix}" # Declare that relationship - var_name["${var_prefix}_${suffix}"]="${var_prefix}_${suffix}" + var_name["srcinfo_${suffix}"]="srcinfo_${suffix}" done unset global fi done - for part_two in "${total_list[@]}"; do - # Now we need to go and check every loop over, and parse it out so we get something like ("prefix", "key"), so we can then work with that. - # But first actually we should promote single element arrays to variables - declare -n referoo="${part_two}" - if (("${#referoo[@]}" == 1)); then - srcinfo._promote_to_variable "${part_two}" - fi - mapfile -t split_up <<< "${part_two/_array_/$'\n'}" - declare -n addarr="${split_up[0]}" - unset "${split_up[1]}" - # So now we need to check if the thing we're trying to insert is a variable, - # or an array. - if srcinfo.is_array "${part_two}"; then - declare -ga "${part_two}" - # shellcheck disable=SC2004 - addarr[${split_up[1]}]="${part_two}" - else - # shellcheck disable=SC2034,SC2004 - addarr[${split_up[1]}]="${!part_two}" - fi - done } function srcinfo.cleanup() { - local var_prefix="${1:?No var_prefix passed to srcinfo.cleanup}" i z - local main_loop_template="${var_prefix}_access" compg - declare -n main_loop="${main_loop_template}" - for i in "${main_loop[@]}"; do - declare -n cleaner="${i}" - for z in "${cleaner[@]}"; do - unset "${var_prefix}_array_${z}" - done - unset cleaner - done - unset "${var_prefix}_access" globase global - # So now lets clean the stragglers that we can't reasonably infer - mapfile -t compg < <(compgen -v) - for i in "${compg[@]}"; do - if [[ ${i} == "${var_prefix}_"* ]]; then - unset -v "${i}" - fi - done -} - -# @description Reformat numbered associative array to indexed -# -# @example -# srcinfo_depends_vala_panel_appmenu_xfce_git=(["vala-panel-appmenu-valapanel-git-0"]="gtk3") -# srcinfo.reformat_assoc_arr "srcinfo_depends_vala_panel_appmenu_xfce_git" "eviler" -# -# converts to `srcinfo_depends_vala_panel_appmenu_valapanel_git=([0]="gtk3")` -# -# @arg $1 string Associative array to reformat -# @arg $2 string Ref string of indexed array to append conversion to (can be anything) -function srcinfo.reformat_assoc_arr() { - local pfx base ida new pfs in_name="${1}" - local -n in_arr="${in_name}" app="${2}" - IFS='_' read -r -a pfs <<< "${in_name}" - for pfx in "${!in_arr[@]}"; do - base="${pfx%-*}" ida="${pfx##*-}" new="${base//-/_}" - new="${new//./_}" - app+=("$(printf "%s[%s]=\"%s\"\n" "${pfs[0]}_${pfs[1]}_${new}" "${ida}" "${in_arr[${pfx}]}")") - done -} - -# @description Parse a specific variable from .SRCINFO -# -# @example -# -# srcinfo.print_var .SRCINFO source -# @arg $1 string .SRCINFO file path -# @arg $2 string Variable or Array to print -function srcinfo.print_var() { - local srcinfo_file="${1}" found="${2}" var_prefix="srcinfo" pkgbase output var name idx evil eviler e printed - local -n bases="${var_prefix}_access" - srcinfo.parse "${srcinfo_file}" "${var_prefix}" - if [[ ${found} == "pkgbase" ]]; then - if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then - pkgbase="${globase}" - declare -p pkgbase - return 0 - else - return 3 - fi - fi - for var in "${bases[@]}"; do - var="${var//./_}" - declare -n output="${var}_array_${found}" - declare -n name="${var}_array_pkgname" - if [[ -n ${output[*]} ]]; then - for idx in "${!output[@]}"; do - if ((${#bases[@]} > 1)); then - # shellcheck disable=SC2076 - if [[ ${var} =~ "pkgbase_${globase//-/_}" ]]; then - evil+=("$(printf "${var_prefix}_${found}_${globase//-/_}[\"${globase}-pkgbase-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")") - else - evil+=("$(printf "${var_prefix}_${found}_${globase//-/_}[\"${name}-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")") - fi - else - evil+=("$(printf "${var_prefix}_${found}_${name//-/_}[\"${name}-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")") - fi - done - fi - done - if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then - unset "${var_prefix}_${found}_${globase//-/_}" - declare -Ag "${var_prefix}_${found}_${globase//-/_}" - else - unset "${var_prefix}_${found}_${name//-/_}" - declare -Ag "${var_prefix}_${found}_${name//-/_}" - fi - # shellcheck disable=SC2294 - eval "${evil[@]}" - if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then - srcinfo.reformat_assoc_arr "${var_prefix}_${found}_${globase//-/_}" "eviler" - unset "${var_prefix}_${found}_${globase//-/_}" - # shellcheck disable=SC2294 - eval "${eviler[@]}" - else - srcinfo.reformat_assoc_arr "${var_prefix}_${found}_${name//-/_}" "eviler" - unset "${var_prefix}_${found}_${name//-/_}" - # shellcheck disable=SC2294 - eval "${eviler[@]}" - fi - for e in "${eviler[@]}"; do - if ! srcinfo._contains printed "${e%\[*}"; then - printed+=("${e%\[*}") - declare -p "${e%\[*}" - fi - unset "${e%\[*}" - done + local compg + mapfile -t compg < <(compgen -v "srcinfo_") + unset "${compg[@]}" srcinfo_access globase global 2> /dev/null } # @description Output a specific variable from .SRCINFO @@ -553,46 +406,22 @@ function srcinfo.print_var() { # @arg $2 string Variable or Array to search # @arg $3 string Package name or base to get output for function srcinfo.match_pkg() { - local declares d bases b guy match out srcfile="${1}" search="${2}" pkg="${3}" + local srcinfo_file="${1}" search="${2}" pkg="${3}" pkgbase output var + local -n bases="srcinfo_access" pkg="${pkg//./_}" - if [[ ${pkg} == "pkgbase:"* || ${search} == "pkgbase" ]]; then - pkg="${pkg/pkgbase:/}" - match="srcinfo_${search%%_*}_${pkg//-/_}_pkgbase" - else - match="srcinfo_${search%%_*}_${pkg//-/_}" - fi - mapfile -t declares < <(srcinfo.print_var "${srcfile}" "${search}" | awk '{sub(/^declare -a |^declare -- |^declare -x /, ""); print}') - [[ ${search} == "pkgbase" && -z ${declares[*]} ]] \ - && mapfile -t declares < <(srcinfo.print_var "${srcfile}" "pkgname" | awk '{sub(/^declare -a |^declare -- |^declare -x /, ""); print}') - for d in "${declares[@]}"; do - if [[ ${d%=\(*} =~ = ]]; then - declare -- "${d}" - bases+=("${d%=*}") - else - declare -a "${d}" - bases+=("${d%=\(*}") - fi - done - for b in "${bases[@]}"; do - guy="${b}[@]" - if [[ -z ${pkg} ]]; then - if [[ ${search} == "pkgname" || ${search} == "pkgbase" ]]; then - if [[ -n ${pkgbase} ]]; then - out="${pkgbase/\"/}" - out="${out/\"/}" - printf '%s\n' "pkgbase:${out}" - continue - fi - printf '%s\n' "${!guy}" - continue - else - printf '%s\n' "${guy}" - continue + pkg="${pkg//:/_}" + pkg="${pkg//-/_}" + srcinfo.parse "${srcinfo_file}" + for var in "${bases[@]}"; do + var="${var//./_}" + declare -n output="${var}_array_${search}" + if [[ -n ${output[*]} ]]; then + if [[ ${search} == "pkgbase" ]]; then + echo "pkgbase:${output[0]}" + elif [[ ${search} == "pkgname" || ${var}_array_${search} == "srcinfo_${pkg}_array_${search}" ]]; then + printf '%s\n' "${output[@]}" fi fi - if [[ ${b} == "${match}" ]]; then - printf '%s\n' "${!guy}" - fi done } @@ -663,45 +492,50 @@ function srcinfo.list_search() { function print_pkgbase_and_pkgname() { if (pkgbase != "") { print pkgbase, pkgbase_desc - if (pkgname != "") { - desc = (pkgname_desc != "" ? pkgname_desc : pkgbase_desc) - print pkgbase ":" pkgname, desc + for (i in pkgnames) { + desc = (pkgname_descs[i] != "" ? pkgname_descs[i] : pkgbase_desc) + print pkgbase ":" pkgnames[i], desc } } } /^---$/ { - if (pkgbase != "" && (pkgbase ~ kw || tolower(pkgbase_desc) ~ kw)) { - print_pkgbase_and_pkgname() - found = 1 - } else if (pkgname != "" && (pkgname ~ kw || tolower(pkgname_desc) ~ kw)) { - print_pkgbase_and_pkgname() - found = 1 + if (pkgbase != "") { + if (pkgbase ~ kw || tolower(pkgbase_desc) ~ kw || kw == "") { + print_pkgbase_and_pkgname() + found = 1 + } else { + for (i in pkgnames) { + desc = (pkgname_descs[i] != "" ? pkgname_descs[i] : pkgbase_desc) + if (pkgnames[i] ~ kw || tolower(desc) ~ kw) { + print pkgbase ":" pkgnames[i], desc + found = 1 + } + } + } } - pkgname = ""; pkgbase = ""; pkgbase_desc = ""; pkgname_desc = ""; next + pkgbase = ""; pkgbase_desc = ""; delete pkgnames; delete pkgname_descs + next } /^[[:space:]]*pkgbase[[:space:]]*=/ { pkgbase = $2 pkgbase_desc = "" } /^[[:space:]]*pkgname[[:space:]]*=/ { - if (pkgname != "") { - desc = (pkgname_desc != "" ? pkgname_desc : pkgbase_desc) - if (pkgname ~ kw || tolower(desc) ~ kw) { - print pkgbase ":" pkgname, desc - found = 1 - } - } - pkgname = $2 - pkgname_desc = "" + # Add pkgname to array + pkgnames[length(pkgnames) + 1] = $2 + pkgname_descs[length(pkgnames)] = "" } /^[[:space:]]*pkgdesc[[:space:]]*=/ { - if (pkgname == "") { + if (length(pkgnames) == 0) { pkgbase_desc = $2 } else { - pkgname_desc = $2 + pkgname_descs[length(pkgnames)] = $2 } } END { + if (pkgbase != "") { + print_pkgbase_and_pkgname() + } if (!found) { print "No matching packages found" }