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