Add script for pretty-printing geany tags files
[geany-mirror.git] / scripts / print-tags.py
blobcb26cc2e479ef3a04c51a3f6a64709688d893181
1 #!/usr/bin/env python3
3 import sys
5 # see tm_source_file.c
6 TA_NAME, TA_LINE, TA_LOCAL, TA_POS, TA_TYPE, TA_ARGLIST, TA_SCOPE, \
7 TA_VARTYPE, TA_INHERITS, TA_TIME, TA_ACCESS, TA_IMPL, TA_LANG, \
8 TA_INACTIVE, TA_FLAGS = range(200, 215)
10 # see TMTagType in tm_parser.h
11 types = [
12 "undef", "class", "enum", "enumerator", "field", "function",
13 "interface", "member", "method", "namespace", "package",
14 "prototype", "struct", "typedef", "union", "variable", "externvar",
15 "macro", "macro_arg", "file", "other",
16 "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN",
19 type_dct = {0: types[0]}
20 for i in range(len(types) - 1):
21 type_dct[1 << i] = types[i + 1]
24 def decode_kind(kind, value):
25 val = ''
26 if kind == TA_NAME:
27 val = value.decode('utf-8')
28 elif kind == TA_LINE:
29 val = int(value)
30 elif kind == TA_LOCAL:
31 val = int(value)
32 elif kind == TA_TYPE:
33 val = type_dct[int(value)]
34 elif kind == TA_ARGLIST:
35 val = value.decode('utf-8')
36 elif kind == TA_SCOPE:
37 val = value.decode('utf-8')
38 elif kind == TA_FLAGS:
39 val = int(value)
40 elif kind == TA_VARTYPE:
41 val = value.decode('utf-8')
42 elif kind == TA_INHERITS:
43 val = value.decode('utf-8')
44 elif kind == TA_TIME:
45 pass;
46 elif kind == TA_LANG:
47 pass;
48 elif kind == TA_INACTIVE:
49 pass;
50 elif kind == TA_ACCESS:
51 val = value.decode('utf-8')
52 elif kind == TA_IMPL:
53 val = value.decode('utf-8')
54 return val
57 def print_tag(tag):
58 res = '{:<12}'.format(tag[TA_TYPE] + ': ')
59 if TA_VARTYPE in tag:
60 res += tag[TA_VARTYPE] + ' '
61 if TA_SCOPE in tag:
62 res += tag[TA_SCOPE] + ' :: '
63 res += tag[TA_NAME]
64 if TA_ARGLIST in tag:
65 res += tag[TA_ARGLIST]
66 if TA_INHERITS in tag:
67 res += ' extends ' + tag[TA_INHERITS]
68 if TA_FLAGS in tag and tag[TA_FLAGS] > 0:
69 res += ' flags: ' + str(tag[TA_FLAGS])
70 # stdout.buffer (stdin.buffer) needed to write (read) binary data, see:
71 # https://docs.python.org/3/library/sys.html?highlight=stdout#sys.stdout
72 sys.stdout.buffer.write(res.encode('utf-8'))
73 sys.stdout.buffer.write(b'\n')
76 def get_next_part(inp, pos, first):
77 part = b''
78 c = inp[pos]
79 if first:
80 kind = TA_NAME
81 else:
82 kind = c
83 pos += 1
84 c = inp[pos]
85 while c < TA_NAME and c != ord('\n'):
86 part += bytes([c])
87 pos += 1
88 c = inp[pos]
89 return part, kind, pos
92 inp = sys.stdin.buffer.read()
94 tag = {}
95 pos = 0
96 line_start_pos = 0
97 line_start = True
98 first_line = True
99 while pos < len(inp):
100 part, kind, pos = get_next_part(inp, pos, line_start)
101 value = decode_kind(kind, part)
102 tag[kind] = value
103 line_start = False
104 if inp[pos] == ord('\n'):
105 if first_line:
106 pass # first line contains '# format=tagmanager' we want to skip
107 else:
108 sys.stdout.buffer.write(inp[line_start_pos:pos])
109 sys.stdout.buffer.write(b'\n')
110 print_tag(tag)
111 first_line = False
112 tag = {}
113 pos += 1
114 line_start_pos = pos
115 line_start = True