summaryrefslogtreecommitdiffstats
path: root/init_functions
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2016-07-06 13:22:16 +0200
committerDave Reisner <dreisner@archlinux.org>2016-07-07 14:30:59 +0200
commitb9308a5296fc0dc8da78cd6f02a5af9c38f0a044 (patch)
treeecfa5b08409b65424cdcf4a063bc0d33fecbd5c2 /init_functions
parenta089c8622708d5249aa7830590464fb29dc799a4 (diff)
downloadmkinitcpio-b9308a5296fc0dc8da78cd6f02a5af9c38f0a044.tar.gz
mkinitcpio-b9308a5296fc0dc8da78cd6f02a5af9c38f0a044.tar.xz
refactor parse_cmdline into something more readable
This refactors parse_cmdline into a few chunks of code, mainly to separate the work of parsing from the handling of the actual parsed parameters. By default, parse_cmdline_item is used as the callback for handling the parameters, but this could be overriden by other code sourcing init_functions if desirable. Our test harness passes more tests, but we leave behind some expected failures to describe the cases where it still fails. Fortunately I've not yet been able to find any cases which warrant --expect-parse-fail.
Diffstat (limited to 'init_functions')
-rw-r--r--init_functions175
1 files changed, 117 insertions, 58 deletions
diff --git a/init_functions b/init_functions
index 05f4ab0..d5a584e 100644
--- a/init_functions
+++ b/init_functions
@@ -114,74 +114,133 @@ set_log_option() {
done
}
-parse_cmdline() {
- local _w _quoted _lhs _rhs _cmdline
- read -r _cmdline
- for _w in $_cmdline; do
- if [ -z "$_quoted" ]; then
- case $_w in
- # ignore everything after a # in the commandline
- \#*) break ;;
- # special cases
- rw|ro) rwopt=$_w ;;
- fstype) rootfstype=$_w ;;
- fsck.mode=*)
- case ${_w#*=} in
- force)
- forcefsck=y
- ;;
- skip)
- fastboot=y
- ;;
- *)
- err "unknown fsck.mode parameter: '${_w#*=}'"
- ;;
- esac
+startswith() {
+ local word=$1 prefix=$2
+
+ case $word in
+ $prefix*)
+ return 0
+ ;;
+ esac
+
+ return 1
+}
+
+endswith() {
+ local word=$1 suffix=$2
+
+ case $word in
+ *$suffix)
+ return 0
+ ;;
+ esac
+
+ return 1
+}
+
+parse_cmdline_item() {
+ local key=$1 value=$2
+
+ case $key in
+ rw|ro)
+ rwopt=$key
+ ;;
+ fstype)
+ # The kernel understands 'rootfstype', but mkinitcpio has (without
+ # documentation) supported 'fstype' instead. Ensure we support both
+ # for backwards compat, but make fstype legacy.
+ rootfstype=$value
+ ;;
+ fsck.mode)
+ case $value in
+ force)
+ forcefsck=y
;;
- rd.*)
- case ${_w#rd.} in
- debug)
- rd_debug=y
- ;;
- log)
- rd_logmask=$(( _rdlog_kmsg | _rdlog_cons ))
- ;;
- log=*)
- set_log_option "${_w#rd.log=}"
- ;;
- esac
+ skip)
+ fastboot=y
;;
- # abide by shell variable naming rules
- [[:alpha:]_]*=*)
- _rhs=${_w#*=}
- _lhs=${_w%%=*}
- _lhs=${_lhs//[-.]/_}
- if [ '"' = "${_rhs:0:1}" ]; then
- if [ '"' = "${_rhs:$((${#_rhs}-1))}" ]; then
- _rhs="${_rhs:1:$((${#_rhs}-2))}"
- else
- _rhs=${_rhs:1}
- _quoted=1
- continue
- fi
+ *)
+ err "unknown fsck.mode parameter: '$value'"
+ ;;
+ esac
+ ;;
+ rd.debug)
+ rd_debug=y
+ ;;
+ rd.log)
+ if [ -n "$value" ]; then
+ set_log_option "$value"
+ else
+ rd_logmask=$(( _rdlog_kmsg | _rdlog_cons ))
+ fi
+ ;;
+ [![:alpha:]_]*|[[:alpha:]_]*[![:alnum:]_]*)
+ # invalid shell variable, ignore it
+ ;;
+ *)
+ # valid shell variable
+ eval "$key"='${value:-y}'
+ ;;
+ esac
+}
+
+process_cmdline_param() {
+ local item_callback=$1 key=$2 value=$3
+
+ # maybe unquote the value
+ if startswith "$value" "[\"']" && endswith "$value" "${value:0:1}"; then
+ value=${value#?} value=${value%?}
+ fi
+
+ "$item_callback" "$key" "$value"
+}
+
+parse_cmdline() {
+ local item_callback=${1:-parse_cmdline_item}
+ local cmdline word quoted key value
+
+ set -f
+ read -r cmdline
+ set -- $cmdline
+ set +f
+
+ for word; do
+ if [ -n "$quoted" ]; then
+ value="$value $word"
+ else
+ case $word in
+ *=*)
+ key=${word%%=*}
+ value=${word#*=}
+
+ if startswith "$value" "[\"']"; then
+ quoted=${value:0:1}
fi
- eval $_lhs=\$_rhs
;;
- [[:alpha:]_]*)
- _lhs=${_w//[-.]/_}
- eval $_lhs=y
+ '#'*)
+ break
+ ;;
+ *)
+ key=$word
;;
esac
- else
- if [ '"' = "${_w:$((${#_w}-1))}" ]; then
- _rhs="$_rhs ${_w%\"}"
- unset _quoted
- eval $_lhs=\$_rhs
+ fi
+
+ if [ -n "$quoted" ]; then
+ if endswith "$value" "$quoted"; then
+ unset quoted
else
- _rhs="$_rhs $_w"
+ continue
fi
fi
+
+ process_cmdline_param "$item_callback" "$key" "$value"
+ unset key value
done
+
+ if [ -n "$key" ]; then
+ process_cmdline_param "$item_callback" "$key" "$value"
+ fi
}
fsck_device() {