zrep logo

kekePower/zini

zrep install kekePower/zini

Version: 1.3.0
Back to script

Source code for kekePower/zini

# Description: A Zsh INI reader
# License: GPL-3.0
# Version: 1.3.0
#
# https://github.com/kekePower/zini/
# 
# zini function to parse INI files and store their content in an associative array
zini() {
    local command="${1}"
    local ini_path="${2}"

    # Function to read and display INI file content
    read_ini_file() {
        local ini_path="${1}"
        typeset -gA config  # Global associative array to hold the configuration
        
        if [[ ! -f "${ini_path}" ]]; then
            echo "Configuration file not found: ${ini_path}"
            return 1
        fi

        local current_section=""
        local line key value composite_key

        while IFS= read -r line || [[ -n ${line} ]]; do
            line=$(echo ${line} | xargs)  # Trim whitespace

            [[ -z "${line}" || "${line}" == \;* ]] && continue

            if [[ "${line}" == \[*\]* ]]; then
                current_section="${line:1:-1}"
            else
                key=${line%%=*}
                value=${line#*=}
                key=$(echo ${key} | xargs)  # Trim key
                value=$(echo ${value} | xargs)  # Trim value

                composite_key="${current_section}_${key}"
                config[${composite_key}]="${value}"
            fi
        done < "${ini_path}"
    }

    # Function to update INI file in memory
    update_ini_file() {
        local ini_path="${1}"
        local section="${2}"
        local key_value=("${(@s/=/)3}")  # Split input at '=' into an array
        local key="${key_value[1]}"
        local value="${key_value[2]}"

        if [[ ! -f "${ini_path}" ]]; then
            echo "Configuration file not found: ${ini_path}"
            return 1
        fi

        local in_section=0
        local updated=0
        local new_content=""

        while IFS= read -r line || [[ -n ${line} ]]; do
            if [[ "${line}" == \[${section}\]* ]]; then
                in_section=1
                new_content+="${line}\n"
            elif [[ ${in_section} -eq 1 && "${line}" == \[*\]* ]]; then
                in_section=0
                new_content+="${line}\n"
            elif [[ ${in_section} -eq 1 && "${line}" == ${key}=* ]]; then
                new_content+="${key}=${value}\n"
                updated=1
            else
                new_content+="${line}\n"
            fi
        done < "${ini_path}"

        if [[ ${updated} -eq 0 ]]; then
            if [[ ${in_section} -eq 1 ]]; then
                new_content+="${key}=${value}\n"
            else
                new_content+="[${section}]\n${key}=${value}\n"
            fi
        fi

        echo -e "${new_content}" > "${ini_path}"
    }

    case "${command}" in
        read)
            read_ini_file "${ini_path}"
            ;;
        update)
            local section="${3}"
            local key_value="${4}"
            update_ini_file "${ini_path}" "${section}" "${key_value}"
            ;;
        *)
            echo "Invalid command. Use 'read' or 'update'."
            return 1
            ;;
    esac
}