|
38 | 38 | from contextlib import contextmanager |
39 | 39 |
|
40 | 40 | from typing import ( |
41 | | - Any, cast, Dict, Generator, List, Optional, NoReturn, TYPE_CHECKING) |
| 41 | + Any, cast, Dict, Generator, List, Optional, NoReturn, Tuple, TYPE_CHECKING) |
42 | 42 |
|
43 | 43 | from chc.app.CApplication import CApplication |
44 | 44 |
|
@@ -291,6 +291,7 @@ def cproject_report_file(args: argparse.Namespace) -> NoReturn: |
291 | 291 | filename: str = args.filename |
292 | 292 | showcode: bool = args.showcode |
293 | 293 | showopen: bool = args.open |
| 294 | + showinvariants: bool = args.showinvariants |
294 | 295 |
|
295 | 296 | targetpath = os.path.abspath(tgtpath) |
296 | 297 | projectpath = targetpath |
@@ -320,7 +321,8 @@ def pofilter(po: "CFunctionPO") -> bool: |
320 | 321 | return True |
321 | 322 |
|
322 | 323 | if showcode: |
323 | | - print(RP.file_code_tostring(cfile, pofilter=pofilter)) |
| 324 | + print(RP.file_code_tostring( |
| 325 | + cfile, pofilter=pofilter, showinvs=showinvariants)) |
324 | 326 |
|
325 | 327 | print(RP.file_proofobligation_stats_tostring(cfile)) |
326 | 328 |
|
@@ -523,6 +525,58 @@ def collect_fi_callees(cfile: "CFile") -> None: |
523 | 525 | exit(0) |
524 | 526 |
|
525 | 527 |
|
| 528 | +def cproject_collect_call_arguments(args: argparse.Namespace) -> NoReturn: |
| 529 | + |
| 530 | + # arguments |
| 531 | + tgtpath: str = args.tgtpath |
| 532 | + projectname: str = args.projectname |
| 533 | + |
| 534 | + targetpath = os.path.abspath(tgtpath) |
| 535 | + projectpath = targetpath |
| 536 | + contractpath = os.path.join(targetpath, "chc_contracts") |
| 537 | + |
| 538 | + if not UF.has_analysisresults_path(targetpath, projectname): |
| 539 | + print_error( |
| 540 | + f"No analysis results found for {projectname} in {targetpath}") |
| 541 | + exit(1) |
| 542 | + |
| 543 | + capp = CApplication( |
| 544 | + projectpath, projectname, targetpath, contractpath) |
| 545 | + |
| 546 | + # callee -> (file, caller) -> arguments |
| 547 | + result: Dict[str, Dict[Tuple[int, str, str], List[str]]] = {} |
| 548 | + |
| 549 | + counter: int = 0 |
| 550 | + for cfile in capp.cfiles: |
| 551 | + for cfun in cfile.get_functions(): |
| 552 | + for instr in cfun.call_instrs: |
| 553 | + callee = str(instr.callee) |
| 554 | + callargs = instr.callargs |
| 555 | + result.setdefault(callee, {}) |
| 556 | + result[callee][(counter, cfile.cfilename, cfun.name)] = [ |
| 557 | + str(i) for i in callargs] |
| 558 | + counter += 1 |
| 559 | + |
| 560 | + lines: List[str] = [] |
| 561 | + |
| 562 | + for callee in sorted(result): |
| 563 | + lines.append("\n" + callee) |
| 564 | + lines.append("-" * len(callee)) |
| 565 | + for (index, cfilename, caller) in sorted(result[callee]): |
| 566 | + calltxt = ( |
| 567 | + callee |
| 568 | + + "(" |
| 569 | + + ", ".join(result[callee][(index, cfilename, caller)]) |
| 570 | + + ")") |
| 571 | + lines.append( |
| 572 | + ("[" + cfilename + ".c:" + caller + "] ").ljust(35) |
| 573 | + + calltxt) |
| 574 | + |
| 575 | + print("\n".join(lines)) |
| 576 | + |
| 577 | + exit(0) |
| 578 | + |
| 579 | + |
526 | 580 | def cproject_missing_summaries(args: argparse.Namespace) -> NoReturn: |
527 | 581 | """CLI command to output library functions without summaries.""" |
528 | 582 |
|
|
0 commit comments