linux/scripts/config
<<
>>
Prefs
   1#!/usr/bin/env bash
   2# SPDX-License-Identifier: GPL-2.0
   3# Manipulate options in a .config file from the command line
   4
   5myname=${0##*/}
   6
   7# If no prefix forced, use the default CONFIG_
   8CONFIG_="${CONFIG_-CONFIG_}"
   9
  10# We use an uncommon delimiter for sed substitutions
  11SED_DELIM=$(echo -en "\001")
  12
  13usage() {
  14        cat >&2 <<EOL
  15Manipulate options in a .config file from the command line.
  16Usage:
  17$myname options command ...
  18commands:
  19        --enable|-e option   Enable option
  20        --disable|-d option  Disable option
  21        --module|-m option   Turn option into a module
  22        --set-str option string
  23                             Set option to "string"
  24        --set-val option value
  25                             Set option to value
  26        --undefine|-u option Undefine option
  27        --state|-s option    Print state of option (n,y,m,undef)
  28
  29        --enable-after|-E beforeopt option
  30                             Enable option directly after other option
  31        --disable-after|-D beforeopt option
  32                             Disable option directly after other option
  33        --module-after|-M beforeopt option
  34                             Turn option into module directly after other option
  35
  36        commands can be repeated multiple times
  37
  38options:
  39        --file config-file   .config file to change (default .config)
  40        --keep-case|-k       Keep next symbols' case (dont' upper-case it)
  41
  42$myname doesn't check the validity of the .config file. This is done at next
  43make time.
  44
  45By default, $myname will upper-case the given symbol. Use --keep-case to keep
  46the case of all following symbols unchanged.
  47
  48$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
  49variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
  50EOL
  51        exit 1
  52}
  53
  54checkarg() {
  55        ARG="$1"
  56        if [ "$ARG" = "" ] ; then
  57                usage
  58        fi
  59        case "$ARG" in
  60        ${CONFIG_}*)
  61                ARG="${ARG/${CONFIG_}/}"
  62                ;;
  63        esac
  64        if [ "$MUNGE_CASE" = "yes" ] ; then
  65                ARG="`echo $ARG | tr a-z A-Z`"
  66        fi
  67}
  68
  69txt_append() {
  70        local anchor="$1"
  71        local insert="$2"
  72        local infile="$3"
  73        local tmpfile="$infile.swp"
  74
  75        # sed append cmd: 'a\' + newline + text + newline
  76        cmd="$(printf "a\\%b$insert" "\n")"
  77
  78        sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
  79        # replace original file with the edited one
  80        mv "$tmpfile" "$infile"
  81}
  82
  83txt_subst() {
  84        local before="$1"
  85        local after="$2"
  86        local infile="$3"
  87        local tmpfile="$infile.swp"
  88
  89        sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
  90        # replace original file with the edited one
  91        mv "$tmpfile" "$infile"
  92}
  93
  94txt_delete() {
  95        local text="$1"
  96        local infile="$2"
  97        local tmpfile="$infile.swp"
  98
  99        sed -e "/$text/d" "$infile" >"$tmpfile"
 100        # replace original file with the edited one
 101        mv "$tmpfile" "$infile"
 102}
 103
 104set_var() {
 105        local name=$1 new=$2 before=$3
 106
 107        name_re="^($name=|# $name is not set)"
 108        before_re="^($before=|# $before is not set)"
 109        if test -n "$before" && grep -Eq "$before_re" "$FN"; then
 110                txt_append "^$before=" "$new" "$FN"
 111                txt_append "^# $before is not set" "$new" "$FN"
 112        elif grep -Eq "$name_re" "$FN"; then
 113                txt_subst "^$name=.*" "$new" "$FN"
 114                txt_subst "^# $name is not set" "$new" "$FN"
 115        else
 116                echo "$new" >>"$FN"
 117        fi
 118}
 119
 120undef_var() {
 121        local name=$1
 122
 123        txt_delete "^$name=" "$FN"
 124        txt_delete "^# $name is not set" "$FN"
 125}
 126
 127if [ "$1" = "--file" ]; then
 128        FN="$2"
 129        if [ "$FN" = "" ] ; then
 130                usage
 131        fi
 132        shift 2
 133else
 134        FN=.config
 135fi
 136
 137if [ "$1" = "" ] ; then
 138        usage
 139fi
 140
 141MUNGE_CASE=yes
 142while [ "$1" != "" ] ; do
 143        CMD="$1"
 144        shift
 145        case "$CMD" in
 146        --keep-case|-k)
 147                MUNGE_CASE=no
 148                continue
 149                ;;
 150        --refresh)
 151                ;;
 152        --*-after|-E|-D|-M)
 153                checkarg "$1"
 154                A=$ARG
 155                checkarg "$2"
 156                B=$ARG
 157                shift 2
 158                ;;
 159        -*)
 160                checkarg "$1"
 161                shift
 162                ;;
 163        esac
 164        case "$CMD" in
 165        --enable|-e)
 166                set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
 167                ;;
 168
 169        --disable|-d)
 170                set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set"
 171                ;;
 172
 173        --module|-m)
 174                set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m"
 175                ;;
 176
 177        --set-str)
 178                # sed swallows one level of escaping, so we need double-escaping
 179                set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\""
 180                shift
 181                ;;
 182
 183        --set-val)
 184                set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
 185                shift
 186                ;;
 187        --undefine|-u)
 188                undef_var "${CONFIG_}$ARG"
 189                ;;
 190
 191        --state|-s)
 192                if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
 193                        echo n
 194                else
 195                        V="$(grep "^${CONFIG_}$ARG=" $FN)"
 196                        if [ $? != 0 ] ; then
 197                                echo undef
 198                        else
 199                                V="${V/#${CONFIG_}$ARG=/}"
 200                                V="${V/#\"/}"
 201                                V="${V/%\"/}"
 202                                V="${V//\\\"/\"}"
 203                                echo "${V}"
 204                        fi
 205                fi
 206                ;;
 207
 208        --enable-after|-E)
 209                set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A"
 210                ;;
 211
 212        --disable-after|-D)
 213                set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A"
 214                ;;
 215
 216        --module-after|-M)
 217                set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
 218                ;;
 219
 220        # undocumented because it ignores --file (fixme)
 221        --refresh)
 222                yes "" | make oldconfig
 223                ;;
 224
 225        *)
 226                echo "bad command: $CMD" >&2
 227                usage
 228                ;;
 229        esac
 230done
 231