1
0
mirror of https://github.com/albfan/bash-ini-parser.git synced 2025-06-08 10:21:50 +03:00
bash-ini-parser/bash-ini-parser
2017-12-16 16:25:44 +01:00

199 lines
4.9 KiB
Bash

#
# based on http://theoldschooldevops.com/2008/02/09/bash-ini-parser/
#
PREFIX="cfg_section_"
function debug {
return #abort debug
echo $*
echo --start--
echo "${ini[*]}"
echo --end--
echo
}
function cfg_parser {
shopt -p extglob &> /dev/null
CHANGE_EXTGLOB=$?
if [ $CHANGE_EXTGLOB = 1 ]
then
shopt -s extglob
fi
ini="$(<$1)" # read the file
ini=${ini//$'\r'/} # remove linefeed i.e dos2unix
ini="${ini//[/\\[}" # escape [
debug
ini="${ini//]/\\]}" # escape ]
debug
IFS=$'\n' && ini=( ${ini} ) # convert to line-array
debug
ini=( ${ini[*]//;*/} ) # remove comments with ;
debug
ini=( ${ini[*]/#+([[:space:]])/} ) # remove init whitespace
debug "whitespace around"
ini=( ${ini[*]/*([[:space:]])=*([[:space:]])/=} ) # remove whitespace around =
debug
ini=( ${ini[*]/#\\[/\}$'\n'"$PREFIX"} ) # set section prefix
debug
ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1)
debug
ini=( ${ini[*]/=/=\( } ) # convert item to array
debug
ini=( ${ini[*]/%/ \)} ) # close array parenthesis
debug
ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
debug
ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
debug
ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
ini=( ${ini[*]/%\{/\{$'\n''cfg_unset ${FUNCNAME/#'$PREFIX'}'$'\n'} ) # clean previous definition of section
debug
ini[0]="" # remove first element
debug
ini[${#ini[*]} + 1]='}' # add the last brace
debug
eval "$(echo "${ini[*]}")" # eval the result
EVAL_STATUS=$?
if [ $CHANGE_EXTGLOB = 1 ]
then
shopt -u extglob
fi
return $EVAL_STATUS
}
function cfg_writer {
SECTION=$1
OLDIFS="$IFS"
IFS=' '$'\n'
if [ -z "$SECTION" ]
then
fun="$(declare -F)"
else
fun="$(declare -F $PREFIX$SECTION)"
if [ -z "$fun" ]
then
echo "section $SECTION not found" >2
exit 1
fi
fi
fun="${fun//declare -f/}"
for f in $fun; do
[ "${f#$PREFIX}" == "${f}" ] && continue
item="$(declare -f ${f})"
item="${item##*\{}" # remove function definition
item="${item##*FUNCNAME*$PREFIX\};}" # remove clear section
item="${item/\}}" # remove function close
item="${item%)*}" # remove everything after parenthesis
item="${item});" # add close parenthesis
vars=""
while [ "$item" != "" ]
do
newvar="${item%%=*}" # get item name
vars="$vars $newvar" # add name to collection
item="${item#*;}" # remove readed line
done
eval $f
echo "[${f#$PREFIX}]" # output section
for var in $vars; do
eval 'local length=${#'$var'[*]}' # test if var is an array
if [ $length == 1 ]
then
echo $var=\"${!var}\" #output var
else
echo ";$var is an array" # add comment denoting var is an array
eval 'echo $var=\"${'$var'[*]}\"' # output array var
fi
done
done
IFS="$OLDIFS"
}
function cfg_unset {
SECTION=$1
OLDIFS="$IFS"
IFS=' '$'\n'
if [ -z "$SECTION" ]
then
fun="$(declare -F)"
else
fun="$(declare -F $PREFIX$SECTION)"
if [ -z "$fun" ]
then
echo "section $SECTION not found" >2
return
fi
fi
fun="${fun//declare -f/}"
for f in $fun; do
[ "${f#$PREFIX}" == "${f}" ] && continue
item="$(declare -f ${f})"
item="${item##*\{}" # remove function definition
item="${item##*FUNCNAME*$PREFIX\};}" # remove clear section
item="${item/\}}" # remove function close
item="${item%)*}" # remove everything after parenthesis
item="${item});" # add close parenthesis
vars=""
while [ "$item" != "" ]
do
newvar="${item%%=*}" # get item name
vars="$vars $newvar" # add name to collection
item="${item#*;}" # remove readed line
done
for var in $vars; do
unset $var
done
done
IFS="$OLDIFS"
}
function cfg_clear {
SECTION=$1
OLDIFS="$IFS"
IFS=' '$'\n'
if [ -z "$SECTION" ]
then
fun="$(declare -F)"
else
fun="$(declare -F $PREFIX$SECTION)"
if [ -z "$fun" ]
then
echo "section $SECTION not found" >2
exit 1
fi
fi
fun="${fun//declare -f/}"
for f in $fun; do
[ "${f#$PREFIX}" == "${f}" ] && continue
unset -f ${f}
done
IFS="$OLDIFS"
}
function cfg_update {
SECTION=$1
VAR=$2
OLDIFS="$IFS"
IFS=' '$'\n'
fun="$(declare -F $PREFIX$SECTION)"
if [ -z "$fun" ]
then
echo "section $SECTION not found" >2
exit 1
fi
fun="${fun//declare -f/}"
item="$(declare -f ${fun})"
#item="${item##* $VAR=*}" # remove var declaration
item="${item/\}}" # remove function close
item="${item}
$VAR=(${!VAR})
"
item="${item}
}" # close function again
eval "function $item"
}
# vim: filetype=sh