config 4.8 KB

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