1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495(*
* Copyright (c) 2014 Leo White <leo@lpw25.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openOdoc_modelopenOr_errortypeunit_content=Lang.Compilation_unit.ttypecontent=|Page_contentofLang.Page.t|Source_tree_contentofLang.SourceTree.t|Unit_contentofunit_contenttypet={content:content;warnings:Odoc_model.Error.tlist}(** Written at the top of the files. Checked when loading. *)letmagic="odoc-%%VERSION%%"(** Exceptions while saving are allowed to leak. *)letsave_unitfile(root:Root.t)(t:t)=Fs.Directory.mkdir_p(Fs.File.dirnamefile);letoc=open_out_bin(Fs.File.to_stringfile)inoutput_stringocmagic;Marshal.to_channelocroot[];Marshal.to_channeloct[];close_outocletsave_pagefile~warningspage=letdir=Fs.File.dirnamefileinletbase=Fs.File.(to_string@@basenamefile)inletfile=ifAstring.String.is_prefix~affix:"page-"basethenfileelseFs.File.create~directory:dir~name:("page-"^base)insave_unitfilepage.Lang.Page.root{content=Page_contentpage;warnings}letsave_source_treefile~warningssrc_page=letdir=Fs.File.dirnamefileinletbase=Fs.File.(to_string@@basenamefile)inletfile=ifAstring.String.is_prefix~affix:"src-"basethenfileelseFs.File.create~directory:dir~name:("src-"^base)insave_unitfilesrc_page.Lang.SourceTree.root{content=Source_tree_contentsrc_page;warnings}letsave_unitfile~warningsm=save_unitfilem.Lang.Compilation_unit.root{content=Unit_contentm;warnings}letload_filef=letfile=Fs.File.to_stringfilein(ifSys.file_existsfilethenOkfileelseError(`Msg(Printf.sprintf"File does not exist")))>>=funfile->letic=open_in_binfileinletres=tryletactual_magic=really_input_stringic(String.lengthmagic)inifactual_magic=magicthenletroot=Marshal.from_channelicinficrootelseletmsg=Printf.sprintf"%s: invalid magic number %S, expected %S\n%!"fileactual_magicmagicinError(`Msgmsg)withexn->letmsg=Printf.sprintf"Error while unmarshalling %S: %s\n%!"file(matchexnwithFailures->s|_->Printexc.to_stringexn)inError(`Msgmsg)inclose_inic;resletloadfile=load_file(funic_->Ok(Marshal.from_channelic))(** The root is saved separately in the files to support this function. *)letload_rootfile=load_file(fun_root->Okroot)