123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2021 The MOPSA Project. *)(* *)(* This program is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License as published *)(* by the Free Software Foundation, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Breakpoints for the interactive mode *)openMopsa_utilsopenCore.AllopenFormatopenLocation(** Breakpoint *)typebreakpoint=|B_functionofstring(** function *)(** Break at the beginning of a function *)|B_lineofstring(** file *)*int(** line *)(** Break at line *)|B_namedofstring(** Named breakpoint *)|B_alarm(** Break on new alarms *)(** Compare two breakpoints *)letcompare_breakpointb1b2:int=matchb1,b2with|B_function(f1),B_function(f2)->comparef1f2|B_line(file1,line1),B_line(file2,line2)->Compare.paircomparecompare(file1,line1)(file2,line2)|B_namedb1,B_namedb2->String.compareb1b2|B_alarm,B_alarm->0|_->compareb1b2(** Print a breakpoint *)letpp_breakpointfmt=function|B_functionf->Format.fprintffmt"%s"f|B_line(file,line)->Format.fprintffmt"%s:%d"fileline|B_namedb->Format.fprintffmt"@%s"b|B_alarm->Format.pp_print_stringfmt"#alarm"(** Set of breakpoints *)moduleBreakpointSet=SetExt.Make(structtypet=breakpointletcompare=compare_breakpointend)(** Print a set of breakpoints *)letpp_breakpoint_setfmtbs=Format.fprintffmt"@[<v>%a@]"(Format.pp_print_list~pp_sep:(funfmt()->Format.fprintffmt"@,")pp_breakpoint)(BreakpointSet.elementsbs)(** Exception raised when parsing an invalid breakpoint string *)exceptionInvalid_breakpoint_syntax(** Parse a breakpoint string *)letparse_breakpointdefault_file(s:string):breakpoint=ifStr.string_match(Str.regexp"@\\(.+\\)$")s0thenletname=Str.matched_group1sinB_namednameelseifStr.string_match(Str.regexp"#alarm$")s0||Str.string_match(Str.regexp"#a$")s0thenB_alarmelseifStr.string_match(Str.regexp"\\([0-9]+\\)$")s0thenletfile=default_fileinletline=int_of_string(Str.matched_group1s)inB_line(file,line)elseifStr.string_match(Str.regexp"\\(.+\\):\\([0-9]+\\)$")s0thenletfile=Str.matched_group1sinletline=int_of_string(Str.matched_group2s)inB_line(file,line)elseifStr.string_match(Str.regexp"\\([^0-9].*\\)$")s0thenletfunc=Str.matched_group1sinB_function(func)elseraiseInvalid_breakpoint_syntax(** Set of active breakpoints *)letbreakpoints=refBreakpointSet.empty