1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#!/usr/bin/env python
#
# This file is Copyright by the GPSD project
# SPDX-License-Identifier: BSD-2-Clause
#
"""Hack program to check GPSD .chk files for empty SKY reports."""
from __future__ import print_function
import ast
import os
import sys
class Error(Exception):
"""Base error class."""
class ParseError(Error):
"""Error for parsing error."""
def ProcessFile(name, withname=False, verbose=False, quiet=False,
quieter=False):
"""Process contents of one file."""
bad = []
linenum = 0
with open(name, encoding=None) as f:
data = f.readlines()
for line in data:
linenum += 1
sline = line.rstrip()
rline = sline.replace('false', 'False').replace('true', 'True')
if not rline.startswith('{'):
continue
try:
parsed = ast.literal_eval(rline)
except ValueError as exc:
raise ParseError('line %d' % linenum, exc.message, rline)
if ((parsed.get('class') == 'SKY' and
not parsed.get('nSat', 0))):
bad.append([linenum, parsed])
if quieter or quiet and not len(bad):
return len(bad), linenum
if withname:
print(os.path.basename(name) + ': ', len(bad))
else:
print(len(bad))
if verbose:
for linenum, item in bad:
print(' %d: %s' % (linenum, repr(item)))
return len(bad), linenum
def Plural(num, single='', multi='s'):
"""Get single/plural suffix for count."""
return single if num == 1 else multi
def Usage(cmd, out):
"""Print usage text."""
def uprint(msg):
print(msg, file=out)
uprint('Usage is: %s [options] <file>...' % os.path.basename(cmd))
uprint('\tOptions are:')
uprint('\t-h:\tHelp - print this text')
uprint("\t-q:\tQuiet - don't list nonoffending file(s)")
uprint("\t-Q:\tReally quiet - don't list any individual file(s)")
uprint('\t-t:\tTotals - print totals at end')
uprint('\t-v:\tVerbose - print each offending line')
def main(argv):
"""main function."""
args = argv[1:]
opts_ok = set(list('hqQtv'))
opts = dict([(o, False) for o in opts_ok])
while args and args[0].startswith('-'):
optarg = args[0]
newopts = set(list(optarg[1:]))
badopts = newopts - opts_ok
if badopts:
print("Bad option%s: '%s' in '%s'" %
(Plural(len(badopts)),
''.join(sorted(list(badopts))), optarg),
file=sys.stderr)
return 3
opts.update(dict([(o, True) for o in list(newopts)]))
args = args[1:]
if opts['h']:
Usage(argv[0], sys.stdout)
return 0
if not args:
Usage(argv[0], sys.stderr)
return 2
withname = len(args) > 1
badlines = totlines = badfiles = files = 0
for name in args:
bad, total = ProcessFile(name, withname=withname,
verbose=opts['v'],
quiet=opts['q'], quieter=opts['Q'])
badlines += bad
totlines += total
badfiles += 1 if bad else 0
files += 1
if opts['t']:
print('Totals: %d empty of %d SKY line%s in %d of %d file%s' %
(badlines, totlines, Plural(totlines),
badfiles, files, Plural(files)))
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
|