123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)openLocationtypet=Lidentofstring|Ldotoftloc*stringloc|Lapplyoftloc*tlocletrecsamett'=t==t'||matcht,t'with|Lidents,Lidents'->String.equalss'|Ldot({txt=t;_},{txt=s;_}),Ldot({txt=t';_},{txt=s';_})->ifString.equalss'thensamett'elsefalse|Lapply({txt=tl;_},{txt=tr;_}),Lapply({txt=tl';_},{txt=tr';_})->sametltl'&&sametrtr'|_,_->falseletrecflataccu=functionLidents->s::accu|Ldot({txt=lid;_},{txt=s;_})->flat(s::accu)lid|Lapply(_,_)->Misc.fatal_error"Longident.flat"letflattenlid=flat[]lidletrechead=functionLidents->s|Ldot(lid,_)->headlid.txt|Lapply(_,_)->assertfalseletlast=functionLidents->s|Ldot(_,s)->s.txt|Lapply(_,_)->Misc.fatal_error"Longident.last"letrecsplit_at_dotsspos=tryletdot=String.index_fromspos'.'inString.subspos(dot-pos)::split_at_dotss(dot+1)withNot_found->[String.subspos(String.lengths-pos)]letunflattenl=matchlwith|[]->None|hd::tl->Some(List.fold_left(funps->Ldot(mknolocp,mknolocs))(Lidenthd)tl)letparses=matchunflatten(split_at_dotss0)with|None->Lident""(* should not happen, but don't put assert false
so as not to crash the toplevel (see Genprintval) *)|Somev->vletkeep_suffix=letrecaux=function|{txt=Lidentstr;_}ast->ifString.uncapitalize_asciistr<>strthenSome(t,false)elseNone|{txt=Ldot(t,str);loc}->ifString.uncapitalize_asciistr.txt<>str.txtthenmatchauxtwith|None->Some({txt=Lidentstr.txt;loc=str.loc},true)|Some(t,is_label)->Some({txt=Ldot(t,str);loc},is_label)elseNone|t->Some(t,false)(* Can be improved... *)infunction|Lidents->Lidents,false|Ldot(t,s)->beginmatchauxtwith|None->Lidents.txt,true|Some(t,is_label)->Ldot(t,s),is_labelend|otherwise->otherwise,false