123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2014 Hugo Heuzard
*
* This program is free software; 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, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*)open!Stdlibletexpand_pathextsrealvirt=letreclooprealfilevirtfileacc=iftrySys.is_directoryrealfilewith_->falsethenArray.fold_left(Sys.readdirrealfile)~init:acc~f:(funaccs->loop(Filename.concatrealfiles)(Filename.concatvirtfiles)acc)elsetryletexmatch=tryletb=Filename.basenamerealfileinleti=String.rindexb'.'inlete=String.subb~pos:(i+1)~len:(String.lengthb-i-1)inList.meme~set:extswithNot_found->List.mem""~set:extsinifList.is_emptyexts||exmatchthen(virtfile,realfile)::accelseaccwithexc->warn"ignoring %s: %s@."realfile(Printexc.to_stringexc);accinlooprealvirt[]letlist_filesnamepaths=letname,virtname=matchString.lsplit2name~on:':'with|Some(src,dest)->ifString.lengthdest>0&¬(Char.equaldest.[0]'/')thenfailwith(Printf.sprintf"path '%s' for file '%s' must be absolute"destsrc);letvirtname=ifChar.equaldest.[String.lengthdest-1]'/'thendest^Filename.basenamesrcelsedestinsrc,virtname|None->(* by default, files are store in /static/ directory *)name,"/static/"^Filename.basenamenameinletname,exts(* extensions filter *)=matchString.lsplit2name~on:'='with|Some(name,exts)->name,String.split_char~sep:','exts|None->name,[]inletfile=ifFilename.is_relativenamethentryFindlib.find_in_findlib_pathspathsnamewithNot_found->failwith(Printf.sprintf"file '%s' not found"name)elsenameinexpand_pathextsfilevirtnameletfind_cmipathsbase=letname,filename=tryletname=String.uncapitalize_asciibase^".cmi"inname,Findlib.find_in_findlib_pathspathsnamewithNot_found->letname=String.capitalize_asciibase^".cmi"inname,Findlib.find_in_findlib_pathspathsnameinFilename.concat"/static/cmis"name,filenameletinstr_of_name_contentprim~name~content=letopenCodeinLet(Var.fresh(),Prim(Externprim,[Pc(IStringname);Pc(IStringcontent)]))letembed_file~name~filename=instr_of_name_content"caml_create_file_extern"~name~content:(Fs.read_filefilename)letinit()=Code.(Let(Var.fresh(),Prim(Extern"caml_fs_init",[])))letf~prim~cmis~files~paths=letprim=matchprimwith|`caml_create_file->"caml_create_file"|`caml_create_file_extern->"caml_create_file_extern"inletcmi_files,missing_cmis=StringSet.fold(funs(acc,missing)->tryletname,filename=find_cmipathssin(name,Fs.read_filefilename)::acc,missingwithNot_found->acc,s::missing)cmis([],[])inifnot(List.is_emptymissing_cmis)then(warn"Some OCaml interface files were not found.@.";warn"Use [-I dir_of_cmis] option to bring them into scope@.";(* [`ocamlc -where`/expunge in.byte out.byte moduleA moduleB ... moduleN] *)List.itermissing_cmis~f:(funnm->warn" %s@."nm));letother_files=List.mapfiles~f:(funf->List.map(list_filesfpaths)~f:(fun(name,filename)->name,Fs.read_filefilename))|>List.concatinList.map(other_files@cmi_files)~f:(fun(name,content)->instr_of_name_contentprim~name~content)