## INI functions [@bashly-upgrade ini] ## This file is a part of Bashly standard library ## ## Usage: ## ## - In your script, call ‘ini_load path/to/config.ini`. ## - A global associative array named `ini` will become available to you, ## - When updating any of the associative array’s values, call ## ‘ini_save path/to/config.ini` to save the data. ## - INI sections are optional. ## ## Get a value: ## ## ${ini} # for keys under a [section] ## ${ini} # for keys not under a [section] ## ${ini:-default} # get a default value if the INI key is unset ## ## Update/create a value: ## ## ini=“value” ## ini_save path/to/config.ini ## ## Delete a value ## ## unset ini ## ini_save path/to/config.ini ## ## Load an INI file and populate the associative array `ini`. ini_load() {

unset ini
declare -gA ini

local ini_file="$1"

local section=""
local key=""
local value=""
local section_regex="^\[(.+)\]"
local key_regex="^([^ =]+) *= *(.*) *$"
local comment_regex="^;"

while IFS= read -r line; do
  if [[ $line =~ $comment_regex ]]; then
    continue
  elif [[ $line =~ $section_regex ]]; then
    section="${BASH_REMATCH[1]}."
  elif [[ $line =~ $key_regex ]]; then
    key="${BASH_REMATCH[1]}"
    value="${BASH_REMATCH[2]}"
    [[ $value == *\$* ]] && eval "value=\"$value\""
    ini["${section}${key}"]="$value"
  fi
done <"$ini_file"

}

## Save the associative array ‘ini` back to a file ini_save() {

declare -gA ini

local ini_file="$1"

local current_section=""
local has_free_keys=false

rm -f "$ini_file"

for key in $(ini_keys); do
  [[ $key == *.* ]] && continue
  has_free_keys=true
  value="${ini[$key]}"
  echo "$key = $value" >>"$ini_file"
done

[[ "${has_free_keys}" == "true" ]] && echo >>"$ini_file"

for key in $(ini_keys); do
  [[ $key == *.* ]] || continue
  value="${ini[$key]}"
  IFS="." read -r section_name key_name <<<"$key"

  if [[ "$current_section" != "$section_name" ]]; then
    [[ $current_section ]] && echo >>"$ini_file"
    echo "[$section_name]" >>"$ini_file"
    current_section="$section_name"
  fi

  echo "$key_name = $value" >>"$ini_file"
done

}

## Show all loaded key-value pairs ini_show() {

declare -gA ini

for key in $(ini_keys); do
  echo "$key = ${ini[$key]}"
done

}

## Get an array of all keys: ## ## for key in $(ini_keys); do ## echo “- $key = ${ini}”; ## done ## ini_keys() {

declare -gA ini

local keys=("${!ini[@]}")
for a in "${keys[@]}"; do echo "$a"; done | sort

}