diff options
author | Alexey Neyman <stilor@att.net> | 2017-05-09 19:10:42 -0700 |
---|---|---|
committer | Alexey Neyman <stilor@att.net> | 2017-07-08 10:56:29 -0700 |
commit | d589df4ebebdd9e89a66dc788e23b3c3db5f23d5 (patch) | |
tree | e31e38f9fcbaf470cc01e2de20ef2a3dfe11e24e /maintainer | |
parent | 2c615fa62c47c324adfd91cde7a68bd06b6164d5 (diff) | |
download | crosstool-ng-d589df4ebebdd9e89a66dc788e23b3c3db5f23d5.tar.gz crosstool-ng-d589df4ebebdd9e89a66dc788e23b3c3db5f23d5.tar.bz2 crosstool-ng-d589df4ebebdd9e89a66dc788e23b3c3db5f23d5.zip |
Switch to template-based approach
Signed-off-by: Alexey Neyman <stilor@att.net>
Diffstat (limited to 'maintainer')
-rwxr-xr-x | maintainer/gen-versions.sh | 501 | ||||
-rw-r--r-- | maintainer/kconfig-versions.template | 129 |
2 files changed, 391 insertions, 239 deletions
diff --git a/maintainer/gen-versions.sh b/maintainer/gen-versions.sh index c13abd27..af58b8b4 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 <<EOF -if ${cond} - -EOF - fi - - cat <<EOF -# Versions for ${info[name]} -choice - bool - prompt "Version of ${info[name]}" - -# Defined versions first -EOF - - for_each_version "${info[name]}" echo \"' -config ${info[pfx]}_V_${info[kcfg]} - bool \"${info[ver]}\" - select ${info[pfx]}_V_${info[kcfg]}_or_later${info[obsolete]:+ - depends on OBSOLETE}${info[experimental]:+ - depends on EXPERIMENTAL}'\" - - if [ -n "${info[repository]}" ]; then - cat <<EOF - -config ${info[pfx]}_V_DEVEL - bool "development" - depends on EXPERIMENTAL - help - Check out from the repository: ${info[repository]#* } -EOF - fi - - # TBD custom (local tarball/directory) - # TBD show custom location selection - - cat <<EOF - -endchoice -EOF - - if [ -n "${info[repository]}" ]; then - local -A dflt_branch=( [git]="master" [svn]="/trunk" ) - cat <<EOF - -if ${info[pfx]}_V_DEVEL - -config ${info[pfx]}_DEVEL_URL - string - default "${info[repository]}" - -config ${info[pfx]}_DEVEL_BRANCH - string "Branch to check out" - default "${dflt_branch[${info[repository]%% *}]}" - help - Git: branch to be checked out - Subversion: directories to append to the repository URL. - -config ${info[pfx]}_DEVEL_REVISION - string "Revision/changeset" - default "HEAD" - help - Commit ID or revision ID to check out. - -endif + local start="${1}" + local end="${2}" + local l lnext s v + + debug "Running lines ${start}..${end}" + l=${start} + while [ "${l}" -le "${end}" ]; do + lnext=$[l+1] + s="${tlines[${l}]}" + # Expand @@foo@@ to ${info[foo]}. First escape quotes/backslashes. + s="${s//\\/\\\\}" + s="${s//\$/\\\$}" + while [ -n "${s}" ]; do + case "${s}" in + *@@*@@*) + v="${s#*@@}" + v="${v%%@@*}" + if [ "${info[${v}]+set}" != "set" ]; then + error "line ${l}: reference to undefined variable '${v}'" + fi + s="${s%%@@*}\${info[${v}]}${s#*@@*@@}" + ;; + *@@*) + error "line ${l}: non-paired @@ markers" + ;; + *) + break + ;; + esac + done + + debug "Evaluate: ${s}" + case "${s}" in + "#!if "*) + run_if "${s#* }" + ;; + "#!foreach "*) + run_foreach "${s#* }" + ;; + "#!"*) + error "line ${l}: unrecognized command" + ;; + *) + # Not a special command + eval "echo \"${s//\"/\\\"}\"" + ;; + esac + l=${lnext} + done +} -EOF - fi +run_template() +{ + local -a tlines + local src="${1}" - cat <<EOF + debug "Running template ${src}" + mapfile -O 1 -t tlines < "${src}" + run_lines 1 ${#tlines[@]} +} -# Text string with the version of ${info[name]} -config ${info[pfx]}_VERSION - string -EOF - for_each_version "${info[name]}" echo \ - \"' default \"${info[ver]}\" if ${info[pfx]}_V_${info[kcfg]}'\" - cat <<EOF - default "unknown" +######################################## -EOF +# Where the version configs are generated +config_dir=config/versions +template=maintainer/kconfig-versions.template - cat <<EOF +declare -A pkg_forks +declare -a pkg_masters pkg_nforks pkg_all -# Flags for all versions indicating "this or later". -# Only produced for master version of the package (which is what -# the build scriptes are tied to); derived versions must -# select the matching master version. -EOF - for_each_version "${info[name]}" echo \"' -config ${info[pfx]}_V_${info[kcfg]}_or_later - bool${info[prev]:+ - select ${info[pfx]}_V_${info[prev]}_or_later}'\" +kconfigize() +{ + local v="${1}" - if [ -n "${cond}" ]; then - cat <<EOF + v=${v//[^0-9A-Za-z_]/_} + echo "${v^^}" +} -endif +read_file() +{ + local l + + while read l; do + case "${l}" in + "#*") continue;; + *) echo "info[${l%%=*}]=${l#*=}";; + esac + done < "${1}" +} -EOF - fi +read_package_desc() +{ + read_file "packages/${1}/package.desc" } -# Generate a menu for selecting a fork for a component -gen_selection() +read_version_desc() { - local only_obsolete=yes only_experimental=yes + read_file "packages/${1}/${2}/version.desc" +} - for_each_version "${info[name]}" ' -[ -z "${info[experimental]}" ] && only_experimental= -[ -z "${info[obsolete]}" ] && only_obsolete= -' +find_forks() +{ + local -A info + + eval `read_package_desc ${1}` + + if [ -n "${info[master]}" ]; then + pkg_nforks[${info[master]}]=$[pkg_nforks[${info[master]}]+1] + pkg_forks[${info[master]}]+=" ${1}" + else + pkg_nforks[${1}]=$[pkg_nforks[${1}]+1] + pkg_forks[${1}]="${1}${pkg_forks[${1}]}" + pkg_masters+=( "${1}" ) + fi +} - debug "${info[name]}: ${only_obsolete:+obsolete} ${only_experimental:+experimental}" +check_obsolete_experimental() +{ + [ -z "${info[obsolete]}" ] && only_obsolete= + [ -z "${info[experimental]}" ] && only_experimental= +} - echo " -config ${info[masterpfx]}_USE_${info[originpfx]} - bool \"${info[origin]}\"${only_obsolete:+ - depends on OBSOLETE}${only_experimental:+ - depends on EXPERIMENTAL} - help" && sed 's/^/\t /' "packages/${info[origin]}.help" +enter_fork() +{ + local fork="${1}" + local -A dflt_branch=( [git]="master" [svn]="/trunk" ) + local versions + local only_obsolete only_experimental + + eval `read_package_desc ${fork}` + + info[name]=${fork} + info[pfx]=`kconfigize ${fork}` + info[originpfx]=`kconfigize ${info[origin]}` + if [ -r "packages/${info[origin]}.help" ]; then + info[originhelp]=`sed 's/^/\t /' "packages/${info[origin]}.help"` + else + info[originhelp]="${info[master]} from ${info[origin]}." + fi + + if [ -n "${info[repository]}" ]; then + info[vcs]=${info[repository]%% *} + info[repository_url]=${info[repository]##* } + info[repository_dflt_branch]=${dflt_branch[${info[vcs]}]} + fi + + versions=`cd packages/${fork} && \ + for f in */version.desc; do [ -r "${f}" ] && echo "${f%/version.desc}"; done | \ + sort -rV | xargs echo` + + set_iter version $versions + info[all_versions]=$versions + + only_obsolete=yes + only_experimental=yes + do_foreach version check_obsolete_experimental + info[only_obsolete]=${only_obsolete} + info[only_experimental]=${only_experimental} } -# Generate a single configuration file -gen_one_component() +enter_version() { - local cond - - debug "Entering: gen_one_component $@" - - # Non-masters forks: skip, will be generated along with their master version - if [ "${info[master]}" != "${info[name]}" ]; then - debug "Skip '${info[name]}': master '${info[master]}'" - return - fi - - debug "Generating '${info[name]}.in'${info[forks]:+ (includes ${info[forks]}})" - exec >"${config_dir}/${info[name]}.in" - cat <<EOF -# -# DO NOT EDIT! This file is automatically generated. -# - -EOF - - # Generate fork selection, if there is more than one fork - if [ -n "${info[forks]}" ]; then - cat <<EOF -choice - bool "Show ${info[name]} versions from" -EOF - for_each_package "${info[name]} ${info[forks]}" gen_selection - - cat <<EOF - -endchoice - -EOF - for_each_package "${info[name]} ${info[forks]}" \ - gen_versions '${info[masterpfx]}_USE_${info[originpfx]}' - else - for_each_package "${info[name]}" gen_versions - fi + local version="${1}" + local tmp + + eval `read_version_desc ${info[name]} ${version}` + info[ver]=${version} + info[kcfg]=`kconfigize ${version}` + tmp=" ${info[all_versions]} " + tmp=${tmp##* ${version} } + info[prev]=`kconfigize ${tmp%% *}` } rm -rf "${config_dir}" mkdir -p "${config_dir}" -all_packages=`cd packages && ls */package.desc 2>/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 00000000..7aa0de17 --- /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 |