commit c9a2cd24c43b3c4571211b596d4967869bdfc826
parent ec600d17b132f4ffc4ae6942752738210051a582
Author: Jan Pobrislo <ccx@webprojekty.cz>
Date: Thu, 3 Sep 2015 18:24:08 +0200
tests, error out on undefined variables, support default variable value in data.awk
Diffstat:
| A | aat.test | | | 34 | ++++++++++++++++++++++++++++++++++ |
| A | aat_data.test | | | 11 | +++++++++++ |
| A | aat_simple.test | | | 18 | ++++++++++++++++++ |
| M | bin/aat.awk | | | 109 | ++++--------------------------------------------------------------------------- |
| M | data.awk | | | 35 | +++++++++++------------------------ |
| A | inputs | | | 22 | ++++++++++++++++++++++ |
| M | query.test | | | 6 | ------ |
| A | testloop | | | 60 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
8 files changed, 161 insertions(+), 134 deletions(-)
diff --git a/aat.test b/aat.test
@@ -0,0 +1,34 @@
+./bin/aat.awk
+<<<
+Hello world!
+>>>
+printf "%s", "Hello world!\n"
+>>>= 0
+
+./bin/aat.awk
+<<<
+|BEGIN {print "Hello world!"}
+>>>
+BEGIN {print "Hello world!"}
+>>>= 0
+
+./bin/aat.awk
+<<<
+Hello {{name}}!
+>>>
+printf "%s", "Hello " (name) "!\n"
+>>>= 0
+
+./bin/aat.awk
+<<<
+Hello {<name>}!
+>>>
+printf "%s", "Hello " (<name>) "!\n"
+>>>= 0
+
+./bin/aat.awk
+<<<
+Hello {<a<b<c>>>}!
+>>>
+printf "%s", "Hello " (<a<b<c>>>) "!\n"
+>>>= 0
diff --git a/aat_data.test b/aat_data.test
@@ -0,0 +1,11 @@
+./inputs './bin/aat @1@ @2@'
+<<<
+@awk ./data.awk
+|END{
+Hello {<name>}!
+|}
+---
+name=world
+>>>
+Hello world!
+>>>= 0
diff --git a/aat_simple.test b/aat_simple.test
@@ -0,0 +1,18 @@
+./bin/aat -
+<<<
+|BEGIN {
+Hello world!
+|}
+>>>
+Hello world!
+>>>= 0
+
+./bin/aat -
+<<<
+|BEGIN {
+|name="world"
+Hello {{name}}!
+|}
+>>>
+Hello world!
+>>>= 0
diff --git a/bin/aat.awk b/bin/aat.awk
@@ -1,4 +1,5 @@
#!/bin/awk -f
+# vim: ft=awk noet sts=4 ts=4 sw=4
BEGIN {
tok_n = 0 # couter of tokens accumulated
@@ -33,7 +34,7 @@ function token(content) {
tok_contents[tok_n] = content
}
if(DEBUG) printf "token %d (%s): \"%s\"\n", \
- tok_n, type_names[tok_type], tok_contents[tok_n] >"/dev/stderr"
+ tok_n, type_names[tok_type], tok_contents[tok_n] >"/dev/stderr"
}
# Print file dependencies for makefile usage
@@ -183,13 +184,13 @@ function call_macro(name, args, file_old) {
# if with a query expression
else if(name == "if"){
tok_type=T_AWK
- token("if(" aat_process(substr(args, RSTART+RLENGTH)) ") {\n")
+ token("if(<" substr(args, RSTART+RLENGTH) ">) {\n")
}
# else if with a query expression
else if(name == "elif"){
tok_type=T_AWK
- token("} else if(" aat_process(substr(args, RSTART+RLENGTH)) ") {\n")
+ token("} else if(<" substr(args, RSTART+RLENGTH) ">) {\n")
}
# Leave the @ there for postprocessing with sed
@@ -314,106 +315,6 @@ function parse_line(line) {
}
}
-# TODO make this pluggable
-# called for expanding {< >}
-function expand_query( expanded) {
- expanded = ""
- while(match(expand_remaining, "['<>]")) {
- if(RSTART > 1)
- expanded = expanded "\"" substr(expand_remaining, 1, RSTART-1) "\""
- char = substr(expand_remaining, RSTART, 1)
- expand_remaining = substr(expand_remaining, RSTART+1)
- if(char == ">")
- return "get("expanded")"
- else if(char == "<") {
- expanded = expanded expand_query()
- } else if(char == "'") {
- if(match(expand_remaining, "'")) {
- expanded = expanded substr(expand_remaining, 1, RSTART-1)
- expand_remaining = substr(expand_remaining, RSTART+1)
- } else {
- expanded = expand_remaining
- expand_remaining = ""
- }
- } else {
- print "ERROR: internal error in expand_query()" >"/dev/stderr"
- exit 1
- }
- }
- if(expand_remaining) {
- expanded = "\"" expand_remaining "\""
- expand_remaining = ""
- }
- return "get("expanded")"
-}
-function match_dbg(type, str) {
- if(DEBUG) printf "<%s match: \"%s\">", type, \
- substr(str, RSTART, RLENGTH) >"/dev/stderr"
-}
-function aat_process(str) {
- processed = ""
- while(str) {
- if(match(str, /^[0-9]x?[0-9a-fA-F.]+(e[-+][0-9]+)?/)) {
- # number literal
- match_dbg("number", str)
- processed = processed "("substr(str, 1, RLENGTH)")"
- str = substr(str, RLENGTH+1)
- } else if(match(str, /^[a-zA-Z_.<>'][a-zA-Z0-9_.<>']*/)) {
- # a query
- match_dbg("query", str)
- processed = processed "<" substr(str, 1, RLENGTH) ">"
- str = substr(str, RLENGTH+1)
- } else if(match(str, /^\|[a-zA-Z_]/)) {
- # filters ahead
- match_dbg("filter", str)
- break
- } else if(match(str, /^"/)) {
- # literal string
- match_dbg("string", str)
- match(str, /^"([^"\\]|\\[^"])*"/)
- processed = processed substr(str, 1, RLENGTH)
- str = substr(str, RLENGTH+1)
- } else if(match(str, /^ /)) {
- # spaces are passed verbatim
- match_dbg("space", str)
- processed = processed " "
- str = substr(str, 2)
- } else {
- # anything else is passed verbatim up to space or quote
- if(match(str, /[ "]/)) {
- if(DEBUG) printf "<* match: \"%s\">", \
- substr(str, 1, RSTART-1) >"/dev/stderr"
- processed = processed substr(str, 1, RSTART-1)
- str = substr(str, RSTART)
- } else {
- if(DEBUG) printf "<* non-match: \"%s\">", \
- str >"/dev/stderr"
- processed = processed str
- str = ""
- }
- }
- }
- while(str) {
- if(!match(str, /^\|[a-zA-Z_][a-zA-Z0-9_.]*/)) {
- print "ERROR: invalid filter: " str >"/dev/stderr"
- exit 1
- }
- filter_name = substr(str, 2, RLENGTH-1)
- str = substr(str, RLENGTH+1)
- if(str == "") {
- args = ""
- } else if(match(str, /\|[a-zA-Z_][a-zA-Z0-9_.]* /)) {
- args = "," substr(str, 1, RSTART-1)
- str = substr(str, RSTART)
- } else {
- args = "," str
- str = ""
- }
- processed = filter_name "(" processed args ")"
- }
- return processed
-}
-
# for every line in files in ARGV
{
# current filename being read
@@ -447,7 +348,7 @@ END {
printf " (%s)", c
} else if(tok_type == T_FUNC) {
# TODO
- printf " (%s)", aat_process(c)
+ printf " (<%s>)", c
} else {
print "ERROR: unknown tok_type: " tok_type >"/dev/stderr"
exit 1
diff --git a/data.awk b/data.awk
@@ -94,7 +94,7 @@ function loop_end() {
loop_stack["depth"]--
}
-function _get(varname, i, n, names, values, loopvar, looprow, prefix) {
+function find(varname, i, n, names, values, loopvar, looprow, prefix) {
for(i=loop_stack["depth"]; i>0; i--) {
prefix = loop_stack[i, "pre"]
if(prefix)
@@ -124,39 +124,26 @@ function _get(varname, i, n, names, values, loopvar, looprow, prefix) {
}
}
}
- if(DEBUG) {
- if(!(varname in V)) {
+ if(!(varname in V)) {
+ if(DEBUG) {
print "variable not found: " varname >"/dev/stderr"
}
+ return 0
}
- return V[varname]
+ found = V[varname]
}
function get(varname, result) {
- result = _get(varname)
+ if(!find(varname)) {
+ print "error: undefined variable '"$varname"'" >"/dev/stderr"
+ exit 1
+ }
if(DEBUG) {
- print "get →" varname "← ⇒ →"result"←" >"/dev/stderr"
+ print "get →" varname "← ⇒ →"found"←" >"/dev/stderr"
}
- return result
+ return found
}
function or_(a, b) {
return a ? a : b
}
-
-# for testing it out, set TEST=1 on commandline
-END {
- if(TEST) {
- for(key in V) {
- printf("%s⇒\t→%s←\n", key, V[key])
- }
- print "--------------------"
- print get("foo")
- for(d1=loop_start("spam"); loop_iter(d1);) {
- print get("name") "-" get("value")
- for(d2=loop_start("spam", "i_"); loop_iter(d2);) {
- print get("eggs") + get("i_eggs")
- } loop_end()
- } loop_end()
- }
-}
diff --git a/inputs b/inputs
@@ -0,0 +1,22 @@
+#!/bin/zsh
+: ${delim:=---}
+cmd=$1
+inputs=( "$(mktemp)" )
+while IFS= read line; do
+ if [[ $line == $delim ]]; then
+ inputs+=( "$(mktemp)" )
+ else
+ printf '%s\n' >>$inputs[-1]
+ fi
+done
+
+for n in $(seq 1 $#inputs); do
+ cmd=${cmd//@${n}@/${(qqq)inputs[$n]}}
+done
+
+eval $cmd
+ret=$?
+
+rm $inputs
+
+exit $ret
diff --git a/query.test b/query.test
@@ -1,9 +1,3 @@
-true
->>>= 0
-
-false
->>>= 1
-
./q
<<<
BEGIN {
diff --git a/testloop b/testloop
@@ -0,0 +1,60 @@
+#!/bin/zsh
+setopt extendedglob
+
+autoload -Uz colors; colors
+
+typeset -ga test_args
+typeset -g run evt fname
+# typeset -gT PYTHONPATH pythonpath
+# pythonpath=( $0:h ~/.local/bzr/*/python(/N) /usr/local/bzr/*/python(/N) $pythonpath )
+# export PYTHONPATH
+
+test_args=( "$@" )
+
+do_test() {
+ shelltest -ap *.test -c "$test_args[@]" -- -j8 -o1
+ # time py.test "$test_args"
+}
+
+trigger_check() {
+ local ret show
+ ret=0; show=1
+ case $fname in
+ (*.py[co]) ret=1;;
+ (*.sw[px]) ret=1;;
+ (*.swpx) ret=1;;
+ (*.tmp) ret=1;;
+ (*'~') ret=1;;
+ (*__pycache__*) ret=1;;
+ (*/bin/[0-9]*) ret=1;;
+ (*/.hypothesis*) ret=1; show=0;;
+ (*/test_error.sql) ret=1;;
+ (*/commlog/*) ret=1; show=0;;
+ (*/.bzr/*) ret=1; show=0;;
+ esac
+ [[ $fname =~ '.*/[0-9]+$' ]] && ret=1
+ if (($ret)); then
+ (($show)) && print -r - "$fname $evt"
+ else
+ print -r "$fg[green]$fname $evt$reset_color"
+ fi
+ return $ret
+}
+
+coproc inotifywait -m -q -e create,move,close_write --format '%e %w%f' -r \
+ --exclude='\.bzr/' --exclude='/commlog/' \
+ .
+
+while read -prt 0.5 evt fname; do
+ print -r "$fg[blue]$fname $evt$reset_color"
+done
+do_test
+while read -pr evt fname; do
+ trigger_check || continue
+ while read -prt 0.5 evt fname; do
+ print -r "$fg[blue]$fname $evt$reset_color"
+ done
+ do_test
+done
+
+#while inotifywait -q --exclude='.*sw[p-z]' --exclude='.*commlog.*' -e create,move,close_write **/*~commlog*~*__pycache__(/) **/*.py || (($? == 2)); do