diff options
| author | Marc Vertes <mvertes@free.fr> | 2025-07-16 11:43:45 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2025-07-16 11:43:45 +0200 |
| commit | 23e204ff6544021efbbe4afed13e1680872ec275 (patch) | |
| tree | f57eea6be2fcd55a10b9e778793e16dbead2d37f | |
| parent | 22a7e5d77587372ea4c63c84fd8e0447f424bc15 (diff) | |
fix format, add filter
| -rwxr-xr-x | mp | 146 |
1 files changed, 103 insertions, 43 deletions
@@ -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) + } } } |
