🎉 initial codebase
This commit is contained in:
parent
4b737128d5
commit
0ce81956e2
153
ini.sh
Normal file
153
ini.sh
Normal file
@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# =====================================================
|
||||
# bash-ini v1.0.0 | (c) 2024 DrMaxNix | www.drmaxnix.de
|
||||
# =====================================================
|
||||
|
||||
#
|
||||
# Parse a ini config file.
|
||||
#
|
||||
# @param $1 Path to ini file.
|
||||
# @param $2 (Optional) prefix for output variable names.
|
||||
#
|
||||
ini_parse(){
|
||||
## VALIDATE PATH ##
|
||||
# get from param
|
||||
local path="$1"
|
||||
|
||||
# make sure it is readable
|
||||
if [[ ! -r "$path" ]]; then
|
||||
ini_log_error "Unable to read config file '$path'"
|
||||
fi
|
||||
|
||||
|
||||
## VAR PREFIX ##
|
||||
# get from param or fallback
|
||||
local var_prefix="${2:-ini}"
|
||||
|
||||
# validate format
|
||||
if [[ ! "$var_prefix" =~ ^[a-z0-9]+(_[a-z0-9]+)*$ ]]; then
|
||||
ini_log_error "Invalid variable prefix '$var_prefix'"
|
||||
fi
|
||||
|
||||
# build global var names
|
||||
local -n out_section_list="${var_prefix}"
|
||||
|
||||
|
||||
local line
|
||||
local section_name
|
||||
while IFS= read -r line; do
|
||||
## TRIM WHITESPACES ##
|
||||
line=$(echo "$line" | sed -E "s/^\s*//g" | sed -E "s/\s*$//g")
|
||||
|
||||
|
||||
## IGNORE LINES ##
|
||||
# empty lines
|
||||
if [[ "$line" == "" ]]; then
|
||||
# ignore
|
||||
continue; fi
|
||||
|
||||
# comments
|
||||
if [[ "$line" =~ ^# || "$line" =~ ^\; ]]; then
|
||||
# ignore
|
||||
continue; fi
|
||||
|
||||
|
||||
## MATCH SECTION HEADER ##
|
||||
if [[ "$line" =~ ^\[.*\]$ ]]; then
|
||||
# get section name
|
||||
section_name=$(echo "$line" | sed -E "s/^\[(.*)\]$/\1/g")
|
||||
|
||||
# trim whitespaces
|
||||
section_name=$(echo "$section_name" | sed -E "s/^\s*//g" | sed -E "s/\s*$//g")
|
||||
|
||||
# validate format
|
||||
if [[ ! "$section_name" =~ ^[A-Za-z0-9]+([\._-][A-Za-z0-9]+)*$ ]]; then
|
||||
ini_log_error "Invalid section name '$section_name'"
|
||||
fi
|
||||
|
||||
# rewrite section name
|
||||
section_name=$(echo "$section_name" | tr 'A-Z' 'a-z' | tr '-' '_' | tr '.' '_')
|
||||
|
||||
# maybe add to section list
|
||||
local found="no"
|
||||
for s in ${out_section_list[*]:-}; do
|
||||
if [[ "$s" == "$section_name" ]]; then found="yes"; break; fi
|
||||
done
|
||||
if [[ "$found" != "yes" ]]; then
|
||||
out_section_list=(${out_section_list[@]:-""} "$section_name")
|
||||
fi
|
||||
|
||||
# declare section map
|
||||
section_map_varname="${var_prefix}__${section_name}"
|
||||
declare -g -A ${section_map_varname}
|
||||
continue; fi
|
||||
|
||||
|
||||
## MATCH ASSIGNMENT ##
|
||||
if [[ "$line" =~ ^([A-Za-z0-9]+([\._-][A-Za-z0-9]+)*)[[:space:]\t]*=[[:space:]\t]*(.*)$ ]]; then
|
||||
# maybe enter root section
|
||||
if [[ ! "${section_name:+x}" ]]; then
|
||||
section_name="_root"
|
||||
out_section_list=(${out_section_list[@]:-""} "$section_name")
|
||||
section_map_varname="${var_prefix}__${section_name}"
|
||||
declare -g -A ${section_map_varname}
|
||||
fi
|
||||
|
||||
# get key and value
|
||||
local key=$(echo "$line" | sed -E "s/^([A-Za-z0-9]+([\._-][A-Za-z0-9]+)*)[ \t]*=[ \t]*(.*)$/\1/g")
|
||||
local value=$(echo "$line" | sed -E "s/^([A-Za-z0-9]+([\._-][A-Za-z0-9]+)*)[ \t]*=[ \t]*(.*)$/\3/g")
|
||||
|
||||
# maybe trim quote marks
|
||||
if [[ "$value" =~ ^\".*\"$ ]]; then
|
||||
value=$(echo "$value" | sed -E "s/^\"(.*)\"$/\1/g")
|
||||
elif [[ "$value" =~ ^\'.*\'$ ]]; then
|
||||
value=$(echo "$value" | sed -E "s/^'(.*)'$/\1/g")
|
||||
fi
|
||||
|
||||
# maybe add key to key list
|
||||
local -n out_section_key_list="${var_prefix}__${section_name}__key_list"
|
||||
local found="no"
|
||||
for k in ${out_section_key_list[*]:-}; do
|
||||
if [[ "$k" == "$key" ]]; then found="yes"; break; fi
|
||||
done
|
||||
if [[ "$found" != "yes" ]]; then
|
||||
out_section_key_list=(${out_section_key_list[@]:-""} "$key")
|
||||
fi
|
||||
|
||||
# set value in section map
|
||||
local -n out_section_map="${var_prefix}__${section_name}"
|
||||
out_section_map[$key]="$value"
|
||||
continue; fi
|
||||
|
||||
|
||||
## UNKNOWN ##
|
||||
ini_log_error "Unknown config string '$line'"
|
||||
done < "$path"
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# HELPER: try calling external logger, else use fallback.
|
||||
#
|
||||
# @param $1 Message to print.
|
||||
#
|
||||
ini_log_debug(){
|
||||
if [[ "$(type -t log_debug)" == "function" ]]; then log_debug "$1"; return; fi
|
||||
echo "[DEBUG] $1" 1>&2
|
||||
}
|
||||
ini_log_info(){
|
||||
if [[ "$(type -t log_info)" == "function" ]]; then log_info "$1"; return; fi
|
||||
echo "[INFO ] $1" 1>&2
|
||||
}
|
||||
ini_log_warn(){
|
||||
if [[ "$(type -t log_warn)" == "function" ]]; then log_warn "$1"; return; fi
|
||||
echo "[WARN ] $1" 1>&2
|
||||
}
|
||||
ini_log_error(){
|
||||
if [[ "$(type -t log_error)" == "function" ]]; then log_error "$1"; return; fi
|
||||
echo "[ERROR] $1" 1>&2
|
||||
exit 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user