123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(**************************************************************************)(* *)(* OCaml *)(* *)(* Fabrice Le Fessant, INRIA Saclay *)(* *)(* Copyright 2012 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. *)(* *)(**************************************************************************)openStdlibletread_magic_numberic=letlen_magic_number=String.lengthConfig.cmt_magic_numberinreally_input_stringiclen_magic_number(* Binary annotations. The typed tree layout depends on the compiler that
wrote the file, so the trees are kept opaque here and decoded by a
compiler-specific backend. *)typebinary_annots=|PackedofObj.t*stringlist|ImplementationofObj.t|InterfaceofObj.t|Partial_implementationofObj.t|Partial_interfaceofObj.t(* Simplified cmt_infos *)typecmt_infos={cmt_modname:string;cmt_annots:binary_annots;cmt_value_dependencies:(Types.value_description*Types.value_description)list;cmt_comments:(string*unit)list;(* Location.t -> unit *)cmt_args:stringarray;cmt_sourcefile:stringoption;cmt_builddir:string;cmt_loadpath:stringlist;cmt_source_digest:stringoption;cmt_initial_env:Env.t;cmt_imports:(string*Digest.toption)list;cmt_interface_digest:Digest.toption;cmt_use_summaries:bool;}(* Error handling *)exceptionErrorofstringletinput_cmtic=(input_valueic:cmt_infos)(* Several compiler releases write different format versions, so [read]
accepts any version and returns the CMT magic number with the infos.
Callers must check the version before reading fields of the infos. *)letcmi_magic_prefix="Caml1999I"letcmt_magic_prefix="Caml1999T"lethas_prefixprefixmagic_number=String.starts_with~prefixmagic_numberletreadfilename=(* Printf.fprintf stderr "Cmt_format.read %s\n%!" filename; *)letic=open_in_binfilenameintryletmagic_number=read_magic_numbericinletcmi,cmt=ifhas_prefixcmt_magic_prefixmagic_numberthen(None,Some(magic_number,input_cmtic))elseifhas_prefixcmi_magic_prefixmagic_numberthenletcmi=Cmi_format.input_cmiicinletcmt=tryletmagic_number=read_magic_numbericinifhas_prefixcmt_magic_prefixmagic_numberthenletcmt=input_cmticinSome(magic_number,cmt)elseNonewith_->Nonein(Somecmi,cmt)elseraise(Error"Invalid magic number")inclose_inic;(* Printf.fprintf stderr "Cmt_format.read done\n%!"; *)(cmi,cmt)withe->close_inic;raiseeletread_cmt_with_magicfilename=matchreadfilenamewith|_,None->raise(Error"Not a typedtree")|_,Somecmt->cmtletread_cmtfilename=snd(read_cmt_with_magicfilename)letread_cmifilename=matchreadfilenamewith|None,_->raise(Error"Not an interface")|Somecmi,_->cmi