X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=json.awk;h=cfb8eac56c680460b9e12d4c6d7a1e7c3f45a61c;hb=766de7de0e82eb3203dc6f0c2e50b0d60b8a9f38;hp=93f6b498c9c277bcaff45551f1d6b3cd599d9102;hpb=ba197f8ee6cc9bb2423d155ae7acd053e5a9bbb4;p=~andy%2Frhawk diff --git a/json.awk b/json.awk index 93f6b49..cfb8eac 100644 --- a/json.awk +++ b/json.awk @@ -1,3 +1,12 @@ +# usage: +# @include "json.awk" +# BEGIN { +# src["hello"] = "world" +# json_save("test.json", src) +# json_load("test.json", dst) +# print dst["hello"] +# } +# # value: # object: { string : value, .. } # array: [ value, .. ] @@ -108,7 +117,14 @@ function json_write_number(number) function json_write_string(string) { - # todo: special characters + gsub(/\\/, "\\\\", string) + gsub(/"/, "\\\"", string) + gsub(/\b/, "\\b", string) + gsub(/\f/, "\\f", string) + gsub(/\n/, "\\n", string) + gsub(/\r/, "\\r", string) + gsub(/\t/, "\\t", string) + return "\"" string "\"" } @@ -117,7 +133,7 @@ function json_write_string(string) function json_tokenize(str, tokens, i, line, items, table, type, found) { table["term"] = "^[\\[\\]{}:,]" - table["str"] = "^\"[^\"]*\"" + table["str"] = "^\"([^\\\\\"]|\\\\.)*\"" table["num"] = "^[+-]?[0-9]+(.[0-9]+)?" table["var"] = "^(true|false|null)" table["space"] = "^[ \\t]+" @@ -150,11 +166,12 @@ function json_tokenize(str, tokens, i, line, items, table, type, found) return 0 } } - return i #for (i = 0; i < length(tokens); i++) # printf "%-3s %-5s [%s]\n", i":", # tokens[i]["type"], tokens[i]["text"] + + return i } function json_parse_value(tokens, i, value, key, line, type, text) @@ -240,6 +257,15 @@ function json_parse_string(tokens, i, value, key, text) text = tokens[i++]["text"] len = length(text); text = len == 2 ? "" : substr(text, 2, len-2) + + gsub(/\\\\/, "\\", text) + gsub(/\\"/, "\"", text) + gsub(/\\b/, "\b", text) + gsub(/\\f/, "\f", text) + gsub(/\\n/, "\n", text) + gsub(/\\r/, "\r", text) + gsub(/\\t/, "\t", text) + json_copy(value, key, text) #print "parse_string: [" text "]" return i @@ -257,13 +283,10 @@ function json_parse_var(tokens, i, value, key, text, null) } -# Nice API? -function json_load(file, var, line, text, tokens, data, key) +# String API +function json_decode(string, var, tokens, data, key) { - while ((getline line < file) > 0) - text = text line - close(file) - if (!json_tokenize(text, tokens)) + if (!json_tokenize(string, tokens)) return "" if (!json_parse_value(tokens, 0, data, 0)) return "" @@ -274,12 +297,26 @@ function json_load(file, var, line, text, tokens, data, key) return 1 } +function json_encode(var, pad) +{ + return json_write_value(var, pad) +} + +# File API +function json_load(file, var, line, string) +{ + delete var + while ((getline line < file) > 0) + string = string line "\n" + return json_decode(string, var) +} + function json_save(file, var, cmd, tmp) { cmd = "mktemp " file ".XXX" cmd | getline tmp close(cmd) - print json_write_value(var) > tmp + print json_encode(var) > tmp close(tmp) system("mv " tmp " " file) } @@ -288,6 +325,7 @@ function json_save(file, var, cmd, tmp) # Test functions function json_test_write() { + print "Testing JSON Write:" num = 42 str = "hello, world" arr[0] = "zero" @@ -302,23 +340,23 @@ function json_test_write() json_copy(mix, "obj", obj); json_copy(dub, "first", mix); json_copy(dub, "second", mix); - print json_write_value(num) - print json_write_value(str) - print json_write_value(arr) - print json_write_value(obj) - print json_write_value(mix) - print json_write_value(dub) + print json_encode(num) + print json_encode(str) + print json_encode(arr) + print json_encode(obj) + print json_encode(mix) + print json_encode(dub) } function json_test_read() { - json_tokenize("[8, \"abc\", 9]", tokens) - json_parse_value(tokens, 0, array, 0) - print json_write_value(array[0]) + print "Testing JSON Read:" + + json_decode("[8, \"abc\", 9]", array); + print json_encode(array) - json_tokenize("{\"abc\": 1, \"def\": 2}", tokens) - json_parse_value(tokens, 0, array, 0) - print json_write_value(array[0]) + json_decode("{\"abc\": 1, \"def\": 2}", array) + print json_encode(array) json = "{ \"first\": { \"arr\": [ \"\", \n" \ " -1, \n" \ @@ -335,26 +373,27 @@ function json_test_read() " \"str\": \"hello, world\" }, \n" \ " \"second\": { \"arr\": [ \"zero\", \n" \ " \"one\", \n" \ - " \"two\" ], \n" \ + " \"two\", \n" \ + " \"\\\"\t\r\b\" ], \n" \ " \"number\": 42, \n" \ " \"obj\": { \"A\": \"a!\", \n" \ " \"B\": \"b!\", \n" \ " \"C\": \"c!\" }, \n" \ " \"str\": \"hello, world\" } }\n" - json_tokenize(json, tokens) - json_parse_value(tokens, 0, array, 0) - print json_write_value(array[0]) + json_decode(json, array) + print json_encode(array) } function json_test_files() { + print "Testing JSON Files:" print "load: [" json_load("email.txt", mail) "]" - print "mail: " json_write_value(mail, " ") + print "mail: " json_encode(mail, " ") mail["andy753421"] = "andy753421@gmail.com" mail["andy"] = "andy@gmail.com" mail["somebody"] = "foo@example.com" - print "mail: " json_write_value(mail, " ") + print "mail: " json_encode(mail, " ") print "save: [" json_save("email.txt", mail) "]" }