12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Utils for ZF} *)openLogtkmoduleA=UntypedASTtypeparse_cache=(string,unit)Hashtbl.tletcreate_parse_cache()=Hashtbl.create8typeparser_res=(UntypedAST.statementIter.t,string)CCResult.ttype'aparser_='a->parser_resletfind_filename~dir:stringoption=Util.debugf2"search `%s` in `%s`"(funk->knamedir);letabs_path=Filename.concatdirnameinifSys.file_existsabs_paththenSomeabs_pathelseNoneletrecparse_lexbuf_?cache?(recursive=true)~dirlex=letl=Parse_zf.parse_statement_listLex_zf.tokenlexinifrecursivethen(letcache=CCOpt.get_lazycreate_parse_cachecacheinCCList.flat_map(funst->matchst.A.stmtwith|A.Includes->beginmatchfind_files~dirwith|None->Util.errorf~where:"utils_zf""could not find included file `%s`"s|Somes'whenHashtbl.memcaches'->[](* already included *)|Somes'->(* put in cache *)Hashtbl.addcaches'();parse_file_~cache~recursives'end|_->[st])l)elselandparse_file_?cache?recursivefile=CCIO.with_infile(funic->letlexbuf=Lexing.from_channelicinParseLocation.set_filelexbuffile;letdir=Filename.dirnamefileinparse_lexbuf_?cache?recursive~dirlexbuf)letparse_lexbuf?cache?recursivefile:parser_res=tryparse_lexbuf_?cache?recursive~dir:"."file|>Iter.of_list|>CCResult.returnwithe->CCResult.of_exneletparse_stdin():parser_res=letlexbuf=Lexing.from_channelstdininParseLocation.set_filelexbuf"stdin";parse_lexbuf~recursive:falselexbufletparse_file?cache?recursivefile:parser_res=iffile="stdin"thenparse_stdin()elsetryparse_file_?cache?recursivefile|>Iter.of_list|>CCResult.returnwith|Sys_errore->CCResult.fail(Util.err_spf"sys_error when parsing `%s`:@ %s"filee)|e->CCResult.of_exne