123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155(********************************************************************************)(* xdg-basedir: XDG basedir location for data/cache/configuration files *)(* *)(* Copyright (C) 2011, OCamlCore SARL *)(* *)(* This library 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; either version 2.1 of the License, or (at *)(* your option) any later version, with the OCaml static compilation *)(* exception. *)(* *)(* This library 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 file COPYING.txt for more *)(* details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this library; if not, write to the Free Software Foundation, *)(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)(********************************************************************************)(** XDG basedir specification
@author Sylvain Le Gall
*)openFilePathopenUnixtypefilename=stringtypedirname=stringtypedirnames=dirnamelisttypet={data_home:dirname;data_dirs:dirnames;config_home:dirname;config_dirs:dirnames;cache_home:dirname;}letdefault=letnot_founddefaultvar=trydefault()withNot_found->failwith(Printf.sprintf"Environment variable '%s' not defined"var)inletgetenv?(default=fun()->raiseNot_found)var=matchSys.getenvvarwith|exceptionNot_found->not_founddefaultvar|""->not_founddefaultvar|var->varinlethome=getenv"HOME"~default:(fun()->(getpwuid(getuid())).pw_dir)inletmk_var_genfenvwin32unix=letlst=ifSys.os_type="Win32"thenwin32elseunixingetenv~default:(fun()->f(Lazy.forcelst))envinletmk_var=mk_var_genmake_filenameinletmk_var_pathenvwin32unix=path_of_string(mk_var_gen(funs->s)envwin32unix)in{data_home=mk_var"XDG_DATA_HOME"(lazy[getenv"AppData"])(lazy[home;".local";"share"]);data_dirs=mk_var_path"XDG_DATA_DIRS"(lazy(getenv"ProgramFiles"))(lazy"/usr/local/share:/usr/share");config_home=mk_var"XDG_CONFIG_HOME"(lazy[home;"Local Settings"])(lazy[home;".config"]);config_dirs=mk_var_path"XDG_CONFIG_DIRS"(lazy(getenv"ProgramFiles"))(lazy"/etc/xdg");cache_home=mk_var"XDG_CACHE_HOME"(lazy[home;"Local Settings";"Cache"])(lazy[home;".cache"]);}letdir_exists?(exists=false)dn=(notexists)||(Sys.file_existsdn&&Sys.is_directorydn)letfile_exists?(exists=false)fn=(notexists)||Sys.file_existsfnletmk_fundatatestcomb=letfilter_comblst?existsa=List.fold_right(funfnacc->letfn'=combfnainiftest?existsfn'thenfn'::accelseacc)lst[]inletuser_dir?(xdg_env=default)?existsa=lethome,_=dataxdg_envinletfn=combhomeainiftest?existsfnthenfnelseraiseNot_foundinletsystem_dirs?(xdg_env=default)=let_,system=dataxdg_envinfilter_combsysteminletall_dirs?(xdg_env=default)=lethome,system=dataxdg_envinfilter_comb(home::system)in(user_dir,system_dirs,all_dirs)moduleMake(E:sigvaldata:t->dirname*dirnamelistend)=structletuser_dir,system_dirs,all_dirs=mk_funE.datadir_exists(funfn()->fn)letuser_file,system_files,all_files=mk_funE.datafile_existsFilePath.concatendmoduleData=Make(structletdatat=(t.data_home,t.data_dirs)end)moduleConfig=Make(structletdatat=(t.config_home,t.config_dirs)end)moduleCache=structletuser_dir?(xdg_env=default)?exists()=letdn=xdg_env.cache_homeinifdir_exists?existsdnthendnelseraiseNot_foundletuser_file?xdg_env?existsfn=letfn'=FilePath.concat(user_dir?exists?xdg_env())fniniffile_exists?existsfn'thenfn'elseraiseNot_foundendletmkdir_openfilefile_openfn=letdn=dirnamefninFileUtil.mkdir~parent:truedn;file_openfn