From d589df4ebebdd9e89a66dc788e23b3c3db5f23d5 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Tue, 9 May 2017 19:10:42 -0700 Subject: Switch to template-based approach Signed-off-by: Alexey Neyman diff --git a/maintainer/gen-versions.sh b/maintainer/gen-versions.sh index c13abd2..af58b8b 100755 --- a/maintainer/gen-versions.sh +++ b/maintainer/gen-versions.sh @@ -1,293 +1,316 @@ #!/bin/bash -# Where the version configs are generated -config_dir=config/versions -defaults=packages/default.desc +######################################## +# Common meta-language implementation -declare -A forks +declare -A info debug() { - if [ -n "${DEBUG}" ]; then - echo ":: $@" >&2 - fi + if [ -n "${DEBUG}" ]; then + echo "DEBUG :: $@" >&2 + fi } -read_files() +warn() { - local f l - - for f in ${defaults} "$@"; do - [ -r "${f}" ] || continue - while read l; do - case "${l}" in - "#*") continue;; - *) echo "[${l%%=*}]=${l#*=}";; - esac - done < "${f}" - done + echo "WARN :: $@" >&2 } -derived_package() +error() { - info[name]=${p} - info[forks]=${forks[${p}]} - info[master]=${info[master]:-${p}} - # Various kconfig-ized prefixes - tmp=${p^^} - info[pfx]=${tmp//[^0-9A-Z_]/_} - tmp=${info[origin]^^} - info[originpfx]=${tmp//[^0-9A-Z_/_} - tmp=${info[master]^^} - info[masterpfx]=${tmp//[^0-9A-Z_/_} + echo "ERROR :: $@" >&2 + exit 1 } -read_package_desc() +find_end() { - read_files "packages/${1}/package.desc" + local token="${1}" + local count=1 + + # Skip first line, we know it has the proper '#!' command on it + endline=$[l + 1] + while [ "${endline}" -le "${end}" ]; do + case "${tlines[${endline}]}" in + "#!${token} "*) + count=$[count + 1] + ;; + "#!end-${token}") + count=$[count - 1] + ;; + esac + if [ "${count}" = 0 ]; then + return + fi + endline=$[endline + 1] + done + error "line ${l}: '${token}' token is unpaired" } -read_version_desc() +set_iter() { - read_files "packages/${1}/package.desc" "packages/${1}/${2}/version.desc" + local name="${1}" + + if [ "${info[iter_${name}]+set}" = "set" ]; then + error "Iterator over '${name}' is already set up" + fi + shift + debug "Setting iterator over '${name}' to '$*'" + info[iter_${name}]="$*" } -for_each_package() +run_if() { - local list="${1}" - local -A info - local p tmp - - debug "Entering: for_each_package $@" - - shift - for p in ${list}; do - eval "info=( `read_package_desc ${p}` )" - derived_package ${p} - debug "Evaluate for ${p}: $@" - eval "$@" - done + local cond="${1}" + local endline + + find_end "if" + if eval "${cond}"; then + debug "True conditional '${cond}' at lines ${l}..${endline}" + run_lines $[l + 1] $[endline - 1] + else + debug "False conditional '${cond}' at lines ${l}..${endline}" + fi + lnext=$[endline + 1] + debug "Continue at line ${lnext}" } -for_each_version() +do_foreach() { - local pkg="${1}" - local -A info prev - local -a versions - local v tmp - - debug "Entering: for_each_version $@" - - shift - versions=( `cd packages/${pkg} && ls */version.desc 2>/dev/null | sed 's,/version.desc$,,' | sort -rV` ) - tmp= - for v in "${versions[@]}"; do - if [ -n "${tmp}" ]; then - prev["${tmp}"]=${v} - fi - tmp="${v}" - done - - if [ -n "${tmp}" ]; then - prev["${tmp}"]= - fi - - for v in "${versions[@]}"; do - eval "info=( `read_version_desc "${pkg}" "${v}"` )" - debug "INFO [[ `read_version_desc "${pkg}" "${v}"` ]]" - derived_package ${pkg} - info[ver]="${v}" - info[kcfg]="${v//[^0-9A-Za-z_]/_}" - info[prev]="${prev[${v}]//[^0-9A-Za-z_]/_}" - debug "Evaluate for ${pkg}/${v}: $@" - eval "$@" - done + local var="${1}" + local v saveinfo + + shift + if [ "`type -t enter_${var}`" != "function" ]; then + error "No parameter setup routine for iterator over '${var}'" + fi + for v in ${info[iter_${var}]}; do + saveinfo=`declare -p info` + eval "enter_${var} ${v}" + eval "$@" + eval "${saveinfo#declare -A }" + done } -# Setup: find master-fork relationships between packages -find_forks() +run_foreach() { - [ "${info[master]}" != "${info[name]}" ] && forks[${info[master]}]+=" ${info[name]}" + local var="${1}" + local endline + + if [ "${info[iter_${var}]+set}" != "set" ]; then + error "line ${l}: iterator over '${var}' is not defined" + fi + find_end "foreach" + debug "Loop over '${var}', lines ${l}..${endline}" + do_foreach ${var} run_lines $[l + 1] $[endline - 1] + lnext=$[endline + 1] + debug "Continue at line ${lnext}" } -gen_versions() +run_lines() { - local cond=$1 - - debug "Entering: gen_versions $@" - - if [ -n "${cond}" ]; then - cat <"${config_dir}/${info[name]}.in" - cat </dev/null | sed 's,/package.desc$,,' | xargs echo` +pkg_all=( `cd packages && \ + ls */package.desc 2>/dev/null | \ + while read f; do [ -r "${f}" ] && echo "${f%/package.desc}"; done | \ + xargs echo` ) debug "Generating package version descriptions" -debug "Packages: ${all_packages}" -for_each_package "${all_packages}" find_forks -for_each_package "${all_packages}" gen_one_component -debug "Done!" +debug "Packages: ${pkg_all[@]}" + +# We need to group forks of the same package into the same +# config file. Discover such relationships and only iterate +# over "master" packages at the top. +for p in "${pkg_all[@]}"; do + find_forks "${p}" +done +debug "Master packages: ${pkg_masters[@]}" + +# Now for each master, create its kconfig file with version +# definitions. +for p in "${pkg_masters[@]}"; do + debug "Generating '${config_dir}/${p}.in'" + exec >"${config_dir}/${p}.in" + # Base definitions for the whole config file + info=( \ + [master]=${p} \ + [masterpfx]=`kconfigize ${p}` \ + [nforks]=${pkg_nforks[${p}]} \ + ) + set_iter fork ${pkg_forks[${p}]} + run_template "${template}" +done diff --git a/maintainer/kconfig-versions.template b/maintainer/kconfig-versions.template new file mode 100644 index 0000000..7aa0de1 --- /dev/null +++ b/maintainer/kconfig-versions.template @@ -0,0 +1,129 @@ +# +# DO NOT EDIT! This file is automatically generated. +# + +#!if [ "@@nforks@@" -ge 2 ] +choice + bool "Show @@master@@ versions from" + +#!foreach fork +config @@masterpfx@@_USE_@@originpfx@@ + bool "@@origin@@" +#!if [ -n "@@only_obsolete@@" ] + depends on OBSOLETE +#!end-if +#!if [ -n "@@only_experimental@@" ] + depends on EXPERIMENTAL +#!end-if + help +@@originhelp@@ + +#!end-foreach +endchoice + +config @@masterpfx@@_USE + string +#!foreach fork + default "@@pfx@@" if @@masterpfx@@_USE_@@originpfx@@ +#!end-foreach + +#!end-if + +#!foreach fork +#!if [ "@@nforks@@" -ge 2 ] +if @@masterpfx@@_USE_@@originpfx@@ +#!end-if + +if EXPERIMENTAL +choice + bool "Source of @@name@@" + +config @@pfx@@_SRC_RELEASE + bool "Released tarball" + help + Download a released tarball. + +#!if [ -n "@@repository@@" ] +config @@pfx@@_SRC_DEVEL + bool "Vendor repository" + help + Check out from vendor repository at: + @@repository@@ +#!end-if + +config @@pfx@@_SRC_CUSTOM + bool "Custom location" + help + Custom directory or tarball. + +endchoice +endif + +#!if [ -n "@@repository@@" ] +if @@pfx@@_SRC_DEVEL + +config @@pfx@@_DEVEL_VCS + string + default "@@vcs@@" + +config @@pfx@@_DEVEL_URL + string + default "@@repository_url@@" + +config @@pfx@@_DEVEL_BRANCH + string "Branch to check out" + default "@@repository_dflt_branch@@" + help + Git: branch to be checked out + Subversion: directories to append to the repository URL. + +config @@pfx@@_DEVEL_REVISION + string "Revision/changeset" + default "HEAD" + help + Commit ID or revision ID to check out. + +endif +#!end-if + +if @@pfx@@_SRC_CUSTOM + +config @@pfx@@_CUSTOM_LOCATION + string "Custom source location" + help + Path to the directory or tarball with the sources. + +endif + +choice + bool "Version of @@name@@" + +#!foreach version +config @@pfx@@_V_@@kcfg@@ + bool "@@ver@@" + select @@pfx@@_V_@@kcfg@@_or_later + +#!end-foreach +endchoice + +#!if [ "@@nforks@@" -ge 2 ] +endif +#!end-if + +config @@pfx@@_VERSION + string +#!foreach version + default "@@ver@@" if @@pfx@@_V_@@kcfg@@ +#!end-foreach + default "unknown" + +#!foreach version +config @@pfx@@_V_@@kcfg@@_or_later + bool +#!if [ -n "@@prev@@" ] + select @@pfx@@_V_@@prev@@_or_later +#!end-if + +#!end-foreach + +#!end-foreach -- cgit v0.10.2-6-g49f6