# This script checks the version of the configuration file and either # alerts the user about the need to run the upgrade, or attempts to # perform such an upgrade. CFGFILE="${1}" . "${CT_LIB_DIR}/scripts/functions" . "${CFGFILE}" # If an old config does not define a version, assume it is 0. This is used # if we run this script on an old full .config file, not restored from a # defconfig. CT_CONFIG_VERSION="${CT_CONFIG_VERSION:-0}" if [ "${CT_CONFIG_VERSION_CURRENT}" == "${CT_CONFIG_VERSION}" ]; then # Nothing to do exit 0 fi if [ -z "${CT_UPGRADECONFIG}" ]; then if [ "${CT_CONFIG_VERSION}" != "0" ]; then oldversion="is version ${CT_CONFIG_VERSION}" else oldversion="has no version" fi cat 2>&1 <&2 } warning() { # $opt comes from the caller echo "WARN ${opt:+:: ${opt} }:: $1" >&2 } error() { # $opt comes from the caller echo " ERR ${opt:+:: ${opt} }:: $1" >&2 exit 1 } warning_if_set() { if is_set; then warning "$@" fi } # When a symbol is replaced with a newer version. If it is a choice and # the replacement existed in the old version as well, add a replacement_for # handler for the other symbol to avoid kconfig warnings. replace() { local newopt="${1}" if is_set; then info "No longer supported; replacing with '${newopt}'". opt="${newopt}" else # Wasn't set; just drop it silently unset opt fi } # Avoid multiple definitions for a symbol when multiple old symbols are folded into one # in a new version. If any of the variable names passed as arguments are set, skip # emitting this variable (which, presumably, is "not set"). replacement_for() { while [ -n "${1}" ]; do if [ -n "${!1}" ]; then unset opt return fi shift done } # Helper: takes ${ln} in the caller's environment and sets ${opt} and ${val} # accordingly. Returns 0 if this line was an option, 1 otherwise. set_opt_and_val() { case "${ln}" in CT_*=*) opt=${ln%%=*} val=${ln#*=} case "${val}" in \"*\") val="${val%\"}" val="${val#\"}" q=\" ;; esac return 0 ;; "# CT_"*" is not set") opt=${ln#* } opt=${opt%% *} return 0 ;; *) ;; esac return 1 } # Main upgrade driver. One version at a time, read line by line, interpret # the options and replace anything that needs replacing. input="${CFGFILE}" while :; do # Purge any possibly stale values unset "${!CT_@}" # Reload the next input so that the upgrade function can rely on other CT_xxx variables, # not just the currently processed variable. . "${input}" v=${CT_CONFIG_VERSION:-0} if [ "${v}" -ge "${MY_CONFIG_VERSION_CURRENT}" ]; then break fi vn=$[ v + 1 ] info "Upgrading v${v} to v${vn}" if [ ! -r "${MY_LIB_DIR}/scripts/upgrade/v${v}" ]; then error "Missing upgrade script for v${v} of the config file" fi unset upgrade . "${MY_LIB_DIR}/scripts/upgrade/v${v}" # First pass: read in the whole file and mark the options mentioned; # it may not be possible to upgrade a defconfig if some non-trivial # option dependencies need to be resolved. We are not interested in # values yet. unset selected_opts declare -A selected_opts while read ln; do if set_opt_and_val; then selected_opts[${opt}]=1 fi done < "${input}" # Second pass: actually upgrade the options. { while read ln; do unset opt unset val q= if set_opt_and_val; then case "${opt}" in CT_CONFIG_VERSION_CURRENT|CT_CONFIG_VERSION) continue ;; esac else echo "${ln}" fi upgrade # Emit the option(s) if [ x${opt+set} = x ]; then continue elif [ x${val+set} = x ]; then echo "# ${opt} is not set" else echo "${opt}=${q}${val}${q}" fi done echo "CT_CONFIG_VERSION=\"${vn}\"" echo "CT_CONFIG_VERSION_CURRENT=\"${CT_CONFIG_VERSION_CURRENT}\"" } < "${input}" > "${CFGFILE}.${vn}" unset opt v=${vn} rm -f "${input}" input="${CFGFILE}.${vn}" # Ideally, we'd do 'ct-ng olddefconfig' after each step with the appropriate # Kconfig so that the next step would be able to use auto-set values from the # previous step. However, that would require us to keep archived config/ trees # from every config file version, which is not practical. So, I decided to defer # this until it is actually needed. Even then, it is probably sufficient to only # keep the versions where there is such a dependency. done mv "${CFGFILE}.${MY_CONFIG_VERSION_CURRENT}" "${CFGFILE}"