summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-07-17 14:27:18 +0200
committerMarc Vertes <mvertes@free.fr>2025-07-17 14:27:18 +0200
commit3c7bc23285157858b3dc7468e5abbb16e05f31f7 (patch)
tree0f06e777692839af9563229df3a2e4f5f3670280
parent23e204ff6544021efbbe4afed13e1680872ec275 (diff)
improve naming
-rwxr-xr-xmp108
-rwxr-xr-xtests33
2 files changed, 74 insertions, 67 deletions
diff --git a/mp b/mp
index fee6568..c263004 100755
--- a/mp
+++ b/mp
@@ -41,8 +41,11 @@ BEGIN {
} else if ($1 == "parse") {
delete v
parse($2, v)
- } else if (NF) {
+ } else if (filename && NF) {
error("invalid command: " $1)
+ } else {
+ parse("", v, "", $0)
+ print format(v)
}
prompt()
}
@@ -55,13 +58,13 @@ function prompt(s) {
if (tty) printf "%s> ", s > "/dev/stderr"
}
-function scan(name, line, r) {
+function scan(infile, line, r) {
TOKEN = ""
sub(/^[[:space:]]+/, "", line)
- if (name) {
+ if (infile) {
while (line == "") {
- if ((r = getline line < name) == 0) return
- if (r == -1) return error("error read " name)
+ if ((r = getline line < infile) == 0) return
+ if (r == -1) return error("error read " infile)
sub(/^[[:space:]]+/, "", line)
}
}
@@ -78,47 +81,49 @@ function scan(name, line, r) {
return substr(line, RLENGTH+1)
}
-function parse(name, mem, key, line, id, ids, i, k) {
- line = scan(name, line)
+function parse(infile, values, key, line, id, ids, i, k) {
+ line = scan(infile, line)
if (TOKEN == "[") {
for (i = 0; TOKEN != "]"; i++) {
if (i > 0 && TOKEN != ",") return error("not a ','", line)
- line = parse(name, mem, key SUBSEP i, line)
+ line = parse(infile, values, key SUBSEP i, line)
if (ERROR) {
if (i == 0 && TOKEN == "]") ERROR = ""
break
}
- line = scan(name, line)
+ line = scan(infile, line)
}
- mem[key] = "a"
+ values[key] = "a"
} else if (TOKEN == "{") {
for (i = 0; TOKEN != "}"; i++) {
if (i > 0 && TOKEN != ",") return error("not a ','", line)
- line = scan(name, line)
+ line = scan(infile, line)
if (i == 0 && TOKEN == "}") break
if (TOKEN !~ /^s/) return error("not a string", line)
k = substr(TOKEN, 2)
ids = ids (i ? SUBSEP : "") substr(TOKEN, 2)
- line = scan(name, line)
+ line = scan(infile, line)
if (TOKEN != ":") return error("not a ':'", line)
- line = parse(name, mem, key SUBSEP i, line)
+ line = parse(infile, values, key SUBSEP i, line)
if (ERROR) return line
- line = scan(name, line)
+ line = scan(infile, line)
}
- mem[key] = "o" ids
+ values[key] = "o" ids
} else if (TOKEN ~ /^[ntfsd]/) {
- mem[key] = TOKEN
+ values[key] = TOKEN
} else if (TOKEN) ERROR = "invalid token '" TOKEN "'"
return line
}
-function format(mem, key, indent, id, c, i, s, v, pre, post, ksep) {
- if (! (key in mem)) return
- pre = indent ? space(indent * 2) : ""
- post = indent ? "\n" : ""
- ksep = indent ? ": " : ":"
- if (id) id = "\"" id "\":" (indent ? " " : "")
- v = mem[key]
+function format(values, key, indent, id, c, i, s, v, pre, post, sp) {
+ if (! (key in values)) return
+ if (indent) {
+ pre = space(indent * 2)
+ post = "\n"
+ sp = " "
+ }
+ if (id) id = "\"" id "\":" sp
+ v = values[key]
c = substr(v, 1, 1)
if (c == "n") return id "null"
if (c == "t") return id "true"
@@ -127,19 +132,19 @@ function format(mem, key, indent, id, c, i, s, v, pre, post, ksep) {
if (c == "s") return id "\"" substr(v, 2) "\""
if (c == "a") {
s = "[" post
- for (i = 0; ((key, i) in mem); i++) {
+ for (i = 0; ((key, i) in values); i++) {
if (i) s = s "," post
- s = s pre format(mem, key SUBSEP i, indent ? indent+1 : 0)
+ s = s pre format(values, key SUBSEP i, indent ? indent+1 : 0)
}
return id s post substr(pre, 3) "]"
}
if (c == "o") {
s = "{" post
v = substr(v, 2)
- for (i = 0; ((key, i) in mem); i++) {
+ for (i = 0; ((key, i) in values); i++) {
if (i) s = s "," post
v = tail(v, SUBSEP)
- s = s pre "\"" HEAD "\"" ksep format(mem, key SUBSEP i, indent ? indent+1 : 0)
+ s = s pre "\"" HEAD "\":" sp format(values, key SUBSEP i, indent ? indent+1 : 0)
}
return id s post substr(pre, 3) "}"
}
@@ -157,56 +162,49 @@ function tail(str, sep, i) {
} else HEAD = str
}
-function head(str, sep, i) {
- if (i = index(str, sep)) {
- TAIL = substr(str, i+1)
- return substr(str, 1, i-1)
- }
- TAIL = ""
- return str
-}
-
function lindex(list, item, i, k) {
for (i = 0; list; i++) {
- if (head(list, SUBSEP) == item) return i
- list = TAIL
+ list = tail(list, SUBSEP)
+ if (HEAD == item) return i
}
return -1
}
# TODO: remove recursivity
-function key(mem, pattern, k1, result, i, k, s, w) {
- if (! (k1 in mem)) return
+# TODO: handle spaces
+function key(values, pattern, k1, result, i, k, s, w) {
+ if (! (k1 in values)) return
gsub(/[.]/, SUBSEP, pattern)
- k = head(pattern, SUBSEP)
- pattern = TAIL
+ pattern = tail(pattern, SUBSEP)
+ k = HEAD
if (k ~ /^[0-9]+$/) {
result = result SUBSEP k
} else {
- s = substr(mem[k1], 2)
+ s = substr(values[k1], 2)
if ((i = lindex(s, k)) >= 0) result = result SUBSEP i
}
- if (pattern) return key(mem, pattern, k1 SUBSEP i, result)
+ if (pattern) return key(values, pattern, k1 SUBSEP i, result)
return result
}
-function filter(mem, key, sk, i, k, n, v) {
- v = mem[key]
+function filter(values, key, sk, i, k, n, v) {
+ v = values[key]
if (v ~ /^o/) {
v = substr(v, 2)
- for (i = 0; v; i++) {
- k = head(v, SUBSEP)
- print sk "." k
- v = TAIL
- filter(mem, key SUBSEP i, sk "." k)
+ for (i = 0; ((key, i) in values); i++) {
+ v = tail(v, SUBSEP)
+ k = HEAD
+ sk = sk ? sk "." k : k
+ print sk
+ filter(values, key SUBSEP i, sk)
} while (v)
return
}
if (v ~ /^a/) {
- n = substr(v, 2)
- for (i = 0; i < n; i++) {
- print sk "." i
- filter(mem, key SUBSEP i, sk "." i)
+ for (i = 0; ((key, i) in values); i++) {
+ sk = sk ? sk "." i : i
+ print sk
+ filter(values, key SUBSEP i, sk)
}
}
}
diff --git a/tests b/tests
index e416f3f..2fcbc3b 100755
--- a/tests
+++ b/tests
@@ -3,9 +3,9 @@
run() {
[ "$filter" ] && case $1 in ($filter) ;; (*) return; esac
- out=$(echo "$2" | ./mp 2>&1)
+ out=$(printf %s "$2" | ./mp 2>&1)
[ "$out" = "$3" ] && pass=$((pass + 1)) && return
- printf "%s FAIL\nWant: \"%s\"\n Got: \"%s\"\n" "$1" "$3" "$out"
+ printf "%s FAIL\nWant: '%s'\n Got: '%s'\n" "$1" "$3" "$out"
fail=$((fail + 1))
return 1
}
@@ -14,13 +14,22 @@ run() {
pass=0 fail=0 filter="$1"
trap 'echo "$pass passed, $fail failed"; exit $((fail != 0))' EXIT
-run basic_1 'parse_string\nformat' ''
-run basic_2 'parse_string null\nformat' 'null'
-run basic_3 'parse_string true\nformat' 'true'
-run basic_4 'parse_string false\nformat' 'false'
-run number_1 'parse_string 12\nformat' '12'
-run string_1 'parse_string "hello"\nformat' '"hello"'
-run array_1 'parse_string []\nformat' '[]'
-run array_2 'parse_string [null]\nformat' '[null]'
-run array_3 'parse_string [true,false]\nformat' '[true,false]'
-run object_1 'parse_string {}\nformat' '{}'
+run basic_1 '' ''
+run basic_2 'null' 'null'
+run basic_3 'true' 'true'
+run basic_4 'false' 'false'
+run number_1 '12' '12'
+run string_1 '"hello"' '"hello"'
+run string_2 '"hello \"world\""' '"hello \"world\""'
+run string_3 '""' '""'
+run array_1 '[]' '[]'
+run array_2 '[null]' '[null]'
+run array_3 '[true,false]' '[true,false]'
+run object_1 '{}' '{}'
+run object_2 '{"":false}' '{"":false}'
+run object_3 '{"":false,"1": true}' '{"":false,"1":true}'
+run object_4 '{ }' '{}'
+run object_5 '{
+}' '{}'
+run object_6 '{"id":
+1}' '{"id":1}'