#!/usr/bin/env bash if [[ "$BASH_VERSION" =~ ^3 ]] { echo 'quinedb requires bash 4!' exit 1 } declare -A db setvar db = ''( ) setvar PREAMBLE = $(cat <<'EOF' #!/usr/bin/env bash if [[ "$BASH_VERSION" =~ ^3 ]]; then echo 'quinedb requires bash 4!' exit 1 fi declare -A db EOF ) setvar POSTAMBLE = $(cat <<'EOF' pr_str () { printf "%q" "$1" } case "$1" in "get") if [ ${db["$2"]+_} ]; then v=${db["$2"]} echo "$(pr_str "$v")" >&2 fi ;; "set") db["$2"]="$3" echo 'OK' >&2 ;; "delete") unset db["$2"] echo 'OK' >&2 ;; "keys") for k in "${!db[@]}"; do echo "$(pr_str "$k")"; done >&2 ;; *) echo "USAGE: quinedb [get k | set k v | delete k | keys]" >&2 ;; esac # print self print_db(){ echo "db=(" i=0 for k in "${!db[@]}"; do escaped_keys[$i]=$(pr_str "$k") i=$((i+1)) done # sort the keys for deterministic printing IFS=$'\n' sorted=($(for l in ${escaped_keys[@]}; do echo $l; done | sort)) unset IFS for k in "${sorted[@]}"; do unescaped=$(eval "echo $k") v=${db["$unescaped"]} echo " [$k]=$(pr_str "$v")" done echo ")" } echo "$PREAMBLE"; echo print_db; echo echo 'PREAMBLE=$(cat <<'\'EOF\' echo "$PREAMBLE" echo EOF echo \); echo echo 'POSTAMBLE=$(cat <<'\'EOF\' echo "$POSTAMBLE" echo EOF echo \); echo echo "$POSTAMBLE" EOF ) proc pr_str { printf "%q" $1 } case (1) { "get" { if test ${db["$2"]+_} { setvar v = ${db["$2"]} echo $(pr_str "$v") >&2 } } "set" { setvar db["$2"]="$3" echo 'OK' >&2 } "delete" { unset db["$2"] echo 'OK' >&2 } "keys" { for k in "${!db[@]}" { echo $(pr_str "$k"); } >&2 } * { echo "USAGE: quinedb [get k | set k v | delete k | keys]" >&2 } } # print self proc print_db { echo "db=(" setvar i = '0' for k in "${!db[@]}" { setvar escaped_keys[$i]=$(pr_str "$k") setvar i = $((i+1)) } # sort the keys for deterministic printing setvar IFS = '$'\n',' sorted = ''($(for l in ${escaped_keys[@]}; do echo $l; done | sort)) unset IFS for k in "${sorted[@]}" { setvar unescaped = $(eval "echo $k") setvar v = ${db["$unescaped"]} echo " [$k]=$(pr_str "$v")" } echo ")" } echo $PREAMBLE; echo print_db; echo echo 'PREAMBLE=$(cat <<''''EOF''' echo $PREAMBLE echo EOF echo ')'; echo echo 'POSTAMBLE=$(cat <<''''EOF''' echo $POSTAMBLE echo EOF echo ')'; echo echo $POSTAMBLE