123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121(*********************************************************************************)(* Ojs-base *)(* *)(* Copyright (C) 2014-2021 INRIA. All rights reserved. *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU General Public License as *)(* published by the Free Software Foundation, version 3 of the License. *)(* *)(* 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 Library General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public *)(* License along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* As a special exception, you have permission to link this program *)(* with the OCaml compiler and distribute executables, as long as you *)(* follow the requirements of the GNU GPL in regard to all of the *)(* software in the executable aside from the OCaml compiler. *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** *)typet={abs:bool;path:stringlist;}[@@derivingyojson]moduleOrd=structtypeu=ttypet=uletcompare=Stdlib.compareendmoduleMap=Map.Make(Ord)moduleSet=Set.Make(Ord)letdir_sep=String.getFilename.dir_sep0letempty={abs=false;path=[]}letroot={abs=true;path=[]}letis_absolutep=p.absletpathp=p.path(*c==v=[String.split_string]=1.2====*)letsplit_string?(keep_empty=false)schars=letlen=String.lengthsinletreciteraccpos=ifpos>=lenthenmatchaccwith""->ifkeep_emptythen[""]else[]|_->[acc]elseifList.mems.[pos]charsthenmatchaccwith""->ifkeep_emptythen""::iter""(pos+1)elseiter""(pos+1)|_->acc::(iter""(pos+1))elseiter(Printf.sprintf"%s%c"accs.[pos])(pos+1)initer""0(*/c==v=[String.split_string]=1.2====*)letof_strings=letpath=split_strings[dir_sep]inletabs=String.lengths>0&&String.gets0=dir_sepin{abs;path}letto_stringp=Printf.sprintf"%s%s"(ifp.absthenFilename.dir_sepelse"")(String.concatFilename.dir_sepp.path)letbasenamep=matchList.revp.pathwith[]->failwith"Path.basename: Invalid argument"|f::_->fletparentp=matchList.revp.pathwith|[]->{abs=false;path=[]}|_::q->{pwithpath=List.revq}letappendp1l={p1withpath=p1.path@l}letappend_pathp1p2={p1withpath=p1.path@p2.path}letis_prefix=letreciter=functionh1::q1,h2::q2->h1=h2&&iter(q1,q2)|[],_->true|_::_,[]->falseinfunp1p2->iter(p1.path,p2.path)letnormalizepath=letreciteracc=function[]->List.revacc|h::q->ifh=Filename.current_dir_nametheniteraccqelseifh=Filename.parent_dir_namethenmatchaccwith[]->[]|_::r->iterrqelseiter(h::acc)qin{pathwithpath=iter[]path.path}