summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-07-10 11:34:36 +0200
committerMarc Vertes <mvertes@free.fr>2025-07-10 11:34:36 +0200
commit2281c4644d9f2b8f3584ec065d2dbd9bff644830 (patch)
treebe9332e53d6a7cff25fcc7480c27fa20b388f581
initial commit
-rw-r--r--Makefile6
-rwxr-xr-xmp99
-rw-r--r--readme.md3
3 files changed, 108 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..86aab59
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+# test:
+#
+
+test.json:
+ curl https://httpbin.org/json > test.json
+
diff --git a/mp b/mp
new file mode 100755
index 0000000..337f316
--- /dev/null
+++ b/mp
@@ -0,0 +1,99 @@
+#!/usr/bin/awk -f
+
+BEGIN {
+ version = "2025-07-08"
+
+ help[""] = "Commands:\n" \
+ " help [cmd] prints cmd help or this help text\n"
+
+ help["help"] = "help [cmd]\n" \
+ " Prints cmd help or general help text.\n" \
+ " Example: help help\n"
+
+ filename = ARGV[1]
+ ARGV[1] = "/dev/stdin"
+ tty = 1 - system("test -t 0")
+ if (filename) src = getfile(filename)
+ prompt("mp-" version " meta parser. Type \"help\" for help.\n")
+}
+$1 == "help" {
+ prompt(help[$2])
+ next
+}
+$1 == "src" {
+ prompt(src)
+ next
+}
+$1 == "parse" {
+ delete v
+ if ($2) parse_json($2, v); else parse_json(src, v)
+ for (k in v) print "v[" k "]: " v[k]
+ prompt()
+ next
+}
+{
+ if (NF) error("invalid command: " $1)
+ prompt()
+}
+
+function error(s) { ERROR = s }
+
+function prompt(s) {
+ if (ERROR) {
+ print ERROR > "/dev/stderr"
+ ERROR = ""
+ }
+ if (tty) printf("%smp> ", s)
+}
+
+function getfile(name, l, r, o) {
+ while (r = getline l < name) {
+ if (r == -1) {
+ error = "getfile " name ": getline error"
+ break
+ }
+ o = o l "\n"
+ }
+ close(name)
+ return o
+}
+
+# parse the next json value in s, returns the number of characters read.
+function parse_json(s, a, p, c, i, n) {
+ if (match(s, /^[[:space:]]+/)) {
+ n = RLENGTH
+ s = substr(s, RLENGTH+1)
+ }
+ if (!s) return n
+ if (match(s, /^null|true|false/)) {
+ a[p, "type"] = substr(s, 1, RLENGTH)
+ return n + RLENGTH
+ }
+ if (match(s, /^[.0-9Ee+-]+/)) {
+ a[p, "type"] = "number"
+ a[p, "string"] = substr(s, 1, RLENGTH)
+ return n + RLENGTH
+ }
+ if (match(s, /^"(\\.|[^\\"])*"/)) {
+ a[p, "type"] = "string"
+ a[p, "string"] = substr(s, 2, RLENGTH-2)
+ return n + RLENGTH
+ }
+ c = substr(s, 1, 1)
+ if (c == "{") {
+ a[p, "type"] = "object"
+ i = 0
+ n++
+ s = substr(s, 2)
+ if (match(s, /^[[:space:]]+/)) {
+ n += RLENGTH
+ s = substr(s, RLENGTH+1)
+ }
+ if (match(s, /^"(\\.|[^\\"])*"/)) {
+ a[p, "key", i] = substr(s, 2, RLENGTH-2)
+ } else {
+ error("invalid key: " s)
+ return n
+ }
+ }
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..83650cf
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,3 @@
+# mp
+
+parsing and repl in awk.