Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

bpo-36876: Fix the C analyzer tool.#22841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Pull in some updates.
  • Loading branch information
@ericsnowcurrently
ericsnowcurrently committedOct 22, 2020
commita72e916e18bf94ac270d1a5aa2d99c0e7c8e0348
19 changes: 19 additions & 0 deletionsTools/c-analyzer/c_analyzer/__init__.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,3 +82,22 @@ def analyze_decl(decl):
raise NotImplementedError((decl, resolved))

yield decl, resolved


#######################################
# checks

def check_all(analysis, checks, *, failfast=False):
for check in checks or ():
for data, failure in check(analysis):
if failure is None:
continue

yield data, failure
if failfast:
yield None, None
break
else:
continue
# We failed fast.
break
94 changes: 66 additions & 28 deletionsTools/c-analyzer/c_analyzer/__main__.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@
from c_parser.info import KIND, is_type_decl
from . import (
analyze as _analyze,
check_all as _check_all,
datafiles as _datafiles,
)

Expand All@@ -37,14 +38,6 @@
logger = logging.getLogger(__name__)


def show_failure(failure, data, *, verbosity=VERBOSITY):
if verbosity >= 3:
logger.info(f'failure: {failure}')
logger.info(f'data: {data}')
else:
logger.warn(f'failure: {failure} (data: {data})')


#######################################
# table helpers

Expand DownExpand Up@@ -149,6 +142,52 @@ def add_checks_cli(parser, checks=None, *, add_flags=None):
]


def _get_check_handlers(fmt, printer, verbosity=VERBOSITY):
div = None
def handle_after():
pass
if not fmt:
div = ''
def handle_failure(failure, data):
data = repr(data)
if verbosity >= 3:
logger.info(f'failure: {failure}')
logger.info(f'data: {data}')
else:
logger.warn(f'failure: {failure} (data: {data})')
elif fmt == 'raw':
def handle_failure(failure, data):
print(f'{failure!r} {data!r}')
elif fmt == 'brief':
def handle_failure(failure, data):
print(f'{data.filename}\t{data.parent or "-"}\t{data.name}\t{failure!r}')
elif fmt == 'summary':
failures = []
def handle_failure(failure, data):
failures.append((failure, data))
def handle_after():
# XXX
raise NotImplementedError
elif fmt == 'full':
div = ''
def handle_failure(failure, data):
name = data.shortkey if data.kind is KIND.VARIABLE else data.name
parent = data.parent or ''
funcname = parent if isinstance(parent, str) else parent.name
known = 'yes' if data.is_known else '*** NO ***'
print(f'{data.kind.value} {name!r} failed ({failure})')
print(f' file: {data.filename}')
print(f' func: {funcname or "-"}')
print(f' name: {data.name}')
print(f' data: ...')
print(f' type unknown: {known}')
else:
if fmt in FORMATS:
raise NotImplementedError(fmt)
raise ValueError(f'unsupported fmt {fmt!r}')
return handle_failure, handle_after, div


#######################################
# the formats

Expand DownExpand Up@@ -207,8 +246,8 @@ def fmt_full(analysis):
}


def add_output_cli(parser):
parser.add_argument('--format', dest='fmt', default='summary', choices=tuple(FORMATS))
def add_output_cli(parser, *, default='summary'):
parser.add_argument('--format', dest='fmt', default=default, choices=tuple(FORMATS))

