diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2018-07-19 19:48:26 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2018-07-19 19:48:26 +0200 |
commit | 7ae9791c59ab4037c9c16a86fe998ef116e0dd10 (patch) | |
tree | 53859394e2711cb1458ae2664bf0185bf704fa51 | |
parent | 16515ddc78fce017f3b577f0a58e0f0288d1512e (diff) |
scripts/verify_log_statements.py: figure out line numbers
Change-Id: Ib75c8f5a99ed556d85896b7f8c65fb9446a2fbce
-rwxr-xr-x | scripts/verify_log_statements.py | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/scripts/verify_log_statements.py b/scripts/verify_log_statements.py index 48f406b..6108c23 100755 --- a/scripts/verify_log_statements.py +++ b/scripts/verify_log_statements.py @@ -22,26 +22,57 @@ log_statement_re = re.compile(r'^[ \t]*LOG[_A-Z]+\(([^";,]*,)*[ \t\r\n]*(("[^"]* re.MULTILINE | re.DOTALL) fmt_re = re.compile(r'("[^"]*".*)*fmt') -errors_found = 0 debug = ('-d' in sys.argv) or ('--debug' in sys.argv) args = [x for x in sys.argv[1:] if not (x == '-d' or x == '--debug')] if not args: args = ['.'] +class error_found: + def __init__(self, f, charpos, msg, text): + self.f = f + self.charpos = charpos + self.msg = msg + self.text = text + self.line = None + +def make_line_idx(file_content): + line_idx = [] + pos = 0 + line_nr = 1 + line_idx.append((pos, line_nr)) + for line in file_content.split('\n'): + pos += len(line) + line_nr += 1 + line_idx.append((pos, line_nr)) + pos += 1 # newline char + return line_idx + +def char_pos_2_line(line_idx, sorted_char_positions): + r = [] + line_i = 0 + next_line_i = 1 + for char_pos in sorted_char_positions: + while (line_i+1) < len(line_idx) and char_pos > line_idx[line_i+1][0]: + line_i += 1 + r.append(line_idx[line_i][1]) + return r def check_file(f): - global errors_found if not (f.endswith('.h') or f.endswith('.c') or f.endswith('.cpp')): - return + return [] - for log in log_statement_re.finditer(codecs.open(f, "r", "utf-8").read()): + errors_found = [] + + file_content = codecs.open(f, "r", "utf-8").read() + + for log in log_statement_re.finditer(file_content): quoted = log.group(2) # Skip 'LOG("bla" fmt )' strings that typically appear as #defines. if fmt_re.match(quoted): if debug: - print('Skipping define:', f, '\n'+log.group(0)) + errors_found.append(error_found(f, log.start(), 'Skipping define', log.group(0))) continue # Drop PRI* parts of 'LOG("bla %"PRIu64" foo")' @@ -56,15 +87,14 @@ def check_file(f): except: # hopefully eval broke because of some '## args' macro def if debug: - print('Ignoring:', f, '\n'+log.group(0)) + ignored.append(error_found(f, log.start(), 'Ignoring', log.group(0))) continue # check for errors... # final newline if not quoted.endswith('\n'): - print('Missing final newline:', f, '\n'+log.group(0)) - errors_found += 1 + errors_found.append(error_found(f, log.start(), 'Missing final newline', log.group(0))) # disallowed chars and extra newlines for c in quoted[:-1]: @@ -73,15 +103,33 @@ def check_file(f): msg = 'Extraneous newline' else: msg = 'Illegal char' - print('%s %r in' % (msg, c), f, '\n' + log.group(0)) - errors_found += 1 + errors_found.append(error_found(f, log.start(), msg + ' %r' % c, log.group(0))) + + if not error_found: + return [] + + line_idx = make_line_idx(file_content) + for r, line in zip(errors_found, char_pos_2_line(line_idx, [rr.charpos for rr in errors_found])): + r.line = line + + return errors_found + +all_errors_found = [] for f in args: if os.path.isdir(f): for parent_path, subdirs, files in os.walk(f, None, None): for ff in files: - check_file(os.path.join(parent_path, ff)) + all_errors_found.extend(check_file(os.path.join(parent_path, ff))) else: - check_file(f) + all_errors_found.extend(check_file(f)) + +def print_errors(errs): + for err in errs: + print('%s: %s:%d\n%s\n' % (err.msg, err.f, err.line or 0, err.text)) + +print_errors(all_errors_found) + +sys.exit(len(all_errors_found)) -sys.exit(errors_found) +# vim: tabstop=2 shiftwidth=2 expandtab |