|
56 | 56 | import subprocess |
57 | 57 | import sys |
58 | 58 |
|
| 59 | + |
59 | 60 | from typing import ( |
60 | 61 | Any, Callable, cast, Dict, List, NoReturn, Optional, TYPE_CHECKING) |
61 | 62 |
|
|
73 | 74 | from chc.util.loggingutil import chklogger, LogLevel |
74 | 75 |
|
75 | 76 | if TYPE_CHECKING: |
| 77 | + from chc.invariants.CInvariantFact import CInvariantNRVFact |
76 | 78 | from chc.app.CAttributes import CAttributes |
77 | 79 | from chc.app.CInstr import CCallInstr |
78 | 80 | from chc.app.CTyp import ( |
@@ -942,6 +944,62 @@ def header(s: str) -> str: |
942 | 944 | exit(0) |
943 | 945 |
|
944 | 946 |
|
| 947 | +def cfile_query_invariants(args: argparse.Namespace) -> NoReturn: |
| 948 | + |
| 949 | + # arguments |
| 950 | + xcfilename: str = args.filename |
| 951 | + opttgtpath: Optional[str] = args.tgtpath |
| 952 | + xfunction: str = args.function |
| 953 | + xline: int = args.line |
| 954 | + |
| 955 | + projectpath = os.path.dirname(os.path.abspath(xcfilename)) |
| 956 | + targetpath = projectpath if opttgtpath is None else opttgtpath |
| 957 | + targetpath = os.path.abspath(targetpath) |
| 958 | + cfilename_c = os.path.basename(xcfilename) |
| 959 | + cfilename = cfilename_c[:-2] |
| 960 | + projectname = cfilename |
| 961 | + |
| 962 | + cchpath = UF.get_cchpath(targetpath, projectname) |
| 963 | + contractpath = os.path.join(targetpath, "chc_contracts") |
| 964 | + |
| 965 | + if not UF.check_analysis_results_files(targetpath, projectname, None, cfilename): |
| 966 | + print_error("No analysis results found for " + cfilename |
| 967 | + + ". Please run analyzer first.") |
| 968 | + exit(1) |
| 969 | + |
| 970 | + capp = CApplication( |
| 971 | + projectpath, projectname, targetpath, contractpath, singlefile=True) |
| 972 | + capp.initialize_single_file(cfilename) |
| 973 | + cfile = capp.get_cfile() |
| 974 | + |
| 975 | + if not cfile.has_function_by_name(xfunction): |
| 976 | + print_error("No function found with name " + xfunction) |
| 977 | + exit(1) |
| 978 | + |
| 979 | + cfun = cfile.get_function_by_name(xfunction) |
| 980 | + ppos = cfun.get_ppos() |
| 981 | + contexts = {ppo.context for ppo in ppos if ppo.line == xline} |
| 982 | + |
| 983 | + print("Invariants for function " + xfunction + ", line " + str(xline)) |
| 984 | + if len(contexts) == 0: |
| 985 | + print("\nNo ast positions found with invariants on line " + str(xline) + ".") |
| 986 | + exit(0) |
| 987 | + |
| 988 | + for ctxt in contexts: |
| 989 | + print("\nAST position: " + str(ctxt)) |
| 990 | + print("-" * (len(str(ctxt)) + 14)) |
| 991 | + invs = cfun.invarianttable.get_sorted_invariants(ctxt) |
| 992 | + nrvfacts: List[str] = [] |
| 993 | + for inv in invs: |
| 994 | + if inv.is_nrv_fact: |
| 995 | + inv = cast("CInvariantNRVFact", inv) |
| 996 | + if not inv.variable.is_check_variable: |
| 997 | + nrvfacts.append(str(inv)) |
| 998 | + print("\n".join(nrvfacts)) |
| 999 | + |
| 1000 | + exit(0) |
| 1001 | + |
| 1002 | + |
945 | 1003 | def cfile_testlibc_summary(args: argparse.Namespace) -> NoReturn: |
946 | 1004 | """Runs one of the programs in tests/libcsummaries |
947 | 1005 |
|
|
0 commit comments