summaryrefslogtreecommitdiff
path: root/jsongen.py
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-09-01 00:54:07 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-09-01 00:54:07 +0000
commit4951e87db953a1b60ac36a9783c270d58cfb97d0 (patch)
tree8d8a0e7d2078e955dbb10524c4220a0972655f9c /jsongen.py
parent8645b62cc230bcdcfc23a677f9d4b81dc4b5181f (diff)
downloadgpsd-4951e87db953a1b60ac36a9783c270d58cfb97d0.tar.gz
Proof of concept for JSON parder generation.
Diffstat (limited to 'jsongen.py')
-rwxr-xr-xjsongen.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/jsongen.py b/jsongen.py
new file mode 100755
index 00000000..d684b6fb
--- /dev/null
+++ b/jsongen.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# Never hand-hack what you can generate...
+#
+# This code senerate template declarations for AIS-JSON parsing from a
+# declarative specification of a JSON structure - and generate those
+# declarative specification from the Python format strings for
+# dumping the structures
+#
+import sys, getopt
+
+# Make shared field names to data types
+typemap = {
+ # AIS fields
+ "raim":"boolean",
+ "accuracy":"boolean",
+ "timestamp":"string",
+ }
+
+# Map C and Python-type format letters to JSON parser datatypes
+fmtmap = {
+ "d": "integer",
+ "u": "uinteger",
+ "f": "real",
+ "a": "string",
+ }
+
+
+ais_specs = (
+ ("json_ais4", "\tAIS_HEADER,", "ais->type4",
+ "\"timestamp\":\"%4u:%02u:%02uT%02u:%02u:%02uZ\","\
+ "\"accuracy\":%s,\"lon\":%d,\"lat\":%d,"\
+ "\"epfd\":%u,\"raim\":%s,\"radio\":%d}\r\n"
+ ),
+ )
+
+def generate(initname, header, structname, specifier):
+ specifier = specifier.strip()
+ if specifier[-1] == "}":
+ specifier = specifier[:-1]
+ else:
+ print "Missing terminating }"
+ sys.exit(1)
+
+ print " const struct json_attr_t %s[] = {" % initname
+ if header:
+ print header
+ for item in specifier.split(","):
+ if "timestamp" in item:
+ (attr, itype) = ("timestamp", "string")
+ else:
+ itype = None
+ (attr, fmt) = item.split(":")
+ if attr[0] == '"':
+ attr = attr[1:]
+ if attr[-1] == '"':
+ attr = attr[:-1]
+ if attr in typemap:
+ itype = typemap[attr]
+ if fmt[-1] in fmtmap:
+ itype = fmtmap[fmt[-1]]
+ if itype == "string":
+ deref = ""
+ else:
+ deref = "&"
+ print '\t{"%s",%s%s,%s.addr.%s = %s%s.%s,' % \
+ (attr, " "*(12-len(attr)),itype, " "*(12-len(itype)), itype, deref, structname, attr)
+ leader = " " * 37
+ if itype == "string":
+ print leader + ".maxlen = sizeof(%s.%s)}," % (structname, attr)
+ elif itype == "boolean":
+ print leader + ".dflt.boolean = false},"
+ elif itype == "real":
+ print leader + ".dflt.real = 0.0},"
+ else:
+ print leader + ".dflt.%s = 0}," % itype
+
+ print """\
+ {NULL},
+ };
+
+"""
+
+if __name__ == '__main__':
+ for description in ais_specs:
+ generate(initname=description[0],
+ header=description[1],
+ structname=description[2],
+ specifier=description[3])