Back to home page

OSCL-LXR

 
 

    


0001 #!/usr/bin/env bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 # Manipulate options in a .config file from the command line
0004 
0005 myname=${0##*/}
0006 
0007 # If no prefix forced, use the default CONFIG_
0008 CONFIG_="${CONFIG_-CONFIG_}"
0009 
0010 # We use an uncommon delimiter for sed substitutions
0011 SED_DELIM=$(echo -en "\001")
0012 
0013 usage() {
0014         cat >&2 <<EOL
0015 Manipulate options in a .config file from the command line.
0016 Usage:
0017 $myname options command ...
0018 commands:
0019         --enable|-e option   Enable option
0020         --disable|-d option  Disable option
0021         --module|-m option   Turn option into a module
0022         --set-str option string
0023                              Set option to "string"
0024         --set-val option value
0025                              Set option to value
0026         --undefine|-u option Undefine option
0027         --state|-s option    Print state of option (n,y,m,undef)
0028 
0029         --enable-after|-E beforeopt option
0030                              Enable option directly after other option
0031         --disable-after|-D beforeopt option
0032                              Disable option directly after other option
0033         --module-after|-M beforeopt option
0034                              Turn option into module directly after other option
0035 
0036         commands can be repeated multiple times
0037 
0038 options:
0039         --file config-file   .config file to change (default .config)
0040         --keep-case|-k       Keep next symbols' case (dont' upper-case it)
0041 
0042 $myname doesn't check the validity of the .config file. This is done at next
0043 make time.
0044 
0045 By default, $myname will upper-case the given symbol. Use --keep-case to keep
0046 the case of all following symbols unchanged.
0047 
0048 $myname uses 'CONFIG_' as the default symbol prefix. Set the environment
0049 variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
0050 EOL
0051         exit 1
0052 }
0053 
0054 checkarg() {
0055         ARG="$1"
0056         if [ "$ARG" = "" ] ; then
0057                 usage
0058         fi
0059         case "$ARG" in
0060         ${CONFIG_}*)
0061                 ARG="${ARG/${CONFIG_}/}"
0062                 ;;
0063         esac
0064         if [ "$MUNGE_CASE" = "yes" ] ; then
0065                 ARG="`echo $ARG | tr a-z A-Z`"
0066         fi
0067 }
0068 
0069 txt_append() {
0070         local anchor="$1"
0071         local insert="$2"
0072         local infile="$3"
0073         local tmpfile="$infile.swp"
0074 
0075         # sed append cmd: 'a\' + newline + text + newline
0076         cmd="$(printf "a\\%b$insert" "\n")"
0077 
0078         sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
0079         # replace original file with the edited one
0080         mv "$tmpfile" "$infile"
0081 }
0082 
0083 txt_subst() {
0084         local before="$1"
0085         local after="$2"
0086         local infile="$3"
0087         local tmpfile="$infile.swp"
0088 
0089         sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
0090         # replace original file with the edited one
0091         mv "$tmpfile" "$infile"
0092 }
0093 
0094 txt_delete() {
0095         local text="$1"
0096         local infile="$2"
0097         local tmpfile="$infile.swp"
0098 
0099         sed -e "/$text/d" "$infile" >"$tmpfile"
0100         # replace original file with the edited one
0101         mv "$tmpfile" "$infile"
0102 }
0103 
0104 set_var() {
0105         local name=$1 new=$2 before=$3
0106 
0107         name_re="^($name=|# $name is not set)"
0108         before_re="^($before=|# $before is not set)"
0109         if test -n "$before" && grep -Eq "$before_re" "$FN"; then
0110                 txt_append "^$before=" "$new" "$FN"
0111                 txt_append "^# $before is not set" "$new" "$FN"
0112         elif grep -Eq "$name_re" "$FN"; then
0113                 txt_subst "^$name=.*" "$new" "$FN"
0114                 txt_subst "^# $name is not set" "$new" "$FN"
0115         else
0116                 echo "$new" >>"$FN"
0117         fi
0118 }
0119 
0120 undef_var() {
0121         local name=$1
0122 
0123         txt_delete "^$name=" "$FN"
0124         txt_delete "^# $name is not set" "$FN"
0125 }
0126 
0127 if [ "$1" = "--file" ]; then
0128         FN="$2"
0129         if [ "$FN" = "" ] ; then
0130                 usage
0131         fi
0132         shift 2
0133 else
0134         FN=.config
0135 fi
0136 
0137 if [ "$1" = "" ] ; then
0138         usage
0139 fi
0140 
0141 MUNGE_CASE=yes
0142 while [ "$1" != "" ] ; do
0143         CMD="$1"
0144         shift
0145         case "$CMD" in
0146         --keep-case|-k)
0147                 MUNGE_CASE=no
0148                 continue
0149                 ;;
0150         --refresh)
0151                 ;;
0152         --*-after|-E|-D|-M)
0153                 checkarg "$1"
0154                 A=$ARG
0155                 checkarg "$2"
0156                 B=$ARG
0157                 shift 2
0158                 ;;
0159         -*)
0160                 checkarg "$1"
0161                 shift
0162                 ;;
0163         esac
0164         case "$CMD" in
0165         --enable|-e)
0166                 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
0167                 ;;
0168 
0169         --disable|-d)
0170                 set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set"
0171                 ;;
0172 
0173         --module|-m)
0174                 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m"
0175                 ;;
0176 
0177         --set-str)
0178                 # sed swallows one level of escaping, so we need double-escaping
0179                 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\""
0180                 shift
0181                 ;;
0182 
0183         --set-val)
0184                 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
0185                 shift
0186                 ;;
0187         --undefine|-u)
0188                 undef_var "${CONFIG_}$ARG"
0189                 ;;
0190 
0191         --state|-s)
0192                 if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
0193                         echo n
0194                 else
0195                         V="$(grep "^${CONFIG_}$ARG=" $FN)"
0196                         if [ $? != 0 ] ; then
0197                                 echo undef
0198                         else
0199                                 V="${V/#${CONFIG_}$ARG=/}"
0200                                 V="${V/#\"/}"
0201                                 V="${V/%\"/}"
0202                                 V="${V//\\\"/\"}"
0203                                 echo "${V}"
0204                         fi
0205                 fi
0206                 ;;
0207 
0208         --enable-after|-E)
0209                 set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A"
0210                 ;;
0211 
0212         --disable-after|-D)
0213                 set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A"
0214                 ;;
0215 
0216         --module-after|-M)
0217                 set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
0218                 ;;
0219 
0220         # undocumented because it ignores --file (fixme)
0221         --refresh)
0222                 yes "" | make oldconfig
0223                 ;;
0224 
0225         *)
0226                 echo "bad command: $CMD" >&2
0227                 usage
0228                 ;;
0229         esac
0230 done