def process_args(args):
pass
Expand All@@ -231,7 +270,7 @@ def process_checks(args):
args.checks = [check]
else:
process_checks = add_checks_cli(parser, checks=checks)
process_output = add_output_cli(parser)
process_output = add_output_cli(parser, default=None)
process_files = add_files_cli(parser, **kwargs)
return [
process_checks,
Expand All@@ -243,6 +282,7 @@ def process_checks(args):
def cmd_check(filenames, *,
checks=None,
ignored=None,
fmt=None,
failfast=False,
iter_filenames=None,
verbosity=VERBOSITY,
Expand All@@ -254,7 +294,11 @@ def cmd_check(filenames, *,
checks = _CHECKS
elif isinstance(checks, str):
checks = [checks]
checks = [_CHECKS[c] if isinstance(c, str) else c
for c in checks]
printer = Printer(verbosity)
(handle_failure, handle_after, div
) = _get_check_handlers(fmt, printer, verbosity)

filenames = filter_filenames(filenames, iter_filenames)

Expand All@@ -263,26 +307,20 @@ def cmd_check(filenames, *,

logger.info('checking...')
numfailed = 0
for check in checks:
if isinstance(check, str):
check = _CHECKS[check]
for data, failure in check(analyzed):
if failure is None:
continue
if numfailed > 0:
printer.info()
numfailed += 1
show_failure(failure, data, verbosity=verbosity)
if failfast:
printer.info('stopping after one failure')
break
else:
continue
# We failed fast.
break
for data, failure in _check_all(analyzed, checks, failfast=failfast):
if data is None:
printer.info('stopping after one failure')
break
if div is not None and numfailed > 0:
printer.info(div)
numfailed += 1
handle_failure(failure, data)
handle_after()

printer.info('-------------------------')
logger.info(f'total failures: {numfailed}')
logger.info('done checking')

if numfailed > 0:
sys.exit(numfailed)

Expand Down
82 changes: 13 additions & 69 deletionsTools/c-analyzer/c_analyzer/datafiles.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
import os.path

import c_common.tables as _tables
import c_common.iterutil as _iterutil
import c_parser.info as _info
import c_parser.datafiles as _parser
from . import analyze as _analyze


#############################
# "known" decls

KNOWN_COLUMNS = [
'filename',
'funcname',
'name',
'kind',
EXTRA_COLUMNS = [
#'typedecl',
'declaration',
]


Expand DownExpand Up@@ -55,80 +48,31 @@ def get_known(known, extracolumns=None, *,


def read_known(infile, extracolumns=None, relroot=None):
extracolumns = EXTRA_COLUMNS + (
list(extracolumns) if extracolumns else []
)
known = {}
for info in _iter_known(infile, extracolumns, relroot):
decl, extra = info
for decl, extra in _parser.iter_decls_tsv(infile, extracolumns, relroot):
known[decl] = extra
return known


def _iter_known(infile, extracolumns, relroot):
if extracolumns:
# Always put the declaration last.
columns = KNOWN_COLUMNS[:-1] + extracolumns + KNOWN_COLUMNS[-1:]
else:
columns = KNOWN_COLUMNS
header = '\t'.join(columns)
for row in _tables.read_table(infile, header, sep='\t'):
if extracolumns:
declinfo = row[:4] + row[-1:]
extra = row[4:-1]
else:
declinfo = row
extra = None
if relroot:
# XXX Use something like tables.fix_row() here.
declinfo = [None if v == '-' else v
for v in declinfo]
declinfo[0] = os.path.join(relroot, declinfo[0])
decl = _info.Declaration.from_row(declinfo)
yield decl, extra


def write_known(rows, outfile, extracolumns=None, *,
relroot=None,
backup=True,
):
if extracolumns:
# Always put the declaration last.
columns = KNOWN_COLUMNS[:-1] + extracolumns + KNOWN_COLUMNS[-1]
def render_decl(decl):
if type(row) is tuple:
decl, *extra = decl
else:
extra = ()
extra += ('???',) * (len(extraColumns) - len(extra))
*row, declaration = _render_known_row(decl, relroot)
row += extra + (declaration,)
return row
else:
columns = KNOWN_COLUMNS
render_decl = _render_known_decl
_tables.write_table(
extracolumns = EXTRA_COLUMNS + (
list(extracolumns) if extracolumns else []
)
_parser.write_decls_tsv(
rows,
outfile,
header='\t'.join(columns),
rows=(render_decl(d, relroot) for d in rows),
sep='\t',
extracolumns,
relroot=relroot,
backup=backup,
)


def _render_known_decl(row, relroot):
if isinstance(row, _info.Declaration):
decl = row
elif not isinstance(row, _info.Declaration):
# e.g. Analyzed
decl = row.decl
# These match KNOWN_COLUMNS.
columns = 'filename parent name kind data'.split()
rowdata = decl.render_rowdata(columns)
if relroot:
rowdata['filename'] = os.path.relpath(rowdata['filename'], relroot)
return [rowdata[c] or '-' for c in columns]
# XXX
#return _tables.fix_row(rowdata[c] for c in columns)


#############################
# ignored vars

Expand Down
7 changes: 6 additions & 1 deletionTools/c-analyzer/c_common/fsutil.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,7 +20,12 @@ def create_backup(old, backup=None):
return None
if not backup or backup is True:
backup = f'{filename}.bak'
shutil.copyfile(filename, backup)
try:
shutil.copyfile(filename, backup)
except FileNotFoundError as exc:
if exc.filename != filename:
raise # re-raise
backup = None
return backup


Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp