summaryrefslogtreecommitdiff
path: root/maintainer
diff options
context:
space:
mode:
authorAlexey Neyman <stilor@att.net>2017-05-10 02:10:42 (GMT)
committerAlexey Neyman <stilor@att.net>2017-07-08 17:56:29 (GMT)
commitd589df4ebebdd9e89a66dc788e23b3c3db5f23d5 (patch)
treee31e38f9fcbaf470cc01e2de20ef2a3dfe11e24e /maintainer
parent2c615fa62c47c324adfd91cde7a68bd06b6164d5 (diff)
Switch to template-based approach
Signed-off-by: Alexey Neyman <stilor@att.net>
Diffstat (limited to 'maintainer')
-rwxr-xr-xmaintainer/gen-versions.sh501
-rw-r--r--maintainer/kconfig-versions.template129
2 files changed, 391 insertions, 239 deletions
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 <<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 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