1import os.path
2
3from c_common import fsutil
4import c_common.tables as _tables
5import c_parser.info as _info
6import c_parser.match as _match
7import c_parser.datafiles as _parser
8from . import analyze as _analyze
9
10
11#############################
12# "known" decls
13
14EXTRA_COLUMNS = [
15    #'typedecl',
16]
17
18
19def get_known(known, extracolumns=None, *,
20              analyze_resolved=None,
21              handle_unresolved=True,
22              relroot=fsutil.USE_CWD,
23              ):
24    if isinstance(known, str):
25        known = read_known(known, extracolumns, relroot)
26    return analyze_known(
27        known,
28        handle_unresolved=handle_unresolved,
29        analyze_resolved=analyze_resolved,
30    )
31
32
33def read_known(infile, extracolumns=None, relroot=fsutil.USE_CWD):
34    extracolumns = EXTRA_COLUMNS + (
35        list(extracolumns) if extracolumns else []
36    )
37    known = {}
38    for decl, extra in _parser.iter_decls_tsv(infile, extracolumns, relroot):
39        known[decl] = extra
40    return known
41
42
43def analyze_known(known, *,
44                  analyze_resolved=None,
45                  handle_unresolved=True,
46                  ):
47    knowntypes = knowntypespecs = {}
48    collated = _match.group_by_kinds(known)
49    types = {decl: None for decl in collated['type']}
50    typespecs = _analyze.get_typespecs(types)
51    def analyze_decl(decl):
52        return _analyze.analyze_decl(
53            decl,
54            typespecs,
55            knowntypespecs,
56            types,
57            knowntypes,
58            analyze_resolved=analyze_resolved,
59        )
60    _analyze.analyze_type_decls(types, analyze_decl, handle_unresolved)
61    return types, typespecs
62
63
64def write_known(rows, outfile, extracolumns=None, *,
65                relroot=fsutil.USE_CWD,
66                backup=True,
67                ):
68    extracolumns = EXTRA_COLUMNS + (
69        list(extracolumns) if extracolumns else []
70    )
71    _parser.write_decls_tsv(
72        rows,
73        outfile,
74        extracolumns,
75        relroot=relroot,
76        backup=backup,
77    )
78
79
80#############################
81# ignored vars
82
83IGNORED_COLUMNS = [
84    'filename',
85    'funcname',
86    'name',
87    'reason',
88]
89IGNORED_HEADER = '\t'.join(IGNORED_COLUMNS)
90
91
92def read_ignored(infile, relroot=fsutil.USE_CWD):
93    return dict(_iter_ignored(infile, relroot))
94
95
96def _iter_ignored(infile, relroot):
97    if relroot and relroot is not fsutil.USE_CWD:
98        relroot = os.path.abspath(relroot)
99    bogus = {_tables.EMPTY, _tables.UNKNOWN}
100    for row in _tables.read_table(infile, IGNORED_HEADER, sep='\t'):
101        *varidinfo, reason = row
102        if _tables.EMPTY in varidinfo or _tables.UNKNOWN in varidinfo:
103            varidinfo = tuple(None if v in bogus else v
104                              for v in varidinfo)
105        if reason in bogus:
106            reason = None
107        varid = _info.DeclID.from_row(varidinfo)
108        varid = varid.fix_filename(relroot, formatted=False, fixroot=False)
109        yield varid, reason
110
111
112def write_ignored(variables, outfile, relroot=fsutil.USE_CWD):
113    raise NotImplementedError
114    if relroot and relroot is not fsutil.USE_CWD:
115        relroot = os.path.abspath(relroot)
116    reason = '???'
117    #if not isinstance(varid, DeclID):
118    #    varid = getattr(varid, 'parsed', varid).id
119    decls = (d.fix_filename(relroot, fixroot=False) for d in decls)
120    _tables.write_table(
121        outfile,
122        IGNORED_HEADER,
123        sep='\t',
124        rows=(r.render_rowdata() + (reason,) for r in decls),
125    )
126