menu_functions 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. # Auxiliary functions for menu system for custom build system
  2. # Copyright (c) 2002 Serge van den Boom
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. MENU_ITEM_TYPES="MENU CHOICE INPUT"
  18. MENU_ITEM_TYPE_MENU_INIT=menu_init_menu
  19. MENU_ITEM_TYPE_MENU_PRINT_VALUE=menu_print_value_menu
  20. MENU_ITEM_TYPE_MENU_HANDLER=menu_handle_menu
  21. MENU_ITEM_TYPE_MENU_SAVE=menu_save_menu
  22. MENU_ITEM_TYPE_MENU_PROCESS=menu_process_menu
  23. MENU_ITEM_TYPE_CHOICE_INIT=menu_init_choice
  24. MENU_ITEM_TYPE_CHOICE_PRINT_VALUE=menu_print_value_choice
  25. MENU_ITEM_TYPE_CHOICE_HANDLER=menu_handle_choice
  26. MENU_ITEM_TYPE_CHOICE_SAVE=menu_save_choice
  27. MENU_ITEM_TYPE_CHOICE_PROCESS=menu_process_choice
  28. MENU_ITEM_TYPE_INPUT_INIT=menu_init_input
  29. MENU_ITEM_TYPE_INPUT_PRINT_VALUE=menu_print_value_input
  30. MENU_ITEM_TYPE_INPUT_HANDLER=menu_handle_input
  31. MENU_ITEM_TYPE_INPUT_SAVE=menu_save_input
  32. MENU_ITEM_TYPE_INPUT_PROCESS=menu_process_input
  33. # Description: Check if a string can be used as a path.
  34. # No checks are done if the path really exists.
  35. # Arguments: $1 - the string to check
  36. # Returns: 0 if the string makes a valid path
  37. # 1 if the string doesn't make a valid path
  38. # Outputs: the path, possibly modified
  39. validate_path() {
  40. if [ "$1" = "/" ]; then
  41. echo "/"
  42. return
  43. fi
  44. cat << EOF
  45. ${1%/}
  46. EOF
  47. return 0
  48. }
  49. # Description: Initialise a menu, setting unset values to default
  50. # Arguments: $1 - the type of menu item
  51. # $2 - the name of the menu item
  52. menu_init() {
  53. local INIT_FUN
  54. eval INIT_FUN="\$MENU_ITEM_TYPE_$1_INIT"
  55. "$INIT_FUN" "$2"
  56. }
  57. # Description: Initialise this menu
  58. # Arguments: $1 - the name of the menu
  59. menu_init_menu() {
  60. local MENU TEMP_ITEMS ITEM TEMP_TYPE
  61. MENU="$1"
  62. eval TEMP_ITEMS="\$MENU_${MENU}_ITEMS"
  63. for ITEM in $TEMP_ITEMS; do
  64. eval TEMP_TYPE="\$MENU_${MENU}_ITEM_${ITEM}_TYPE"
  65. menu_init "$TEMP_TYPE" "$ITEM"
  66. done
  67. }
  68. # Description: Check if this choice is available
  69. # Arguments: $1 - the name of the choice menu
  70. # $2 - the name of the choice
  71. # Returns: 0 - if the choice is available
  72. # 1 - if the choice is not available
  73. menu_have_choice() {
  74. local MENU CHOICE TEMP_VALID TEMP_PRECOND
  75. MENU="$1"
  76. CHOICE="$2"
  77. eval TEMP_VALID="\$CHOICE_${MENU}_OPTION_${CHOICE}_VALID"
  78. if [ -n "$TEMP_VALID" ]; then
  79. return "$TEMP_VALID"
  80. fi
  81. eval TEMP_PRECOND="\$CHOICE_${MENU}_OPTION_${CHOICE}_PRECOND"
  82. if [ -z "$TEMP_PRECOND" ] || $TEMP_PRECOND; then
  83. eval "CHOICE_${MENU}_OPTION_${CHOICE}_VALID"=0
  84. return 0
  85. fi
  86. eval "CHOICE_${MENU}_OPTION_${CHOICE}_VALID"=1
  87. return 1
  88. }
  89. # Description: Initialise this choice menu
  90. # Arguments: $1 - the name of the choice menu
  91. menu_init_choice() {
  92. local MENU TEMP_VALUE TEMP_DEFAULT TEMP_OPTIONS OPTION TEMP_TITLE
  93. MENU="$1"
  94. eval TEMP_VALUE="\$CHOICE_${MENU}_VALUE"
  95. eval TEMP_DEFAULT="\$CHOICE_${MENU}_DEFAULT"
  96. eval TEMP_OPTIONS="\$CHOICE_${MENU}_OPTIONS"
  97. for OPTION in $TEMP_VALUE $TEMP_DEFAULT $TEMP_OPTIONS; do
  98. if menu_have_choice "$MENU" "$OPTION"; then
  99. eval CHOICE_${MENU}_VALUE="$OPTION"
  100. eval CHOICE_${MENU}_OLD_VALUE="$OPTION"
  101. return
  102. fi
  103. done
  104. eval TEMP_VALUE="\$CHOICE_${MENU}_TITLE"
  105. echo "Error: No option for '$TEMP_VALUE' is available for your system."
  106. exit 1
  107. }
  108. # Description: Initialise this input menu
  109. # Arguments: $1 - the name of the input menu
  110. menu_init_input() {
  111. local MENU TEMP_VALUE TEMP_DEFAULT
  112. MENU="$1"
  113. eval TEMP_VALUE="\$INPUT_${MENU}_VALUE"
  114. if [ -z "$TEMP_VALUE" ]; then
  115. eval TEMP_VALUE="\$INPUT_${MENU}_DEFAULT"
  116. eval INPUT_${MENU}_VALUE="\$TEMP_VALUE"
  117. fi
  118. eval INPUT_${MENU}_OLD_VALUE="\$TEMP_VALUE"
  119. }
  120. # Description: Print the string describing the value of a menu item.
  121. # Arguments: $1 - the type of menu item
  122. # $2 - the name of the menu item
  123. # Outputs: The string describing the value of the menu item
  124. menu_print_value() {
  125. local PRINT_VALUE
  126. eval PRINT_VALUE="\$MENU_ITEM_TYPE_$1_PRINT_VALUE"
  127. "$PRINT_VALUE" "$2"
  128. }
  129. # Description: Print the string describing the value this menu
  130. # Arguments: $1 - the name of the menu item
  131. # Outputs: The string describing the value of this menu
  132. menu_print_value_menu() {
  133. echo "[...]"
  134. }
  135. # Description: Print the string describing the value this choice menu
  136. # Arguments: $1 - the name of the choice menu item
  137. # Outputs: The string describing the value of this choice menu
  138. menu_print_value_choice() {
  139. local TEMP_VALUE TEMP_TITLE
  140. eval TEMP_VALUE="\$CHOICE_$1_VALUE"
  141. eval TEMP_TITLE=\"\$CHOICE_$1_OPTION_${TEMP_VALUE}_TITLE\"
  142. cat << EOF
  143. $TEMP_TITLE
  144. EOF
  145. }
  146. # Description: Print the value of this input menu
  147. # Arguments: $1 - the name of the input menu item
  148. # Outputs: The value of the given input menu
  149. menu_print_value_input() {
  150. local TEMP_VALUE TEMP_TITLE
  151. eval TEMP_VALUE="\$INPUT_$1_VALUE"
  152. cat << EOF
  153. $TEMP_VALUE
  154. EOF
  155. }
  156. # Description: Print the string describing the value of a menu item.
  157. # Arguments: $1 - the type of menu item
  158. # $2 - the name of the menu item
  159. # Outputs: The string describing the value of the menu item
  160. menu_handle() {
  161. local HANDLER
  162. eval HANDLER="\$MENU_ITEM_TYPE_$1_HANDLER"
  163. "$HANDLER" "$2"
  164. }
  165. # Description: Process a menu-type menu item
  166. # Arguments: $1 - The name of the menu
  167. menu_handle_menu() {
  168. local TEMP_ITEMS I CHOICE NUM_ITEMS TEMP_TYPE MENU ITEM TEMP_TITLE
  169. eval TEMP_ITEMS="\$MENU_$1_ITEMS"
  170. MENU="$1"
  171. while :; do
  172. echo
  173. eval TEMP_TITLE="\$MENU_${MENU}_TITLE"
  174. cat << EOF
  175. $ANSI_BOLD-= $TEMP_TITLE =-$ANSI_NORMAL
  176. EOF
  177. I=0
  178. for ITEM in $TEMP_ITEMS; do
  179. I=$(($I + 1))
  180. eval TEMP_TYPE="\$MENU_${MENU}_ITEM_${ITEM}_TYPE"
  181. eval TEMP_TITLE="\$${TEMP_TYPE}_${ITEM}_TITLE"
  182. printf " %i. %-36s %s\n" $I "$TEMP_TITLE" \
  183. "$(menu_print_value $TEMP_TYPE $ITEM)"
  184. done
  185. NUM_ITEMS="$I"
  186. echo
  187. echo "Press a number plus <ENTER> if you want to change something, "
  188. echo -n "or just <ENTER> if everything is ok: "
  189. read CHOICE
  190. # Check if the choice was empty
  191. if [ -z "$CHOICE" ]; then
  192. # We're done
  193. return
  194. fi
  195. # Check if what the user entered was a number
  196. egrep -q "^[0-9]+$" << EOF
  197. $CHOICE
  198. EOF
  199. if [ $? -ne 0 ]; then
  200. echo "Invalid choice."
  201. continue
  202. fi
  203. # Check if the number the user entered if valid
  204. if [ "$CHOICE" -lt 1 -o "$CHOICE" -gt "$NUM_ITEMS" ]; then
  205. echo "Invalid choice."
  206. continue
  207. fi
  208. # Now look up the choice
  209. I=0
  210. for ITEM in $TEMP_ITEMS; do
  211. I=$(($I + 1))
  212. if [ "$I" -eq "$CHOICE" ]; then
  213. eval TEMP_TYPE="\$MENU_${MENU}_ITEM_${ITEM}_TYPE"
  214. menu_handle "$TEMP_TYPE" "$ITEM"
  215. break
  216. fi
  217. done
  218. done
  219. }
  220. # Description: Process a choice-type menu item
  221. # Arguments: $1 - The name of the menu
  222. menu_handle_choice() {
  223. local TEMP_OPTIONS I CHOICE NUM_OPTIONS TEMP_TYPE MENU OPTION \
  224. TEMP_VALUE TEMP_TITLE SELECTED
  225. eval TEMP_OPTIONS="\$CHOICE_$1_OPTIONS"
  226. MENU="$1"
  227. while :; do
  228. echo
  229. eval TEMP_TITLE="\$CHOICE_${MENU}_TITLE"
  230. cat << EOF
  231. $ANSI_BOLD-= $TEMP_TITLE =-$ANSI_NORMAL
  232. EOF
  233. eval TEMP_VALUE="\$CHOICE_${MENU}_VALUE"
  234. # Check in advance which options are present, so that that
  235. # is echoed before the menu is printed.
  236. # menu_have_choice caches results.
  237. # Also, count the number of options
  238. I=0
  239. for OPTION in $TEMP_OPTIONS; do
  240. menu_have_choice "$MENU" "$OPTION"
  241. done
  242. NUM_OPTIONS="$I"
  243. I=0
  244. for OPTION in $TEMP_OPTIONS; do
  245. I=$(($I + 1))
  246. eval TEMP_TITLE="\$CHOICE_${MENU}_OPTION_${OPTION}_TITLE"
  247. if [ "$TEMP_VALUE" = "$OPTION" ]; then
  248. SELECTED="-->"
  249. else
  250. SELECTED=" "
  251. fi
  252. if menu_have_choice "$MENU" "$OPTION"; then
  253. printf " %*i. %s %s\n" "${#NUM_OPTIONS}" "$I" \
  254. "$SELECTED" "$TEMP_TITLE"
  255. else
  256. printf " %-*s %s (N/A) %s\n" "${#NUM_OPTIONS}" "-" \
  257. "$SELECTED" "$TEMP_TITLE"
  258. fi
  259. done
  260. echo
  261. echo "Select the option you want by typing a number plus <ENTER>"
  262. echo -n "or just <ENTER> if everything is ok: "
  263. read CHOICE
  264. echo
  265. # Check if the choice was empty
  266. if [ -z "$CHOICE" ]; then
  267. # We're done
  268. return
  269. fi
  270. # Check if what the user entered was a number
  271. egrep -q "^[0-9]+$" << EOF
  272. $CHOICE
  273. EOF
  274. if [ $? -ne 0 ]; then
  275. echo "Invalid choice."
  276. continue
  277. fi
  278. # Check if the number the user entered if valid
  279. if [ "$CHOICE" -lt 1 -o "$CHOICE" -gt "$NUM_ITEMS" ]; then
  280. echo "Invalid choice."
  281. continue
  282. fi
  283. # Now look up the choice
  284. I=0
  285. for OPTION in $TEMP_OPTIONS; do
  286. I=$(($I + 1))
  287. if [ "$I" -eq "$CHOICE" ]; then
  288. if menu_have_choice "$MENU" "$OPTION"; then
  289. eval "CHOICE_${MENU}_VALUE"="$OPTION"
  290. return
  291. else
  292. echo "That option is unavailable on your system."
  293. fi
  294. fi
  295. done
  296. done
  297. }
  298. # Description: Process an input-type menu item
  299. # Arguments: $1 - The name of the menu
  300. menu_handle_input() {
  301. local ITEM TEMP_TITLE TEMP_VALUE TEMP_DEFAULT NEW_VALUE TEMP_VALIDATOR
  302. ITEM="$1"
  303. eval TEMP_TITLE="\$INPUT_${ITEM}_TITLE"
  304. while :; do
  305. echo
  306. cat << EOF
  307. $ANSI_BOLD-= $TEMP_TITLE =-$ANSI_NORMAL
  308. EOF
  309. eval TEMP_VALUE="\$INPUT_${ITEM}_VALUE"
  310. eval TEMP_DEFAULT="\$INPUT_${ITEM}_DEFAULT"
  311. echo " Default value: $TEMP_DEFAULT"
  312. echo " Current value: $TEMP_VALUE"
  313. echo -n " New value: "
  314. read NEW_VALUE
  315. # If no new value is entered, keep the old one.
  316. if [ -z "$NEW_VALUE" ]; then
  317. return
  318. fi
  319. # If a validator function is present, validate the new value
  320. eval TEMP_VALIDATOR="\$INPUT_${ITEM}_VALIDATOR"
  321. if [ -n "$TEMP_VALIDATOR" ]; then
  322. NEW_VALUE=`$TEMP_VALIDATOR "$NEW_VALUE"`
  323. if [ $? -ne 0 ]; then
  324. echo "Invalid value"
  325. continue
  326. fi
  327. fi
  328. break
  329. done
  330. eval "INPUT_${ITEM}_VALUE"=\"\$NEW_VALUE\"
  331. }
  332. # Description: echo the current state of a menu item in a form that can be
  333. # executed to restore the state.
  334. # Arguments: $1 - the type of menu item
  335. # $2 - the name of the menu item
  336. # Outputs: The string describing the value of the menu item
  337. menu_save() {
  338. local SAVE_FUN
  339. eval SAVE_FUN="\$MENU_ITEM_TYPE_$1_SAVE"
  340. "$SAVE_FUN" "$2"
  341. }
  342. # Description: echo the current state of a menu in a form that can be
  343. # executed to restore the state.
  344. # Arguments: $1 - the name of the menu
  345. # Outputs: The string describing the value of the menu
  346. menu_save_menu() {
  347. local MENU TEMP_ITEMS ITEM TEMP_TYPE
  348. MENU="$1"
  349. eval TEMP_ITEMS="\$MENU_${MENU}_ITEMS"
  350. for ITEM in $TEMP_ITEMS; do
  351. eval TEMP_TYPE="\$MENU_${MENU}_ITEM_${ITEM}_TYPE"
  352. menu_save "$TEMP_TYPE" "$ITEM"
  353. done
  354. }
  355. # Description: echo the current state of a choice menu in a form that can be
  356. # executed to restore the state.
  357. # Arguments: $1 - the name of the choice menu
  358. # Outputs: The string describing the value of the choice menu
  359. menu_save_choice() {
  360. local MENU TEMP_VALUE
  361. MENU="$1"
  362. eval TEMP_VALUE="\$CHOICE_${MENU}_VALUE"
  363. cat << EOF
  364. CHOICE_${MENU}_VALUE='$TEMP_VALUE'
  365. EOF
  366. }
  367. # Description: echo the current state of an input menu in a form that can be
  368. # executed to restore the state.
  369. # Arguments: $1 - the name of the input menu
  370. # Outputs: The string describing the value of the input menu
  371. menu_save_input() {
  372. local MENU TEMP_VALUE
  373. MENU="$1"
  374. eval TEMP_VALUE="\$INPUT_${MENU}_VALUE"
  375. cat << EOF
  376. INPUT_${MENU}_VALUE='$TEMP_VALUE'
  377. EOF
  378. }
  379. # Description: Perform the actions associated with the choice made for a
  380. # menu items.
  381. # Arguments: $1 - the type of menu item
  382. # $2 - the name of the menu item
  383. menu_process() {
  384. local PROCESS_FUN
  385. eval PROCESS_FUN="\$MENU_ITEM_TYPE_$1_PROCESS"
  386. "$PROCESS_FUN" "$2"
  387. }
  388. # Description: Perform the actions associated with the chosen menu items
  389. # for a menu.
  390. # Arguments: $1 - the name of the menu
  391. menu_process_menu() {
  392. local MENU TEMP_ITEMS ITEM TEMP_TYPE
  393. MENU="$1"
  394. eval TEMP_ITEMS="\$MENU_${MENU}_ITEMS"
  395. for ITEM in $TEMP_ITEMS; do
  396. eval TEMP_TYPE="\$MENU_${MENU}_ITEM_${ITEM}_TYPE"
  397. menu_process "$TEMP_TYPE" "$ITEM"
  398. done
  399. }
  400. # Description: Perform the actions associated with the choice made for
  401. # a choice menu.
  402. # Arguments: $1 - the name of the choice menu
  403. menu_process_choice() {
  404. local MENU TEMP_VALUE TEMP_ACTION
  405. MENU="$1"
  406. eval TEMP_VALUE="\$CHOICE_${MENU}_VALUE"
  407. eval TEMP_ACTION="\$CHOICE_${MENU}_OPTION_${TEMP_VALUE}_ACTION"
  408. if [ -n "$TEMP_ACTION" ]; then
  409. $TEMP_ACTION
  410. fi
  411. }
  412. # Description: Perform the actions associated with the input menu.
  413. # Arguments: $1 - the name of the input menu
  414. menu_process_input() {
  415. # Nothing to do
  416. :
  417. }
  418. do_menu() {
  419. if [ -e config.state ]; then
  420. . config.state
  421. fi
  422. menu_init MENU "$@"
  423. menu_handle MENU "$@"
  424. echo
  425. echo "Saving configuration..."
  426. menu_save MENU "$@" > config.state
  427. echo "Propagating configuration..."
  428. menu_process MENU "$@"
  429. echo "Configuration complete."
  430. }