12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2024 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* 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, version 2.1. *)(* *)(* It 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. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)letrecgcdab=ifa=0thenabsbelseifb=0thenabsaelsegcdb(amodb)let(%.)=gcd(* -------------------------------------------------------------------------- *)(* --- Range Maps --- *)(* -------------------------------------------------------------------------- *)type'arange={offset:int;length:int;data:'a;}letpp_rangefmtr=Format.fprintffmt"%04d..%04d"r.offset(r.offset+r.length-1)letpp_offsetfmtr=Format.fprintffmt"%04d:%04d"r.offsetr.lengthtype'at=Rof'arangelist(* sorted, no-overlap *)letempty=R[]letsingletonr=ifnot(0<=r.offset&&0<r.length)thenraise(Invalid_argument"Region.Ranges.singleton");R[r]letrange?(offset=0)?(length=1)data=singleton{offset;length;data}letrecfind(k:int)=function|[]->raiseNot_found|({offset;length}asr)::rs->ifoffset<=k&&k<=offset+lengththenrelsefindkrsletfindk(Rrs)=findkrsletrecmergefrarb=matchra,rbwith|[],rs|rs,[]->rs|a::wa,b::wb->leta'=a.offset+a.lengthinletb'=b.offset+b.lengthinifa'<=b.offsetthena::mergefwarbelseifb'<a.offsetthenb::mergefrawbelseletoffset=mina.offsetb.offsetinletlength=maxa'b'-offsetinletdata=fabinletr={offset;length;data}inifa'<b'thenmergefwa(r::wb)elsemergef(r::wa)wbletmergef(Rx)(Ry)=R(mergefxy)letsquashf=function|R[]->None|R(x::xs)->Some(List.fold_left(funwr->fwr.data)x.dataxs)letiterif(Rxs)=List.iterfxsletiterf(Rxs)=List.iter(funr->fr.data)xsletmapf(Rxs)=R(List.map(funr->{rwithdata=fr.data})xs)(* -------------------------------------------------------------------------- *)