1import csv 2 3from ..common.info import ID, UNKNOWN 4from ..common.util import read_tsv 5from .info import Variable 6 7 8# XXX need tests: 9# * read_file() 10# * look_up_variable() 11 12 13COLUMNS = ('filename', 'funcname', 'name', 'kind', 'declaration') 14HEADER = '\t'.join(COLUMNS) 15 16 17def read_file(infile, *, 18 _read_tsv=read_tsv, 19 ): 20 """Yield (kind, id, decl) for each row in the data file. 21 22 The caller is responsible for validating each row. 23 """ 24 for row in _read_tsv(infile, HEADER): 25 filename, funcname, name, kind, declaration = row 26 if not funcname or funcname == '-': 27 funcname = None 28 id = ID(filename, funcname, name) 29 yield kind, id, declaration 30 31 32def from_file(infile, *, 33 handle_var=Variable.from_id, 34 _read_file=read_file, 35 ): 36 """Return the info for known declarations in the given file.""" 37 known = { 38 'variables': {}, 39 #'types': {}, 40 #'constants': {}, 41 #'macros': {}, 42 } 43 for kind, id, decl in _read_file(infile): 44 if kind == 'variable': 45 values = known['variables'] 46 value = handle_var(id, decl) 47 else: 48 raise ValueError(f'unsupported kind in row {row}') 49 value.validate() 50 values[id] = value 51 return known 52 53 54def look_up_variable(varid, knownvars, *, 55 match_files=(lambda f1, f2: f1 == f2), 56 ): 57 """Return the known Variable matching the given ID. 58 59 "knownvars" is a mapping of ID to Variable. 60 61 "match_files" is used to verify if two filenames point to 62 the same file. 63 64 If no match is found then None is returned. 65 """ 66 if not knownvars: 67 return None 68 69 if varid.funcname == UNKNOWN: 70 if not varid.filename or varid.filename == UNKNOWN: 71 for varid in knownvars: 72 if not varid.funcname: 73 continue 74 if varid.name == varid.name: 75 return knownvars[varid] 76 else: 77 return None 78 else: 79 for varid in knownvars: 80 if not varid.funcname: 81 continue 82 if not match_files(varid.filename, varid.filename): 83 continue 84 if varid.name == varid.name: 85 return knownvars[varid] 86 else: 87 return None 88 elif not varid.filename or varid.filename == UNKNOWN: 89 raise NotImplementedError 90 else: 91 return knownvars.get(varid.id) 92