123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220(***************************************************************************)(* *)(* SPDX-License-Identifier BSD-3-Clause *)(* Copyright (C) 2001-2003 *)(* George C. Necula <necula@cs.berkeley.edu> *)(* Scott McPeak <smcpeak@cs.berkeley.edu> *)(* Wes Weimer <weimer@cs.berkeley.edu> *)(* Ben Liblit <liblit@cs.berkeley.edu> *)(* All rights reserved. *)(* File modified by *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* INRIA (Institut National de Recherche en Informatique et Automatique) *)(* *)(***************************************************************************)moduleH=Hashtbl(************************************************************************
Configuration
************************************************************************)(** The configuration data can be of several types **)typeconfigData=ConfIntofint|ConfBoolofbool|ConfFloatoffloat|ConfStringofstring|ConfListofconfigDatalist(* Store here window configuration file *)letconfigurationData:(string,configData)H.t=H.create13letclearConfiguration()=H.clearconfigurationDataletsetConfiguration(key:string)(c:configData)=H.replaceconfigurationDatakeycletfindConfiguration(key:string):configData=H.findconfigurationDatakeyletfindConfigurationInt(key:string):int=matchfindConfigurationkeywithConfInti->i|_->Kernel.warning"Configuration %s is not an integer"key;raiseNot_foundletfindConfigurationFloat(key:string):float=matchfindConfigurationkeywithConfFloati->i|_->Kernel.warning"Configuration %s is not a float"key;raiseNot_foundletuseConfigurationInt(key:string)(f:int->unit)=tryf(findConfigurationIntkey)withNot_found->()letuseConfigurationFloat(key:string)(f:float->unit)=tryf(findConfigurationFloatkey)withNot_found->()letfindConfigurationString(key:string):string=matchfindConfigurationkeywithConfStrings->s|_->Kernel.warning"Configuration %s is not a string"key;raiseNot_foundletuseConfigurationString(key:string)(f:string->unit)=tryf(findConfigurationStringkey)withNot_found->()letfindConfigurationBool(key:string):bool=matchfindConfigurationkeywithConfBoolb->b|_->Kernel.warning"Configuration %s is not a boolean"key;raiseNot_foundletuseConfigurationBool(key:string)(f:bool->unit)=tryf(findConfigurationBoolkey)withNot_found->()letfindConfigurationList(key:string):configDatalist=matchfindConfigurationkeywithConfListl->l|_->Kernel.warning"Configuration %s is not a list"key;raiseNot_foundletuseConfigurationList(key:string)(f:configDatalist->unit)=tryf(findConfigurationListkey)withNot_found->()letsaveConfiguration(fname:Filepath.t)=(* Convert configuration data to a string, for saving externally *)letconfigToString(c:configData):string=letbuff=Buffer.create80inletrecloop(c:configData):unit=matchcwithConfInti->Buffer.add_charbuff'i';Buffer.add_stringbuff(string_of_inti);Buffer.add_charbuff';'|ConfBoolb->Buffer.add_charbuff'b';Buffer.add_stringbuff(string_of_boolb);Buffer.add_charbuff';'|ConfFloatf->Buffer.add_charbuff'f';Buffer.add_stringbuff(string_of_floatf);Buffer.add_charbuff';'|ConfStrings->ifString.containss'"'thenKernel.fatal"Guilib: configuration string contains quotes";Buffer.add_charbuff'"';Buffer.add_stringbuffs;Buffer.add_charbuff'"';(* '"' *)|ConfListl->Buffer.add_charbuff'[';List.iterloopl;Buffer.add_charbuff']'inloopc;Buffer.contentsbuffintryletopenFilesystem.Operatorsinlet$oc=Filesystem.with_open_out_exnfnameinKernel.debug"Saving configuration to %a@."Filepath.pretty_absfname;H.iter(funkc->output_stringoc(k^"\n");output_stringoc((configToStringc)^"\n"))configurationDatawith_->Kernel.warning"Cannot open configuration file %a\n"Filepath.pretty_absfname(** Make some regular expressions early *)letintRegexp=Str.regexp"i\\([^;]+\\);"letfloatRegexp=Str.regexp"f\\([^;]+\\);"letboolRegexp=Str.regexp"b\\(\\(true\\)\\|\\(false\\)\\);"letstringRegexp=Str.regexp"\"\\([^\"]*\\)\""letloadConfiguration(fname:Filepath.t):unit=H.clearconfigurationData;letstringToConfig(s:string):configData=letidx=ref0in(* the current index *)letl=String.lengthsinletrecgetOne():configData=if!idx>=lthenraiseNot_found;ifStr.string_matchintRegexps!idxthenbeginidx:=Str.match_end();letp=Str.matched_group1sin(tryConfInt(int_of_stringp)withFailure_->Kernel.warning"Invalid integer configuration element %s"p;raiseNot_found)endelseifStr.string_matchfloatRegexps!idxthenbeginidx:=Str.match_end();letp=Str.matched_group1sin(tryConfFloat(float_of_stringp)withFailure_->Kernel.warning"Invalid float configuration element %s"p;raiseNot_found)endelseifStr.string_matchboolRegexps!idxthenbeginidx:=Str.match_end();ConfBool(bool_of_string(Str.matched_group1s))endelseifStr.string_matchstringRegexps!idxthenbeginidx:=Str.match_end();ConfString(Str.matched_group1s)endelseifString.gets!idx='['thenbegin(* We are starting a list *)incridx;letrecloop(acc:configDatalist):configDatalist=if!idx>=lthenbeginKernel.warning"Non-terminated list in configuration %s"s;raiseNot_foundend;ifString.gets!idx=']'thenbeginincridx;List.revaccendelseloop(getOne()::acc)inConfList(loop[])endelsebeginKernel.warning"Bad configuration element in a list: %s"(String.subs!idx(l-!idx));raiseNot_foundendingetOne()inletopenFilesystem.Operatorsintrylet$ic=Filesystem.with_open_in_exnfnameinKernel.debug"Loading configuration from %a@."Filepath.pretty_absfname;whiletruedoletk=input_lineicinlets=input_lineicintryletc=stringToConfigsinsetConfigurationkcwithNot_found->()donewithEnd_of_file|Sys_error_->()