#!/bin/bash ini() { # # do ini operation # local op=$1 local arg=$2 local fn local limit=_ini_cat case $op in lskeys) fn=_ini_lskeys ;; sec) fn=_ini_grepsec ;; values) fn=_ini_greppath ;; 1value) fn=_ini_greppath; limit="tail -1" ;; *) die "incorrect use of \`ini()\`" esac cat $MKIT_INI | $fn $arg | $limit } _ini_cat() { # # A no-op for text stream # while read line; do printf -- "%s\n" "$line" done } _ini_expand() { # # Expand reference value (prefix only) # local line suffix ref value while read line; # [foo:bar]/path do suffix="${line#\[*\]}" # /path ref="${line%$suffix}" # [foo:bar] ref="${ref%\]}" # [foo:bar ref="${ref#\[}" # foo:bar value="$(ini 1value "$ref")" # foo_bar_value printf -- "%s\n" "$value$suffix" # foo_bar_value/path done } _ini_grepkey() { # # Read key from a section # local wnt=$1 grep '.' \ | grep -v '\s*#' \ | sed -e 's/ *= */=/; s/ +$//; s/^//;' \ | grep -e "^$wnt=" \ | cut -d= -f2- \ | _ini_maybe_expand } _ini_greppath() { # # Read key from the right section # # E.g. `files:share:my/lib.sh` should read # # [files:share] # my/lib.sh = proj/my/lib.sh # local wnt=$1 local wntkey=${wnt##*:} local wntsec=${wnt%:$wntkey} if test "$wntsec" = 'ENV'; then local override="${!wntkey}" if test -n "$override"; then echo "$override" return fi fi _ini_grepsec $wntsec | _ini_grepkey $wntkey } _ini_grepsec() { # # Read one INI section # local wnt=$1 local ok=false grep '.' \ | grep -v '\s*#' \ | while read line; do case "$line" in \[$wnt\]) ok=true; continue ;; \[*\]) ok=false; continue ;; esac $ok || continue printf -- "%s\n" "$line" done \ | sed -e 's/ *= */=/; s/ +$//; s/^//;' } _ini_lskeys() { # # List keys from a section # local sct=$1 _ini_grepsec $sct | cut -d= -f1 | sort | uniq } _ini_maybe_expand() { # # Decide whether or not to expand # if test $MKIT_INI_EXPAND -gt 0; then MKIT_INI_EXPAND=$(( $MKIT_INI_EXPAND - 1 )) _ini_expand else _ini_cat fi }