summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-09-01 02:08:45 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-09-01 02:08:45 +0000
commitea1018a0cbeebd622c7a556f10ea7363aed58dd1 (patch)
tree862db6bd1578d35281de6af917e0848338ee704d
parent4951e87db953a1b60ac36a9783c270d58cfb97d0 (diff)
downloadgpsd-ea1018a0cbeebd622c7a556f10ea7363aed58dd1.tar.gz
Split into spec translation and generation.
-rwxr-xr-xjsongen.py131
1 files changed, 82 insertions, 49 deletions
diff --git a/jsongen.py b/jsongen.py
index d684b6fb..ff736e0e 100755
--- a/jsongen.py
+++ b/jsongen.py
@@ -11,41 +11,75 @@ 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"
- ),
- )
+ {
+ "initname" : "json_ais4",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type4",
+ "fieldmap":(
+ # fieldname type default
+ ('timestamp', 'string', None),
+ ('accuracy', 'boolean', "true"),
+ ('lon', 'integer', "AIS_LON_NOT_AVAILABLE"),
+ ('lat', 'integer', "AIS_LAT_NOT_AVAILABLE"),
+ ('epfd', 'uinteger', "0"),
+ ('raim', 'boolean', "false"),
+ ('radio', 'integer', "0"),
+ ),
+ "stringbuffered":("timestamp",),
+ },
+)
-def generate(initname, header, structname, specifier):
- specifier = specifier.strip()
- if specifier[-1] == "}":
- specifier = specifier[:-1]
+def generate(spec):
+ print " const struct json_attr_t %s[] = {" % spec["initname"]
+ if spec["header"]:
+ print spec["header"]
+ for (attr, itype, default) in spec["fieldmap"]:
+ structname = spec["structname"]
+ if itype == "string":
+ deref = ""
+ else:
+ deref = "&"
+ if attr in spec["stringbuffered"]:
+ target = attr
+ else:
+ target = structname + "." + attr
+ print '\t{"%s",%s%s,%s.addr.%s = %s%s,' % \
+ (attr, " "*(12-len(attr)),itype, " "*(12-len(itype)), itype, deref, target)
+ leader = " " * 37
+ if itype == "string":
+ print leader + ".maxlen = sizeof(%s)}," % target
+ else:
+ print leader + ".dflt.%s = %s}," % (itype, default)
+
+ print """\
+ {NULL},
+ };
+
+"""
+
+def string_to_specifier(strspec):
+ "Compile a Python-style format string to an attribute-type fieldmap."
+ # Map C and Python-type format letters to JSON parser datatypes
+ fmtmap = {
+ "d": "integer",
+ "u": "uinteger",
+ "f": "real",
+ "a": "string",
+ }
+ strspec = strspec.strip()
+ if strspec[-1] == "}":
+ strspec = strspec[:-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(","):
+ print '"fieldmap":('
+ for item in strspec.split(","):
if "timestamp" in item:
(attr, itype) = ("timestamp", "string")
else:
@@ -59,31 +93,30 @@ def generate(initname, header, structname, specifier):
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 " " + `(attr, itype)` + ","
+ print " )"
- print """\
- {NULL},
- };
-"""
+# Edit into this global the string spec you need to convert
+stringspec = \
+"\"timestamp\":\"%4u:%02u:%02uT%02u:%02u:%02uZ\","\
+ "\"accuracy\":%s,\"lon\":%d,\"lat\":%d,"\
+ "\"epfd\":%u,\"raim\":%s,\"radio\":%d}\r\n"
if __name__ == '__main__':
- for description in ais_specs:
- generate(initname=description[0],
- header=description[1],
- structname=description[2],
- specifier=description[3])
+ try:
+ (options, arguments) = getopt.getopt(sys.argv[1:], "g")
+ except getopt.GetoptError, msg:
+ print "jsongen.py: " + str(msg)
+ raise SystemExit, 1
+
+ specify = False
+ for (switch, val) in options:
+ if (switch == '-g'):
+ specify = True
+
+ if specify:
+ string_to_specifier(stringspec)
+ else:
+ for description in ais_specs:
+ generate(description)