| import csv |
| |
| from ..common.info import ID, UNKNOWN |
| from ..common.util import read_tsv |
| from .info import Variable |
| |
| |
| # XXX need tests: |
| # * read_file() |
| # * look_up_variable() |
| |
| |
| COLUMNS = ('filename', 'funcname', 'name', 'kind', 'declaration') |
| HEADER = '\t'.join(COLUMNS) |
| |
| |
| def read_file(infile, *, |
| _read_tsv=read_tsv, |
| ): |
| """Yield (kind, id, decl) for each row in the data file. |
| |
| The caller is responsible for validating each row. |
| """ |
| for row in _read_tsv(infile, HEADER): |
| filename, funcname, name, kind, declaration = row |
| if not funcname or funcname == '-': |
| funcname = None |
| id = ID(filename, funcname, name) |
| yield kind, id, declaration |
| |
| |
| def from_file(infile, *, |
| handle_var=Variable.from_id, |
| _read_file=read_file, |
| ): |
| """Return the info for known declarations in the given file.""" |
| known = { |
| 'variables': {}, |
| #'types': {}, |
| #'constants': {}, |
| #'macros': {}, |
| } |
| for kind, id, decl in _read_file(infile): |
| if kind == 'variable': |
| values = known['variables'] |
| value = handle_var(id, decl) |
| else: |
| raise ValueError(f'unsupported kind in row {row}') |
| value.validate() |
| values[id] = value |
| return known |
| |
| |
| def look_up_variable(varid, knownvars, *, |
| match_files=(lambda f1, f2: f1 == f2), |
| ): |
| """Return the known Variable matching the given ID. |
| |
| "knownvars" is a mapping of ID to Variable. |
| |
| "match_files" is used to verify if two filenames point to |
| the same file. |
| |
| If no match is found then None is returned. |
| """ |
| if not knownvars: |
| return None |
| |
| if varid.funcname == UNKNOWN: |
| if not varid.filename or varid.filename == UNKNOWN: |
| for varid in knownvars: |
| if not varid.funcname: |
| continue |
| if varid.name == varid.name: |
| return knownvars[varid] |
| else: |
| return None |
| else: |
| for varid in knownvars: |
| if not varid.funcname: |
| continue |
| if not match_files(varid.filename, varid.filename): |
| continue |
| if varid.name == varid.name: |
| return knownvars[varid] |
| else: |
| return None |
| elif not varid.filename or varid.filename == UNKNOWN: |
| raise NotImplementedError |
| else: |
| return knownvars.get(varid.id) |