feat(package): hemar: antlr grammar, but still does not work
This commit is contained in:
38
package/hemar/parser/default.nix
Normal file
38
package/hemar/parser/default.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{ dash, hectic, symlinkJoin }:
|
||||
let
|
||||
shell = "${dash}/bin/dash";
|
||||
bashOptions = [
|
||||
"errexit"
|
||||
"nounset"
|
||||
];
|
||||
|
||||
test = hectic.writeShellApplication {
|
||||
inherit shell bashOptions;
|
||||
name = "hemar-test";
|
||||
runtimeInputs = [ ];
|
||||
|
||||
text = ''
|
||||
# shellcheck disable=SC2034
|
||||
WORKSPACE=${./.}
|
||||
${builtins.readFile hectic.helpers.posix-shell.log}
|
||||
${builtins.readFile ./test.sh}
|
||||
'';
|
||||
};
|
||||
|
||||
hemar = hectic.writeShellApplication {
|
||||
inherit shell bashOptions;
|
||||
name = "hemar";
|
||||
runtimeInputs = [ ];
|
||||
|
||||
text = ''
|
||||
# shellcheck disable=SC2034
|
||||
WORKSPACE=${./.}
|
||||
${builtins.readFile hectic.helpers.posix-shell.log}
|
||||
${builtins.readFile ./hemar.sh}
|
||||
'';
|
||||
};
|
||||
in
|
||||
symlinkJoin {
|
||||
name = "hemar";
|
||||
paths = [ hemar test ];
|
||||
}
|
||||
472
package/hemar/parser/hemar.sh
Normal file
472
package/hemar/parser/hemar.sh
Normal file
@@ -0,0 +1,472 @@
|
||||
#!/bin/dash
|
||||
|
||||
log notice "running"
|
||||
|
||||
# Syntax scheme:
|
||||
#
|
||||
# hemar
|
||||
# elements
|
||||
#
|
||||
# elements
|
||||
# element
|
||||
# element ws elements
|
||||
#
|
||||
# element
|
||||
# tag
|
||||
# text
|
||||
#
|
||||
# text
|
||||
# text-item
|
||||
# text-item text
|
||||
#
|
||||
# text-item
|
||||
# '0020' . '10FFFF' - '{'
|
||||
# nopatern
|
||||
#
|
||||
# tag
|
||||
# '{[' ws path ws ']}'
|
||||
# '{[' ws loop-statement ws ']}'
|
||||
# '{[' ws include-header ws ']}'
|
||||
# '{[' ws "end" ws ']}'
|
||||
# '{[' ws function ws ']}'
|
||||
# '{[' ws '{[' ws ']}'
|
||||
#
|
||||
# # loop tag
|
||||
# loop-statemant
|
||||
# "for" string "in" path
|
||||
#
|
||||
# # include tag
|
||||
# include-header
|
||||
# "include" path
|
||||
#
|
||||
# # fucntion tag
|
||||
# function
|
||||
# "compute" language function-body
|
||||
# "compute" - function-body
|
||||
#
|
||||
# language
|
||||
# "dash"
|
||||
# "plpgsql"
|
||||
#
|
||||
# function-body
|
||||
# ""
|
||||
# '0020' . '10FFFF', function-body
|
||||
#
|
||||
# function-character
|
||||
# '0020' . '10FFFF' - ']'
|
||||
# ncpatern
|
||||
#
|
||||
# # path
|
||||
# path
|
||||
# "."
|
||||
# segmented-path
|
||||
#
|
||||
# segmented-path
|
||||
# segment
|
||||
# segment "." segmented-path
|
||||
#
|
||||
# segment
|
||||
# string
|
||||
# index
|
||||
#
|
||||
# index
|
||||
# '\' digit
|
||||
# '\' onenine digits
|
||||
# '\' '-' digit
|
||||
# '\' '-' onenine digits
|
||||
#
|
||||
# # types
|
||||
# string
|
||||
# character
|
||||
# character string
|
||||
#
|
||||
# character
|
||||
# '0020' . '10FFFF' - '"' - '\' - '.' - ']'
|
||||
# '\' escape
|
||||
# ncpatern
|
||||
#
|
||||
# escape
|
||||
# '.'
|
||||
# ']}'
|
||||
# '"'
|
||||
# '\'
|
||||
# '/'
|
||||
# 'b'
|
||||
# 'f'
|
||||
# 'n'
|
||||
# 'r'
|
||||
# 't'
|
||||
# 'u' hex hex hex hex
|
||||
# ws
|
||||
#
|
||||
# hex
|
||||
# digit
|
||||
# 'A' . 'F'
|
||||
# 'a' . 'f'
|
||||
#
|
||||
# digits
|
||||
# digit
|
||||
# digit digits
|
||||
#
|
||||
# digit
|
||||
# '0'
|
||||
# onenine
|
||||
#
|
||||
# onenine
|
||||
# '1' . '9'
|
||||
#
|
||||
# # paterns
|
||||
# ws
|
||||
# ""
|
||||
# '\x20' ws
|
||||
# '\x0a' ws
|
||||
# '\x0d' ws
|
||||
# '\x09' ws
|
||||
#
|
||||
# nopatern
|
||||
# '{' '0020' . '10FFFF' - '['
|
||||
#
|
||||
# ncpatern
|
||||
# ']' '0020' . '10FFFF' - '}'
|
||||
|
||||
|
||||
# AST Plex:
|
||||
#
|
||||
# Type = 0..=5
|
||||
#
|
||||
# Text = string # just a text body
|
||||
#
|
||||
# Interpolation = string # path to variable
|
||||
#
|
||||
# Include = string # path to include data
|
||||
#
|
||||
# Section = {
|
||||
# v = string # item variable name for loop
|
||||
# p = string # path to array for iteration
|
||||
# b = [Element] # section body
|
||||
#
|
||||
# }
|
||||
#
|
||||
# End = null
|
||||
#
|
||||
# Compute = {
|
||||
# l = string # programing language
|
||||
# b = string # function body
|
||||
# }
|
||||
#
|
||||
# Element = {
|
||||
# t = Type # element type
|
||||
# b = Text # element body
|
||||
# | Interpolation
|
||||
# | Section
|
||||
# | End
|
||||
# | Include
|
||||
# | Compute
|
||||
# }
|
||||
#
|
||||
# AbstarctSyntaxTree (ATS) = {
|
||||
# e = [Element] # elements array
|
||||
# }
|
||||
AST=$(mktemp)
|
||||
AST_key='.'
|
||||
trap 'rm -f "$AST"' EXIT INT HUP
|
||||
|
||||
yq -o j -i '.' "$AST"
|
||||
|
||||
log debug "AST path: ${WHITE}${AST}"
|
||||
|
||||
# 0 - text
|
||||
# 1 - deside tag type
|
||||
# 2 - interpolation
|
||||
# 3 - section
|
||||
# 4 - include
|
||||
# 5 - compute
|
||||
STAGE=0
|
||||
|
||||
# is_ws(char) -> bool
|
||||
is_ws() {
|
||||
ord=$(printf '%d' "'$1")
|
||||
case $ord in
|
||||
32|10|13|9) # <-> \x20 | \x0a | \x0d | \x09 <-> space | \n | \r | \t
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# remove_last_double_quote(text) -> text
|
||||
remove_last_double_quote() {
|
||||
printf '%s' "$1" | sed 's/\(.*\)"\(.*\)/\1\2/'
|
||||
}
|
||||
|
||||
#buf_read(buf?) -> text
|
||||
buf_read() {
|
||||
local buf
|
||||
if [ ${1+x} ]; then
|
||||
buf=${1}
|
||||
else
|
||||
buf=${CURRENT_STAGE_BUFFER}
|
||||
fi
|
||||
|
||||
cat "$buf"
|
||||
}
|
||||
|
||||
#buf_next()
|
||||
buf_next() {
|
||||
case "$CURRENT_STAGE_BUFFER" in
|
||||
"$STAGE_BUFFER_1")
|
||||
CURRENT_STAGE_BUFFER="$STAGE_BUFFER_2"
|
||||
;;
|
||||
"$STAGE_BUFFER_2")
|
||||
CURRENT_STAGE_BUFFER="$STAGE_BUFFER_3"
|
||||
;;
|
||||
"$STAGE_BUFFER_3")
|
||||
CURRENT_STAGE_BUFFER="$STAGE_BUFFER_4"
|
||||
;;
|
||||
"$STAGE_BUFFER_4")
|
||||
CURRENT_STAGE_BUFFER="$STAGE_BUFFER_1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
buf_reset() {
|
||||
: > "$STAGE_BUFFER_1"
|
||||
: > "$STAGE_BUFFER_2"
|
||||
: > "$STAGE_BUFFER_3"
|
||||
: > "$STAGE_BUFFER_4"
|
||||
|
||||
CURRENT_STAGE_BUFFER="$STAGE_BUFFER_1"
|
||||
}
|
||||
|
||||
STAGE_BUFFER_1="$(mktemp)"
|
||||
STAGE_BUFFER_2="$(mktemp)"
|
||||
STAGE_BUFFER_3="$(mktemp)"
|
||||
STAGE_BUFFER_4="$(mktemp)"
|
||||
CURRENT_STAGE_BUFFER=$STAGE_BUFFER_1
|
||||
trap 'rm -f "$STAGE_BUFFER_1" "$STAGE_BUFFER_2" "$STAGE_BUFFER_3" "$STAGE_BUFFER_4"' EXIT INT HUP
|
||||
log debug "stage buffer 1: ${WHITE}$STAGE_BUFFER_1"
|
||||
log debug "stage buffer 2: ${WHITE}$STAGE_BUFFER_2"
|
||||
log debug "stage buffer 3: ${WHITE}$STAGE_BUFFER_3"
|
||||
log debug "stage buffer 4: ${WHITE}$STAGE_BUFFER_4"
|
||||
|
||||
# json_escape(value) -> str
|
||||
json_escape() {
|
||||
# TODO: escape functionality
|
||||
printf '%s' "${1}" | sed 's/"/\\"/g'
|
||||
}
|
||||
|
||||
# finds close pattern and store the char to the stage buffers separating by spaces
|
||||
find_close_pattern() {
|
||||
local buf char="${1:?}"
|
||||
|
||||
regular_char() {
|
||||
[ ${TAG_ws_started+x} ] && {
|
||||
unset TAG_ws_started
|
||||
if [ "${TAG_first_ws_handled+x}" ]; then
|
||||
buf_next
|
||||
else
|
||||
TAG_first_ws_handled=1
|
||||
fi
|
||||
}
|
||||
printf '%s' "$1" >> "$CURRENT_STAGE_BUFFER"
|
||||
}
|
||||
|
||||
if [ ! "${TAG_close_tag_flag+x}" ] && [ "$char" = ']' ]; then
|
||||
TAG_close_tag_flag=1
|
||||
elif [ "${TAG_close_tag_flag+x}" ]; then
|
||||
unset TAG_close_tag_flag
|
||||
if [ "$char" = '}' ]; then
|
||||
|
||||
log debug "cur buf: $WHITE$(cat "$STAGE_BUFFER_1")"
|
||||
# removes first and last white spaces from the buffer
|
||||
sed -i 's/[[:space:]]$//g' "$CURRENT_STAGE_BUFFER"
|
||||
sed -i 's/^[[:space:]]//g' "$CURRENT_STAGE_BUFFER"
|
||||
|
||||
return 0
|
||||
else
|
||||
regular_char ']'"$char"
|
||||
fi
|
||||
else
|
||||
# shellcheck disable=SC1003
|
||||
case "$char" in
|
||||
'"')
|
||||
if [ "${TAG_escape_flag+x}" ]; then
|
||||
unset TAG_escape_flag
|
||||
else
|
||||
if [ ${TAG_double_quote_flag+x} ]; then
|
||||
unset TAG_double_quote_flag
|
||||
return 1
|
||||
else
|
||||
TAG_double_quote_flag=1
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
'\')
|
||||
if [ "${TAG_escape_flag+x}" ]; then
|
||||
unset TAG_escape_flag
|
||||
else
|
||||
TAG_escape_flag=1
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if [ "${TAG_escape_flag+x}" ]; then
|
||||
if is_ws "$char"; then
|
||||
unset TAG_escape_flag
|
||||
else
|
||||
log error "unexpected char \`$char\` after escape symbol"
|
||||
exit 1
|
||||
fi
|
||||
elif is_ws "$char" && ! [ "${TAG_double_quote_flag+x}" ]; then
|
||||
TAG_ws_started=1
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
regular_char "$char"
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# finds open pattern and stores the char to the STAGE_BUFFER_1
|
||||
find_open_pattern() {
|
||||
local char="${1:?}"
|
||||
if [ ! "${open_tag_flag+x}" ] && [ "$char" = '{' ]; then
|
||||
open_tag_flag=1
|
||||
elif [ "${open_tag_flag+x}" ]; then
|
||||
unset open_tag_flag
|
||||
if [ "$char" = '[' ]; then
|
||||
return 0
|
||||
else
|
||||
printf '{%s' "$char" >> "$CURRENT_STAGE_BUFFER"
|
||||
fi
|
||||
else
|
||||
printf '%s' "$char" >> "$CURRENT_STAGE_BUFFER"
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
parse() {
|
||||
char="$1"
|
||||
|
||||
case "$STAGE" in
|
||||
# Text Stage - save char in STAGE_BUFFER_1 until next tag opens
|
||||
0)
|
||||
if find_open_pattern "$char"; then
|
||||
log debug "open pattern founded"
|
||||
buf=$(cat "$CURRENT_STAGE_BUFFER")
|
||||
yq -o j -i "$AST_key += [{
|
||||
\"type\": \"text\",
|
||||
\"value\": \"$(json_escape "$buf")\"
|
||||
}]" "$AST"
|
||||
|
||||
buf_reset
|
||||
STAGE=1
|
||||
fi
|
||||
;;
|
||||
1)
|
||||
if find_close_pattern "$char"; then
|
||||
case "$(cat "$STAGE_BUFFER_1")" in
|
||||
compute)
|
||||
log error 'compute unimplemented'
|
||||
;;
|
||||
include)
|
||||
log error 'include unimplemented'
|
||||
;;
|
||||
for)
|
||||
path=$STAGE_BUFFER_2
|
||||
|
||||
log error 'for unimplemented'
|
||||
;;
|
||||
end)
|
||||
log error 'end unimplemented'
|
||||
;;
|
||||
'{[')
|
||||
yq -o j -i "$AST_key += [{
|
||||
\"type\": \"text\",
|
||||
\"value\": \"{[\"
|
||||
}]" "$AST"
|
||||
;;
|
||||
*) # interpolation tag
|
||||
buf=$(cat "$STAGE_BUFFER_1")
|
||||
yq -o j -i "$AST_key += [{
|
||||
\"type\": \"interpolation\",
|
||||
\"path\": \"$(json_escape "$buf")\"
|
||||
}]" "$AST"
|
||||
;;
|
||||
esac
|
||||
|
||||
# zero-initialization
|
||||
unset TAG_ws_started TAG_double_quote_flag TAG_escape_flag TAG_first_ws_handled TAG_close_tag_flag
|
||||
|
||||
buf_reset
|
||||
STAGE=1
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
|
||||
;;
|
||||
3)
|
||||
|
||||
;;
|
||||
4)
|
||||
|
||||
;;
|
||||
*)
|
||||
log error "error: ${WHITE}impossible stage"
|
||||
exit 13
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
-c|--compact-output)
|
||||
OUTPUT_ARGS="${OUTPUT_ARGS+$OUTPUT_ARGS }-I=0"
|
||||
shift
|
||||
;;
|
||||
--*|-*)
|
||||
log error "argument $1 does not exists"
|
||||
exit 9
|
||||
;;
|
||||
*)
|
||||
log error "subcommand $1 does not exists"
|
||||
exit 9
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Using dd to read one character at a time
|
||||
input=$(cat)
|
||||
i=1
|
||||
while :; do
|
||||
#log trace "loop"
|
||||
char=$(printf '%s' "$input" | dd bs=1 skip=$((i-1)) count=1 2>/dev/null)
|
||||
[ -z "$char" ] && break
|
||||
|
||||
parse "$char"
|
||||
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
# finish TEXT tag if file ends on it
|
||||
if [ "$STAGE" -eq 0 ]; then
|
||||
if [ "${open_tag_flag+x}" ]; then
|
||||
unset open_tag_flag
|
||||
printf '{' >> "$STAGE_BUFFER_1"
|
||||
fi
|
||||
|
||||
buf=$(cat "$STAGE_BUFFER_1")
|
||||
yq -o j -i "$AST_key += [{
|
||||
\"type\": \"text\",
|
||||
\"value\": \"$(json_escape "$buf")\"
|
||||
}]" "$AST"
|
||||
fi
|
||||
|
||||
# return the output
|
||||
# shellcheck disable=SC2086
|
||||
yq ${OUTPUT_ARGS:-} -o j "$AST"
|
||||
70
package/hemar/parser/src/plex/backend/env_var.sh
Normal file
70
package/hemar/parser/src/plex/backend/env_var.sh
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/bin/dash
|
||||
|
||||
plex_set() {
|
||||
local structname key val regex base esc_key regex esc temp
|
||||
structname=$1 key=$2 val=$3
|
||||
|
||||
# construct regex for ancestors
|
||||
regex="^$key="
|
||||
|
||||
base=$key
|
||||
while expr "$base" : '.*\.' >/dev/null; do
|
||||
base=$(printf '%s\n' "$base" | sed 's/\.[^.]*$//')
|
||||
esc=$(printf '%s\n' "$base" | sed 's/\./\\./g')
|
||||
regex="$regex|^$esc="
|
||||
done
|
||||
|
||||
# add descendants
|
||||
esc_key="$(printf '%s\n' "$key" | sed 's/\./\\./g')"
|
||||
regex="$regex|^${esc_key}\."
|
||||
|
||||
# remove old
|
||||
# <plex>=$(printf '%s\n' "$<plex>" | grep -v -E "$regex")
|
||||
temp="$(eval "printf '%s\\n' \"\$$structname\"" | grep -v -E "$regex")"
|
||||
eval "$structname=\"\$temp\""
|
||||
|
||||
# add new
|
||||
eval "$structname=\$(printf '%s\\n%s=%s\\n' \"\$$structname\" \"\$key\" \"\$val\")"
|
||||
}
|
||||
|
||||
plex_child() {
|
||||
local structname prefix
|
||||
structname=$1 prefix=$2
|
||||
|
||||
eval printf '%s\\n' \"\$"$structname"\" \
|
||||
| grep "^$prefix\." \
|
||||
| sed "s|^$prefix\.||"
|
||||
}
|
||||
|
||||
plex_val() {
|
||||
local structname key
|
||||
structname=$1 key=$2
|
||||
eval printf '%s\n' \"\$"$structname"\" | grep "^$key=" | cut -d= -f2-
|
||||
}
|
||||
|
||||
plex_fetch() {
|
||||
local structname key
|
||||
structname=$1 key=$2
|
||||
if eval printf '%s\\n' \"\$"$structname"\" | grep -q "^$key="; then
|
||||
eval printf '%s\\n' \"\$"$structname"\" | grep "^$key=" | cut -d= -f2-
|
||||
else
|
||||
eval printf '%s\\n' \"\$"$structname"\" | grep "^$key\." | sed "s|^$key\.||"
|
||||
fi
|
||||
}
|
||||
|
||||
plex_push() {
|
||||
local structname prefix val max idx newidx kv
|
||||
structname=${1:?}
|
||||
prefix=${2:?}
|
||||
val=${3:?}
|
||||
|
||||
# find max index
|
||||
max=0
|
||||
for kv in $(plex_fetch "$structname" "$prefix"); do
|
||||
idx=${kv%%=*}
|
||||
[ "$idx" -gt "$max" ] 2>/dev/null && max=$idx
|
||||
done
|
||||
|
||||
newidx=$((max + 1))
|
||||
plex_set "$structname" "$prefix.$newidx" "$val"
|
||||
}
|
||||
50
package/hemar/parser/src/plex/backend/file.sh
Normal file
50
package/hemar/parser/src/plex/backend/file.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/dash
|
||||
|
||||
PLEX_TEMP="$(mktemp -d)"
|
||||
|
||||
#plex_set(name, key, value)
|
||||
plex_set() {
|
||||
local plexfile key val regex base esc_key esc
|
||||
plexfile="${PLEX_TEMP:?}${1:?}" key="${2:?}" val="${3:?}"
|
||||
|
||||
find PLEX_
|
||||
}
|
||||
|
||||
plex_child() {
|
||||
local plexfile key
|
||||
plexfile="${PLEX_TEMP:?}${1:?}" key="${2:?}"
|
||||
|
||||
grep "^$key\." "" | sed "s|^$key\.||"
|
||||
}
|
||||
|
||||
plex_val() {
|
||||
local plexfile key
|
||||
plexfile="${PLEX_TEMP:?}${1:?}" key="${2:?}"
|
||||
grep "^$key=" | cut -d= -f2- "$plexfile"
|
||||
}
|
||||
|
||||
plex_fetch() {
|
||||
local plexfile key temp
|
||||
plexfile="${PLEX_TEMP:?}${1:?}" key="${2:?}"
|
||||
|
||||
if temp="$(grep "^$key=" | cut -d= -f2- "$plexfile")"; then
|
||||
printf '%s' "$temp"
|
||||
else
|
||||
grep "^$key\." "" | sed "s|^$key\.||"
|
||||
fi
|
||||
}
|
||||
|
||||
plex_push() {
|
||||
local plex prefix val max idx newidx kv
|
||||
plex="${1:?}" prefix="${2:?}" val="${3:?}"
|
||||
|
||||
# find max index
|
||||
max=0
|
||||
for kv in $(plex_fetch "$plex" "$prefix"); do
|
||||
idx=${kv%%=*}
|
||||
[ "$idx" -gt "$max" ] 2>/dev/null && max=$idx
|
||||
done
|
||||
|
||||
newidx=$((max + 1))
|
||||
plex_set "$plex" "$prefix.$newidx" "$val"
|
||||
}
|
||||
40
package/hemar/parser/src/plex/backend/yq-go.sh
Normal file
40
package/hemar/parser/src/plex/backend/yq-go.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/dash
|
||||
|
||||
PLEX_TEMP="$(mktemp -d)"
|
||||
trap 'rm -rf $PLEX_TEMP' EXIT
|
||||
|
||||
#plex_set(name, key, value)
|
||||
plex_set() {
|
||||
local plexfile key val
|
||||
plexfile="${PLEX_TEMP:?}/${1:?}.json" key="${2:?}" val="${3:?}"
|
||||
|
||||
touch "$plexfile"
|
||||
|
||||
yq -i ".$key = \"$val\"" "$plexfile"
|
||||
}
|
||||
|
||||
#plex_child(name, key)
|
||||
plex_child() {
|
||||
plex_fetch "${1:?}" "${2:?}"
|
||||
}
|
||||
|
||||
#plex_val(name, key)
|
||||
plex_val() {
|
||||
plex_fetch "${1:?}" "${2:?}"
|
||||
}
|
||||
|
||||
#plex_val(name, key)
|
||||
plex_fetch() {
|
||||
local plexfile key
|
||||
plexfile="${PLEX_TEMP:?}/${1:?}.json" key="${2:?}"
|
||||
|
||||
yq -r ".$key" "$plexfile"
|
||||
}
|
||||
|
||||
#plex_push(name, prefix, val)
|
||||
plex_push() {
|
||||
local plexfile prefix val
|
||||
plexfile="${PLEX_TEMP:?}/${1:?}.json" prefix="${2:?}" val="${3:?}"
|
||||
|
||||
yq -i ".$prefix += [\"$val\"]" "$plexfile"
|
||||
}
|
||||
21
package/hemar/parser/src/plex/plex.sh
Normal file
21
package/hemar/parser/src/plex/plex.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/dash
|
||||
|
||||
init_plex() {
|
||||
local backend
|
||||
backend=${1:?}
|
||||
|
||||
case "$backend" in
|
||||
env)
|
||||
. ${WORKSPACE}/src/plex/backend/env_var.sh
|
||||
;;
|
||||
file)
|
||||
. ${WORKSPACE}/src/plex/backend/file.sh
|
||||
;;
|
||||
yq-go)
|
||||
. ${WORKSPACE}/src/plex/backend/yq-go.sh
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
6
package/hemar/parser/test.sh
Normal file
6
package/hemar/parser/test.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/dash
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
#. "${WORKSPACE:?}/test/plex/jq_backend_time.sh"
|
||||
#. "${WORKSPACE:?}/test/plex/env_backend_time.sh"
|
||||
. "${WORKSPACE:?}/test/plex/jq_backend.sh"
|
||||
112
package/hemar/parser/test/plex/env_backend_time.sh
Normal file
112
package/hemar/parser/test/plex/env_backend_time.sh
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/bin/dash
|
||||
|
||||
. "${WORKSPACE:?}/src/plex/plex.sh"
|
||||
init_plex env
|
||||
|
||||
MY_STRUCT=''
|
||||
|
||||
math() {
|
||||
awk "BEGIN {print $1}"
|
||||
}
|
||||
|
||||
elapsed() {
|
||||
local task time count decrease avg
|
||||
task=$1
|
||||
time=$2
|
||||
count=$3
|
||||
decrease=${4:-0}
|
||||
avg=$(math "$time/$count-$decrease")
|
||||
|
||||
printf '\n[%s]\nelapsed %s seconds\n%s per second\n' \
|
||||
"$task" "$avg" "$(math "1/$avg")" >&2
|
||||
printf '%s' "$avg"
|
||||
}
|
||||
|
||||
set_word_length() {
|
||||
local length
|
||||
length=${1:?}
|
||||
|
||||
# shellcheck disable=SC2183
|
||||
__WORD_OFFSET_PATERN="$(printf '%*s' "$length" | tr ' ' '?')"
|
||||
}
|
||||
|
||||
UNIQ_8_WORDS_COUNT=1000
|
||||
DEFAULT_WORD_LENGTH=8
|
||||
set_word_length "$DEFAULT_WORD_LENGTH"
|
||||
|
||||
randomword() {
|
||||
local length
|
||||
length=${1:-$DEFAULT_WORD_LENGTH}
|
||||
LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c "$length"
|
||||
}
|
||||
|
||||
WORDS=$(randomword $((8 * UNIQ_8_WORDS_COUNT)))
|
||||
|
||||
new_word() {
|
||||
local prefix
|
||||
prefix=${WORDS%"${WORDS#"$__WORD_OFFSET_PATERN"}"}
|
||||
WORDS=${WORDS#"$__WORD_OFFSET_PATERN"}$prefix
|
||||
printf '%s' "$prefix"
|
||||
}
|
||||
|
||||
bench_set() {
|
||||
local task depth count wordtime i start key d end
|
||||
task=$1
|
||||
depth=$2
|
||||
count=$3
|
||||
wordtime=$4
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "$count" ]; do
|
||||
key=$(new_word)
|
||||
if [ "$depth" -gt 1 ]; then
|
||||
d=1
|
||||
while [ "$d" -lt "$depth" ]; do
|
||||
key="$key.$(new_word)"
|
||||
d=$((d + 1))
|
||||
done
|
||||
fi
|
||||
plex_set 'MY_STRUCT' "$key" "$i"
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
elapsed "$task" "$((end - start))" "$count" "$(math "$wordtime*$depth")" >/dev/null
|
||||
}
|
||||
|
||||
DEFAULT_TRIES=1000
|
||||
ACCURATE_TRIES=10000
|
||||
SUPPER_ACCURATE_TRIES=100000
|
||||
|
||||
WORD_CREATE_ACCURACY="$ACCURATE_TRIES"
|
||||
BENCH_ACCURACY="$DEFAULT_TRIES"
|
||||
|
||||
count="$WORD_CREATE_ACCURACY"
|
||||
set_word_length 8
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "${count:?}" ]; do
|
||||
new_word >/dev/null
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
wordtime=$(elapsed 'Word creation' "$((end - start))" "$count")
|
||||
|
||||
bench_set 'Set element with depth 1 length 8' 1 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 2 length 8' 2 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 3 length 8' 3 "$BENCH_ACCURACY" "$wordtime"
|
||||
|
||||
count="$WORD_CREATE_ACCURACY"
|
||||
set_word_length 2
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "${count:?}" ]; do
|
||||
new_word >/dev/null
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
wordtime=$(elapsed 'Word creation' "$((end - start))" "$count")
|
||||
|
||||
bench_set 'Set element with depth 1 length 2' 1 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 2 length 2' 2 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 3 length 2' 3 "$BENCH_ACCURACY" "$wordtime"
|
||||
|
||||
19
package/hemar/parser/test/plex/jq_backend.sh
Normal file
19
package/hemar/parser/test/plex/jq_backend.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
. "${WORKSPACE:?}/src/plex/plex.sh"
|
||||
init_plex yq-go
|
||||
|
||||
plex_set ZALUPA zalupa apulaz
|
||||
log error "struct:\n$WHITE$(yq . "$PLEX_TEMP/ZALUPA.json")$NC"
|
||||
|
||||
plex_set ZALUPA kek.zalupa apulaz
|
||||
|
||||
log error "struct:\n$WHITE$(yq . "$PLEX_TEMP/ZALUPA.json")$NC"
|
||||
|
||||
plex_set ZALUPA zalupa apulaz
|
||||
|
||||
log error "struct:\n$WHITE$(yq . "$PLEX_TEMP/ZALUPA.json")$NC"
|
||||
|
||||
plex_val ZALUPA zalupa
|
||||
|
||||
plex_child ZALUPA kek
|
||||
|
||||
plex_fetch ZALUPA kek
|
||||
128
package/hemar/parser/test/plex/jq_backend_time.sh
Normal file
128
package/hemar/parser/test/plex/jq_backend_time.sh
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/bin/dash
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "${WORKSPACE:?}/src/plex/plex.sh"
|
||||
init_plex yq-go
|
||||
|
||||
math() {
|
||||
awk "BEGIN {print $1}"
|
||||
}
|
||||
|
||||
elapsed() {
|
||||
local task time count decrease avg
|
||||
task=$1
|
||||
time=$2
|
||||
count=$3
|
||||
decrease=${4:-0}
|
||||
avg=$(math "$time/$count-$decrease")
|
||||
|
||||
if [ "$time" -eq 0 ]; then
|
||||
log info "\n[$WHITE${task}$NC]\ninstant\n"
|
||||
else
|
||||
log info "\n[$WHITE${task}$NC]\nelapsed $WHITE${avg}$NC seconds\n$WHITE$(math "1/$avg")$NC per second\n"
|
||||
fi
|
||||
printf '%s' "$avg"
|
||||
}
|
||||
|
||||
set_word_length() {
|
||||
local length
|
||||
length=${1:?}
|
||||
|
||||
# shellcheck disable=SC2183
|
||||
__WORD_OFFSET_PATERN="$(printf '%*s' "$length" | tr ' ' '?')"
|
||||
}
|
||||
|
||||
UNIQ_8_WORDS_COUNT=1000
|
||||
DEFAULT_WORD_LENGTH=8
|
||||
set_word_length "$DEFAULT_WORD_LENGTH"
|
||||
|
||||
randomword() {
|
||||
local length
|
||||
length=${1:-$DEFAULT_WORD_LENGTH}
|
||||
LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c "$length"
|
||||
}
|
||||
|
||||
WORDS=$(randomword $((8 * UNIQ_8_WORDS_COUNT)))
|
||||
WORDS=0123456789abcdefg
|
||||
|
||||
new_word() {
|
||||
local prefix
|
||||
# shellcheck disable=SC2295
|
||||
prefix=${WORDS%"${WORDS#${__WORD_OFFSET_PATERN:?}}"}
|
||||
# shellcheck disable=SC2295
|
||||
WORDS=${WORDS#${__WORD_OFFSET_PATERN:?}}$prefix
|
||||
printf '%s' "$prefix"
|
||||
}
|
||||
|
||||
bench_set() {
|
||||
local task depth count wordtime i start key d end
|
||||
task=$1
|
||||
depth=$2
|
||||
count=$3
|
||||
wordtime=$4
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "$count" ]; do
|
||||
key=$(new_word)
|
||||
if [ "$depth" -gt 1 ]; then
|
||||
d=1
|
||||
while [ "$d" -lt "$depth" ]; do
|
||||
key="$key.$(new_word)"
|
||||
d=$((d + 1))
|
||||
done
|
||||
fi
|
||||
set +e
|
||||
plex_set 'MY_STRUCT' "$key" "$i"
|
||||
error_code=$?
|
||||
set -e
|
||||
if [ $error_code != 0 ]; then
|
||||
log error "key: $WHITE$key$NC, i: $WHITE$i$NC, struct: $WHITE$(jq . "$PLEX_TEMP/MY_STRUCT")$NC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
elapsed "$task" "$((end - start))" "$count" "$(math "$wordtime*$depth")" >/dev/null
|
||||
}
|
||||
|
||||
DEFAULT_TRIES=1000
|
||||
ACCURATE_TRIES=10000
|
||||
SUPPER_ACCURATE_TRIES=100000
|
||||
|
||||
WORD_CREATE_ACCURACY="$SUPPER_ACCURATE_TRIES"
|
||||
BENCH_ACCURACY="$DEFAULT_TRIES"
|
||||
|
||||
count="$WORD_CREATE_ACCURACY"
|
||||
set_word_length 8
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "${count:?}" ]; do
|
||||
new_word >/dev/null
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
time=$((end - start))
|
||||
log debug "word creation time: $time"
|
||||
wordtime=$(elapsed 'Word creation' "$time" "$count")
|
||||
|
||||
bench_set 'Set element with depth 1 length 8' 1 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 2 length 8' 2 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 3 length 8' 3 "$BENCH_ACCURACY" "$wordtime"
|
||||
|
||||
log notice -
|
||||
|
||||
count="$WORD_CREATE_ACCURACY"
|
||||
set_word_length 2
|
||||
i=0
|
||||
start=$(date +%s)
|
||||
while [ "$i" -lt "${count:?}" ]; do
|
||||
new_word >/dev/null
|
||||
i=$((i + 1))
|
||||
done
|
||||
end=$(date +%s)
|
||||
wordtime=$(elapsed 'Word creation' "$((end - start))" "$count")
|
||||
|
||||
bench_set 'Set element with depth 1 length 2' 1 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 2 length 2' 2 "$BENCH_ACCURACY" "$wordtime"
|
||||
bench_set 'Set element with depth 3 length 2' 3 "$BENCH_ACCURACY" "$wordtime"
|
||||
Reference in New Issue
Block a user