12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091(**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*)includeSystypet=stringletdummy_path:t=""letcat=Sys_utils.catletcompare=Pervasives.compareletdirname=Filename.dirname(**
* Resolves a path (using realpath)
*
* The advantage of using a path instead of strings is that you
* don't need to care about symlinks or trailing slashes: each
* path gets normalized by calling realpath.
*
* A few things to keep in mind:
* - paths are always absolute. So the empty string "" becomes
* the current directory (in absolute)
*)letmakepath=matchSys_utils.realpathpathwith|Somepath->path|None->path(* assert false? *)(**
* Creates a Path without running it through `realpath`. This is unsafe because
* it doesn't normalize symlinks, trailing slashes, or relative paths. The path
* you pass here must be absolute, and free of symlinks (including ../).
*)letmake_unsafepath=pathletto_stringpath=pathletconcatpathmore=make(Filename.concatpathmore)letparentpath=ifis_directorypaththenmake(concatpathFilename.parent_dir_name)elsemake(Filename.dirnamepath)letoutput=output_stringletslash_escaped_string_of_pathpath=letbuf=Buffer.create(String.lengthpath)inString.iter(funch->matchchwith|'\\'->Buffer.add_stringbuf"zB"|':'->Buffer.add_stringbuf"zC"|'/'->Buffer.add_stringbuf"zS"|'\x00'->Buffer.add_stringbuf"z0"|'z'->Buffer.add_stringbuf"zZ"|_->Buffer.add_charbufch)path;Buffer.contentsbufletpath_of_slash_escaped_stringstr=letlength=String.lengthstrinletbuf=Buffer.createlengthinletrecconsumei=ifi>=lengththen()elseletreplacement=ifi<length-1&&str.[i]='z'thenmatchstr.[i+1]with|'B'->Some'\\'|'C'->Some':'|'S'->Some'/'|'0'->Some'\x00'|'Z'->Some'z'|_->NoneelseNoneinletc,next_i=matchreplacementwith|Somer->r,i+2|None->str.[i],i+1inBuffer.add_charbufc;consumenext_iinconsume0;make(Buffer.contentsbuf)