summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-07-16 11:43:45 +0200
committerMarc Vertes <mvertes@free.fr>2025-07-16 11:43:45 +0200
commit23e204ff6544021efbbe4afed13e1680872ec275 (patch)
treef57eea6be2fcd55a10b9e778793e16dbead2d37f
parent22a7e5d77587372ea4c63c84fd8e0447f424bc15 (diff)
fix format, add filter
-rwxr-xr-xmp146
1 files changed, 103 insertions, 43 deletions
diff --git a/mp b/mp
index 62f0e6d..fee6568 100755
--- a/mp
+++ b/mp
@@ -10,7 +10,6 @@ BEGIN {
" Prints cmd help or general help text.\n" \
" Example: help help\n"
- SUBSEP="."
filename = ARGV[1]
ARGV[1] = "/dev/stdin"
tty = 1 - system("test -t 0")
@@ -22,15 +21,18 @@ BEGIN {
if ($1 == "help") {
printf "%s", help[$2]
} else if ($1 == "format") {
- print json_format(v, "", $2)
+ if ($2 == "\"\"") $2 = ""
+ print format(v, key(v, $2), 0+$3)
} else if ($1 == "key") {
- key(v, $2)
+ print key(v, $2)
+ } else if ($1 == "filter") {
+ filter(v, "", $2)
} else if ($1 == "dump") {
if ($2 ~ /^\|/) {
cmd = substr($0, 1+index($0, "|"))
- for (k in v) print k " '" v[k] "'" | cmd
+ for (k in v) print k " " v[k] | cmd
close(cmd)
- } else for (k in v) print k " '" v[k] "'"
+ } else for (k in v) print k " " v[k]
} else if ($1 == "parse_string") {
delete v
sub(/^[[:space:]]+/, "")
@@ -54,7 +56,7 @@ function prompt(s) {
}
function scan(name, line, r) {
- TOKEN = TOKSTR = ""
+ TOKEN = ""
sub(/^[[:space:]]+/, "", line)
if (name) {
while (line == "") {
@@ -64,24 +66,21 @@ function scan(name, line, r) {
}
}
if (match(line, /^(null|true|false|[][}{,:])/)) {
- TOKEN = substr(line, 1, RLENGTH)
+ TOKEN = substr(line, 1, 1)
} else if (match(line, /^[.0-9Ee+-]+/)) {
- TOKSTR = substr(line, 1, RLENGTH)
- TOKEN = "number"
+ TOKEN = "d" substr(line, 1, RLENGTH)
} else if (match(line, /^"(\\.|[^\\"])*"/)) {
- TOKSTR = substr(line, 2, RLENGTH-2)
- TOKEN = "string"
+ TOKEN = "s" substr(line, 2, RLENGTH-2)
} else {
- TOKSTR = substr(line, 1, 1)
- if (TOKSTR) TOKEN = "invalid"
+ TOKEN = substr(line, 1, 1)
+ if (TOKEN) TOKEN = "I" TOKEN
}
return substr(line, RLENGTH+1)
}
-function parse(name, mem, key, line, i) {
+function parse(name, mem, key, line, id, ids, i, k) {
line = scan(name, line)
if (TOKEN == "[") {
- mem[key, "type"] = "array"
for (i = 0; TOKEN != "]"; i++) {
if (i > 0 && TOKEN != ",") return error("not a ','", line)
line = parse(name, mem, key SUBSEP i, line)
@@ -91,52 +90,58 @@ function parse(name, mem, key, line, i) {
}
line = scan(name, line)
}
+ mem[key] = "a"
} else if (TOKEN == "{") {
- mem[key, "type"] = "object"
for (i = 0; TOKEN != "}"; i++) {
if (i > 0 && TOKEN != ",") return error("not a ','", line)
line = scan(name, line)
if (i == 0 && TOKEN == "}") break
- if (TOKEN != "string") return error("not a string", line)
- mem[key, i, "key"] = TOKSTR
+ if (TOKEN !~ /^s/) return error("not a string", line)
+ k = substr(TOKEN, 2)
+ ids = ids (i ? SUBSEP : "") substr(TOKEN, 2)
line = scan(name, line)
if (TOKEN != ":") return error("not a ':'", line)
line = parse(name, mem, key SUBSEP i, line)
if (ERROR) return line
line = scan(name, line)
}
- } else if (TOKEN ~ /^(null|true|false|string|number)$/) {
- mem[key, "type"] = TOKEN
- if (TOKSTR) mem[key, "string"] = TOKSTR
+ mem[key] = "o" ids
+ } else if (TOKEN ~ /^[ntfsd]/) {
+ mem[key] = TOKEN
} else if (TOKEN) ERROR = "invalid token '" TOKEN "'"
return line
}
-function json_format(mem, key, indent, i, t, s, pre, post, ksep) {
+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 ? ": " : ":"
- t = mem[key, "type"]
- if (t == "null" || t == "true" || t == "false") return t
- if (t == "number") return mem[key, "string"]
- if (t == "string") return "\"" mem[key, "string"] "\""
- if (t == "object") {
- s = "{" post
- for (i = 0; ; i++) {
- if (! ((key, i , "type") in mem)) break
- s = s pre "\"" mem[key, i, "key"] "\"" ksep json_format(mem, key SUBSEP i, indent ? indent+1 : 0) "," post
+ if (id) id = "\"" id "\":" (indent ? " " : "")
+ v = mem[key]
+ c = substr(v, 1, 1)
+ if (c == "n") return id "null"
+ if (c == "t") return id "true"
+ if (c == "f") return id "false"
+ if (c == "d") return id substr(v, 2)
+ if (c == "s") return id "\"" substr(v, 2) "\""
+ if (c == "a") {
+ s = "[" post
+ for (i = 0; ((key, i) in mem); i++) {
+ if (i) s = s "," post
+ s = s pre format(mem, key SUBSEP i, indent ? indent+1 : 0)
}
- if (i) s = substr(s, 1, length(s) - length(post) - 1)
- return s post substr(pre, 3) "}"
+ return id s post substr(pre, 3) "]"
}
- if (t == "array") {
- s = "[" post
- for (i = 0; ; i++) {
- if (! ((key, i , "type") in mem)) break
- s = s pre json_format(mem, key SUBSEP i, indent ? indent+1 : 0) "," post
+ if (c == "o") {
+ s = "{" post
+ v = substr(v, 2)
+ for (i = 0; ((key, i) in mem); i++) {
+ if (i) s = s "," post
+ v = tail(v, SUBSEP)
+ s = s pre "\"" HEAD "\"" ksep format(mem, key SUBSEP i, indent ? indent+1 : 0)
}
- if (i) s = substr(s, 1, length(s) - length(post) - 1)
- return s post substr(pre, 3) "]"
+ return id s post substr(pre, 3) "}"
}
}
@@ -145,8 +150,63 @@ function space(n, i, s) {
return s
}
-function key(a, s, p, k) {
- print "# s:" s
- if (a[p, "type"] == "object") {
+function tail(str, sep, i) {
+ if (i = index(str, sep)) {
+ HEAD = substr(str, 1, i-1)
+ return substr(str, i+1)
+ } 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
+ }
+ return -1
+}
+
+# TODO: remove recursivity
+function key(mem, pattern, k1, result, i, k, s, w) {
+ if (! (k1 in mem)) return
+ gsub(/[.]/, SUBSEP, pattern)
+ k = head(pattern, SUBSEP)
+ pattern = TAIL
+ if (k ~ /^[0-9]+$/) {
+ result = result SUBSEP k
+ } else {
+ s = substr(mem[k1], 2)
+ if ((i = lindex(s, k)) >= 0) result = result SUBSEP i
+ }
+ if (pattern) return key(mem, pattern, k1 SUBSEP i, result)
+ return result
+}
+
+function filter(mem, key, sk, i, k, n, v) {
+ v = mem[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)
+ } 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)
+ }
}
}