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