|
56 | 56 | import subprocess |
57 | 57 | import sys |
58 | 58 |
|
59 | | -from typing import Callable, List, NoReturn, Optional, TYPE_CHECKING |
| 59 | +from typing import Callable, cast, List, NoReturn, Optional, TYPE_CHECKING |
60 | 60 |
|
61 | 61 | from chc.cmdline.AnalysisManager import AnalysisManager |
62 | 62 | from chc.cmdline.ParseManager import ParseManager |
|
71 | 71 | from chc.util.loggingutil import chklogger, LogLevel |
72 | 72 |
|
73 | 73 | if TYPE_CHECKING: |
| 74 | + from chc.invariants.CInvariantFact import CInvariantNRVFact |
74 | 75 | from chc.proof.CFunctionPO import CFunctionPO |
75 | 76 |
|
76 | 77 |
|
@@ -665,6 +666,62 @@ def header(s: str) -> str: |
665 | 666 | exit(0) |
666 | 667 |
|
667 | 668 |
|
| 669 | +def cfile_query_invariants(args: argparse.Namespace) -> NoReturn: |
| 670 | + |
| 671 | + # arguments |
| 672 | + xcfilename: str = args.filename |
| 673 | + opttgtpath: Optional[str] = args.tgtpath |
| 674 | + xfunction: str = args.function |
| 675 | + xline: int = args.line |
| 676 | + |
| 677 | + projectpath = os.path.dirname(os.path.abspath(xcfilename)) |
| 678 | + targetpath = projectpath if opttgtpath is None else opttgtpath |
| 679 | + targetpath = os.path.abspath(targetpath) |
| 680 | + cfilename_c = os.path.basename(xcfilename) |
| 681 | + cfilename = cfilename_c[:-2] |
| 682 | + projectname = cfilename |
| 683 | + |
| 684 | + cchpath = UF.get_cchpath(targetpath, projectname) |
| 685 | + contractpath = os.path.join(targetpath, "chc_contracts") |
| 686 | + |
| 687 | + if not UF.check_analysis_results_files(targetpath, projectname, None, cfilename): |
| 688 | + print_error("No analysis results found for " + cfilename |
| 689 | + + ". Please run analyzer first.") |
| 690 | + exit(1) |
| 691 | + |
| 692 | + capp = CApplication( |
| 693 | + projectpath, projectname, targetpath, contractpath, singlefile=True) |
| 694 | + capp.initialize_single_file(cfilename) |
| 695 | + cfile = capp.get_cfile() |
| 696 | + |
| 697 | + if not cfile.has_function_by_name(xfunction): |
| 698 | + print_error("No function found with name " + xfunction) |
| 699 | + exit(1) |
| 700 | + |
| 701 | + cfun = cfile.get_function_by_name(xfunction) |
| 702 | + ppos = cfun.get_ppos() |
| 703 | + contexts = {ppo.context for ppo in ppos if ppo.line == xline} |
| 704 | + |
| 705 | + print("Invariants for function " + xfunction + ", line " + str(xline)) |
| 706 | + if len(contexts) == 0: |
| 707 | + print("\nNo ast positions found with invariants on line " + str(xline) + ".") |
| 708 | + exit(0) |
| 709 | + |
| 710 | + for ctxt in contexts: |
| 711 | + print("\nAST position: " + str(ctxt)) |
| 712 | + print("-" * (len(str(ctxt)) + 14)) |
| 713 | + invs = cfun.invarianttable.get_sorted_invariants(ctxt) |
| 714 | + nrvfacts: List[str] = [] |
| 715 | + for inv in invs: |
| 716 | + if inv.is_nrv_fact: |
| 717 | + inv = cast("CInvariantNRVFact", inv) |
| 718 | + if not inv.variable.is_check_variable: |
| 719 | + nrvfacts.append(str(inv)) |
| 720 | + print("\n".join(nrvfacts)) |
| 721 | + |
| 722 | + exit(0) |
| 723 | + |
| 724 | + |
668 | 725 | def cfile_testlibc_summary(args: argparse.Namespace) -> NoReturn: |
669 | 726 | """Runs one of the programs in tests/libcsummaries |
670 | 727 |
|
|
0 commit comments