diff options
author | Fred Wright <fw@fwright.net> | 2016-04-14 19:54:21 -0700 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2016-04-16 04:26:49 -0400 |
commit | b880c430e8e69ef90e1ec0840f3b1c92360e9885 (patch) | |
tree | da45bcfd173b59a4dbbdc4e6cea80c391cc00c9c /devtools | |
parent | f2ce184299978f27d610c46a40de76e717e53170 (diff) | |
download | gpsd-b880c430e8e69ef90e1ec0840f3b1c92360e9885.tar.gz |
Fixes cycle_analyzer for Python 3 (as well as other bugs).
It appears that this program hadn't been used in a while, since it had
bugs unrelated to Python 3. After fixing some bugs, it's able to run
successfully on all the test logfiles, except that it chokes on the
binary data in ac12_binary (due to a newline within the binary data),
and on the known malformed sentence in triton400.
In order to allow the utility functions in gps.misc to be imported, it
adds a symlink from devtools/gps to gps. Due to some weirdness in
Python 3 imports, there didn't seem to be any other way to make this
work with uninstalled libraries, and in any case it allows the local
libraries to take precendence over the system libraries.
TESTED:
Ran with all six supported Python versions on all daemon logfiles,
with only the errors noted above.
Diffstat (limited to 'devtools')
-rwxr-xr-x | devtools/cycle_analyzer | 78 | ||||
l--------- | devtools/gps | 1 |
2 files changed, 44 insertions, 35 deletions
diff --git a/devtools/cycle_analyzer b/devtools/cycle_analyzer index f38c3859..53ddd517 100755 --- a/devtools/cycle_analyzer +++ b/devtools/cycle_analyzer @@ -52,20 +52,26 @@ device will confuse the NMEA cycle detector, leading to more reports per cycle than the ideal. """ +# This code runs compatibly under Python 2 and 3.x for x >= 2. +# Preserve this property! +from __future__ import absolute_import, print_function, division + import sys, os, getopt, json +from gps.misc import polystr, isotime + verbose = 0 suppress_regular = False parse_json = False -class analyze_error: +class analyze_error(BaseException): def __init__(self, filename, msg): self.filename = filename self.msg = msg def __repr__(self): return '%s: %s' % (self.filename, self.msg) -class event: +class event(object): def __init__(self, tag, time=0): self.tag = tag self.time = time @@ -77,7 +83,7 @@ class event: __repr__ = __str__ def tags(lst): - return map(lambda x: x.tag, lst) + return [x.tag for x in lst] def extract_from_nmea(filename, lineno, line): "Extend sequence of tag/timestamp tuples from an NMEA sentence" @@ -86,7 +92,7 @@ def extract_from_nmea(filename, lineno, line): "GLL": 5, "GGA": 1, "GBS": 1, - "PASHR": 4, + "PASHR": {"POS": 4}, } fields = line.split(",") tag = fields[0] @@ -94,8 +100,11 @@ def extract_from_nmea(filename, lineno, line): tag = tag[3:] elif tag[0] == "$": tag = tag[1:] - if tag in hhmmss: - timestamp = fields[hhmmss[tag]] + field = hhmmss.get(tag) + if isinstance(field, dict): + field = field.get(fields[1]) + if field: + timestamp = fields[field] return [event(tag, timestamp)] else: return [] @@ -106,12 +115,12 @@ def extract_from_json(filename, lineno, line): return [] try: sentence = json.loads(line) - if u"time" not in sentence: + if "time" not in sentence: return [] - return [event(sentence[u"tag"].encode("iso-8859-1"), "%.2f" % sentence[u"time"])] - except ValueError, e: - print line.rstrip() - print e + return [event(polystr(sentence["class"]), "%.2f" % isotime(sentence["time"]))] + except ValueError as e: + print(line.rstrip(), file=sys.stderr) + print(repr(e), file=sys.stderr) return [] def extract_timestamped_sentences(fp, json_parse=parse_json): @@ -119,7 +128,7 @@ def extract_timestamped_sentences(fp, json_parse=parse_json): sequence = [] lineno = 0 while True: - line = fp.readline() + line = polystr(fp.readline()) if not line: break lineno += 1 @@ -140,9 +149,9 @@ def analyze(sequence, name): if not sequence: return if "sequence" in stages: - print "Raw tag/timestamp sequence" + print("Raw tag/timestamp sequence") for e in sequence: - print e + print(e) # Then, do cycle detection events = [] out_of_order = False @@ -161,9 +170,9 @@ def analyze(sequence, name): if out_of_order and verbose: sys.stderr.write("%s: has some timestamps out of order.\n" % name) if "events" in stages: - print "Event list:" + print("Event list:") for e in events: - print e + print(e) # Now group events into bursts bursts = [] current = [] @@ -174,9 +183,9 @@ def analyze(sequence, name): else: current.append(e) if "bursts" in stages: - print "Burst list:" + print("Burst list:") for burst in bursts: - print burst + print(burst) # We need 4 cycles because the first and last might be incomplete. if tags(events).count("<") < 4: sys.stderr.write("%s: has fewer than 4 cycles.\n" % name) @@ -196,7 +205,7 @@ def analyze(sequence, name): if "trim" in stages: "After trimming:" for burst in bursts: - print burst + print(burst) # Now the actual clique analysis unequal = False for i in range(len(bursts)-1): @@ -208,7 +217,7 @@ def analyze(sequence, name): # Should know now if cycle is regular if regular: if not suppress_regular: - print "%s: has a regular cycle %s." % (name, " ".join(tags(bursts[0]))) + print("%s: has a regular cycle %s." % (name, " ".join(tags(bursts[0])))) else: # If it was not the case that all cycles matched, then we need # a minimum of 6 cycles because the first and last might be @@ -218,16 +227,16 @@ def analyze(sequence, name): sys.stderr.write("%s: variable-cycle log has has fewer than 6 cycles.\n" % name) return if verbose > 0: - print "%s: has a split or variable cycle." % name + print("%s: has a split or variable cycle." % name) cycle_enders = [] for burst in bursts: if burst[-1].tag not in cycle_enders: cycle_enders.append(burst[-1].tag) if len(cycle_enders) == 1: if not suppress_regular: - print "%s: has a fixed end-of-cycle sentence %s." % (name, cycle_enders[0]) + print("%s: has a fixed end-of-cycle sentence %s." % (name, cycle_enders[0])) else: - print "%s: has multiple cycle-enders %s." % (name, " ".join(cycle_enders)) + print("%s: has multiple cycle-enders %s." % (name, " ".join(cycle_enders))) # Sanity check pathological = [] for ender in cycle_enders: @@ -235,7 +244,7 @@ def analyze(sequence, name): if ender in tags(burst) and not ender == burst[-1].tag and not ender in pathological: pathological.append(ender) if pathological: - print "%s: cycle-enders %s also occur in mid-cycle!" % (name, " ".join(pathological)) + print("%s: cycle-enders %s also occur in mid-cycle!" % (name, " ".join(pathological))) if __name__ == "__main__": stages = "" @@ -250,32 +259,31 @@ if __name__ == "__main__": verbose += 1 elif (switch == '-s'): # Suppress logs with no problems suppress_regular = True - except getopt.GetoptError, msg: - print "cycle_analyzer: " + str(msg) - raise SystemExit, 1 + except getopt.GetoptError as msg: + print("cycle_analyzer: " + str(msg)) + raise SystemExit(1) try: if arguments: for filename in arguments: - fp = open(filename) + fp = open(filename, 'rb') try: sequence = extract_timestamped_sentences(fp) analyze(sequence, filename) - except analyze_error, e: + except analyze_error as e: if filename.endswith(".log") and os.path.exists(filename+".chk"): - fp2 = open(filename+".chk") + fp2 = open(filename+".chk", "rb") try: sequence = extract_timestamped_sentences(fp2, json_parse=True) analyze(sequence, filename+".chk") finally: fp2.close() else: - print e + print(repr(e), file=sys.stderr) fp.close() else: sequence = extract_timestamped_sentences(sys.stdin) analyze(sequence, "standard input") - except analyze_error, e: - print str(e) - raise SystemExit, 1 - + except analyze_error as e: + print(repr(e), file=sys.stderr) + raise SystemExit(1) diff --git a/devtools/gps b/devtools/gps new file mode 120000 index 00000000..3673ce63 --- /dev/null +++ b/devtools/gps @@ -0,0 +1 @@ +../gps
\ No newline at end of file |