12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455letlocation_errorf~loc=Format.ksprintf(funerr->raise(Ocaml_common.Location.Error(Ocaml_common.Location.error~locerr)))(* Same as [List.find_map] introduced in OCaml 4.10. *)letrecfind_mapf=function|[]->None|x::l->(matchfxwith|Some_asresult->result|None->find_mapfl)(* Return the list of paths we should try using, in order. *)letget_candidate_paths~locpath=letsource_dir=loc.Ocaml_common.Location.loc_start.pos_fname|>Filename.dirnameinifFilename.is_relativepaththenletabsolute_path=Filename.concatsource_dirpathin(* Try the path relative to the source file first, then the one relative to the
current working directory (typically, the build directory). *)[absolute_path;path]else(* The user passed an absolute path. Use as is. *)[path]letread_filepath=tryletfile=open_in_binpathinFun.protect~finally:(fun()->close_in_noerrfile)(fun()->Some(really_input_stringfile(in_channel_lengthfile)))with_->Noneletget_blob~locpath=matchfind_mapread_file(get_candidate_paths~locpath)with|Someblob->blob|None->location_errorf~loc"[%%blob] could not find or load file %s"pathletexpand~ctxtpath=letopenPpxlibinletloc=Expansion_context.Extension.extension_point_locctxtinAst_builder.Default.estring~loc(get_blob~locpath)letextension=letopenPpxlibinExtension.V3.declare"blob"Extension.Context.expressionAst_pattern.(single_expr_payload(estring__))expandletrule=Ppxlib.Context_free.Rule.extensionextensionlet()=Ppxlib.Driver.register_transformation~rules:[rule]"ppx_blob"