(root)/
Python-3.12.0/
Tools/
c-analyzer/
c_parser/
datafiles.py
       1  import os.path
       2  
       3  from c_common import fsutil
       4  import c_common.tables as _tables
       5  import c_parser.info as _info
       6  
       7  
       8  BASE_COLUMNS = [
       9      'filename',
      10      'funcname',
      11      'name',
      12      'kind',
      13  ]
      14  END_COLUMNS = {
      15      'parsed': 'data',
      16      'decls': 'declaration',
      17  }
      18  
      19  
      20  def _get_columns(group, extra=None):
      21      return BASE_COLUMNS + list(extra or ()) + [END_COLUMNS[group]]
      22      #return [
      23      #    *BASE_COLUMNS,
      24      #    *extra or (),
      25      #    END_COLUMNS[group],
      26      #]
      27  
      28  
      29  #############################
      30  # high-level
      31  
      32  def read_parsed(infile):
      33      # XXX Support other formats than TSV?
      34      columns = _get_columns('parsed')
      35      for row in _tables.read_table(infile, columns, sep='\t', fix='-'):
      36          yield _info.ParsedItem.from_row(row, columns)
      37  
      38  
      39  def write_parsed(items, outfile):
      40      # XXX Support other formats than TSV?
      41      columns = _get_columns('parsed')
      42      rows = (item.as_row(columns) for item in items)
      43      _tables.write_table(outfile, columns, rows, sep='\t', fix='-')
      44  
      45  
      46  def read_decls(infile, fmt=None):
      47      if fmt is None:
      48          fmt = _get_format(infile)
      49      read_all, _ = _get_format_handlers('decls', fmt)
      50      for decl, _ in read_all(infile):
      51          yield decl
      52  
      53  
      54  def write_decls(decls, outfile, fmt=None, *, backup=False):
      55      if fmt is None:
      56          fmt = _get_format(infile)
      57      _, write_all = _get_format_handlers('decls', fmt)
      58      write_all(decls, outfile, backup=backup)
      59  
      60  
      61  #############################
      62  # formats
      63  
      64  def _get_format(file, default='tsv'):
      65      if isinstance(file, str):
      66          filename = file
      67      else:
      68          filename = getattr(file, 'name', '')
      69      _, ext = os.path.splitext(filename)
      70      return ext[1:] if ext else default
      71  
      72  
      73  def _get_format_handlers(group, fmt):
      74      # XXX Use a registry.
      75      if group != 'decls':
      76          raise NotImplementedError(group)
      77      if fmt == 'tsv':
      78          return (_iter_decls_tsv, _write_decls_tsv)
      79      else:
      80          raise NotImplementedError(fmt)
      81  
      82  
      83  # tsv
      84  
      85  def iter_decls_tsv(infile, extracolumns=None, relroot=fsutil.USE_CWD):
      86      if relroot and relroot is not fsutil.USE_CWD:
      87          relroot = os.path.abspath(relroot)
      88      for info, extra in _iter_decls_tsv(infile, extracolumns):
      89          decl = _info.Declaration.from_row(info)
      90          decl = decl.fix_filename(relroot, formatted=False, fixroot=False)
      91          yield decl, extra
      92  
      93  
      94  def write_decls_tsv(decls, outfile, extracolumns=None, *,
      95                      relroot=fsutil.USE_CWD,
      96                      **kwargs
      97                      ):
      98      if relroot and relroot is not fsutil.USE_CWD:
      99          relroot = os.path.abspath(relroot)
     100      decls = (d.fix_filename(relroot, fixroot=False) for d in decls)
     101      # XXX Move the row rendering here.
     102      _write_decls_tsv(decls, outfile, extracolumns, kwargs)
     103  
     104  
     105  def _iter_decls_tsv(infile, extracolumns=None):
     106      columns = _get_columns('decls', extracolumns)
     107      for row in _tables.read_table(infile, columns, sep='\t'):
     108          if extracolumns:
     109              declinfo = row[:4] + row[-1:]
     110              extra = row[4:-1]
     111          else:
     112              declinfo = row
     113              extra = None
     114          # XXX Use something like tables.fix_row() here.
     115          declinfo = [None if v == '-' else v
     116                      for v in declinfo]
     117          yield declinfo, extra
     118  
     119  
     120  def _write_decls_tsv(decls, outfile, extracolumns, kwargs):
     121      columns = _get_columns('decls', extracolumns)
     122      if extracolumns:
     123          def render_decl(decl):
     124              if type(row) is tuple:
     125                  decl, *extra = decl
     126              else:
     127                  extra = ()
     128              extra += ('???',) * (len(extraColumns) - len(extra))
     129              *row, declaration = _render_known_row(decl)
     130              row += extra + (declaration,)
     131              return row
     132      else:
     133          render_decl = _render_known_decl
     134      _tables.write_table(
     135          outfile,
     136          header='\t'.join(columns),
     137          rows=(render_decl(d) for d in decls),
     138          sep='\t',
     139          **kwargs
     140      )
     141  
     142  
     143  def _render_known_decl(decl, *,
     144                         # These match BASE_COLUMNS + END_COLUMNS[group].
     145                         _columns = 'filename parent name kind data'.split(),
     146                         ):
     147      if not isinstance(decl, _info.Declaration):
     148          # e.g. Analyzed
     149          decl = decl.decl
     150      rowdata = decl.render_rowdata(_columns)
     151      return [rowdata[c] or '-' for c in _columns]
     152      # XXX
     153      #return _tables.fix_row(rowdata[c] for c in columns)