+# 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, .. ]
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 "\""
}
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]+"
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)
if (tokens[i++]["text"] != "{")
return 0;
- do {
- delete k
- delete v
- if (!(i=json_parse_value(tokens, i, k, 0)))
- return 0
- if (tokens[i++]["text"] != ":")
- return 0
- if (!(i=json_parse_value(tokens, i, v, 0)))
- return 0
- json_copy(object, k[0], v[0])
- } while (tokens[i++]["text"] == ",")
- i--
+ if (tokens[i]["text"] != "}") {
+ do {
+ delete k
+ delete v
+ if (!(i=json_parse_value(tokens, i, k, 0)))
+ return 0
+ if (tokens[i++]["text"] != ":")
+ return 0
+ if (!(i=json_parse_value(tokens, i, v, 0)))
+ return 0
+ json_copy(object, k[0], v[0])
+ } while (tokens[i++]["text"] == ",")
+ i--
+ }
if (tokens[i++]["text"] != "}")
return 0;
if (tokens[i++]["text"] != "[")
return 0;
- do {
- delete v
- if (!(i=json_parse_value(tokens, i, v, 0)))
- return 0
- json_copy(array, k++, v[0])
- } while (tokens[i++]["text"] == ",")
- i--
+ if (tokens[i]["text"] != "]") {
+ do {
+ delete v
+ if (!(i=json_parse_value(tokens, i, v, 0)))
+ return 0
+ json_copy(array, k++, v[0])
+ } while (tokens[i++]["text"] == ",")
+ i--
+ }
if (tokens[i++]["text"] != "]")
return 0;
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
function json_load(file, var, line, text, tokens, data, key)
{
while ((getline line < file) > 0)
- text = text line
+ text = text line "\n"
close(file)
if (!json_tokenize(text, tokens))
return ""
" false, \n" \
" null ], \n" \
" \"number\": 42, \n" \
+ " \"eobj\": [ ], \n" \
+ " \"earr\": { }, \n" \
" \"obj\": { \"A\": \"a!\", \n" \
" \"B\": \"b!\", \n" \
" \"C\": \"c!\" }, \n" \
" \"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" \