Skip to content

Instantly share code, notes, and snippets.

@jonashaag
Last active February 8, 2016 08:43
Show Gist options
  • Save jonashaag/d9297a6a0c6b5e251687 to your computer and use it in GitHub Desktop.
Save jonashaag/d9297a6a0c6b5e251687 to your computer and use it in GitHub Desktop.
Parser for gnu global output
import re
import urllib
import subprocess
import collections
def drop_dupes(iterator):
return collections.OrderedDict.fromkeys(iterator).keys()
def read_lines(path):
with open(path) as f:
return f.read().splitlines()
def execute_global(args):
return subprocess.check_output(["global", "--result", "cscope", "--encode-path", " "] + args)
def parse_global_output(output):
def parse_line(line):
sourcefile, symbol, lineno, context = line.split(' ', 3)
sourcefile = urllib.unquote(sourcefile)
lineno = int(lineno) - 1
return sourcefile, symbol, lineno
return [parse_line(line) for line in drop_dupes(output.splitlines())]
def find_symbol_matches(line, symbol):
SYMBOL_RE = "(^|\W)%s($|\W)"
def _match_span(match):
span_start, span_end = match.span()
prefix, suffix = match.groups()
return (span_start + len(prefix), span_end - len(suffix))
return map(_match_span, re.finditer(SYMBOL_RE % re.escape(symbol), line))
def find_references(sourcefile):
source_lines = read_lines(sourcefile)
output = execute_global(["-f", sourcefile, "-r"])
references = [[] for _ in range(len(source_lines))]
for _, symbol, lineno in parse_global_output(output):
matches = find_symbol_matches(source_lines[lineno], symbol)
references[lineno].append((symbol, matches))
return references
def find_definitions(symbol):
output = execute_global(["-d", symbol])
return [(sourcefile, lineno) for sourcefile, _, lineno in parse_global_output(output)]
if __name__ == '__main__':
import sys
import pprint
if sys.argv[1] == '-r':
print(find_references(sys.argv[2]))
else:
print(find_definitions(sys.argv[1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment