123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337(**************************************************************************)(* ocaml-gettext: a library to translate messages *)(* *)(* Copyright (C) 2003-2008 Sylvain Le Gall <sylvain@le-gall.net> *)(* *)(* 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 GNU *)(* Lesser General Public License 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *)(* USA *)(**************************************************************************)openGettextTypesopenGettextCompatopenGettextUtilsopenGettextModulesopenLexing(* Function the main global variable of gettext with/without thread *)typeglobal_type={t:toption;realize:t->t';t':t'option}(* Default value *)letdummy_realize_t_printf_format_textdomainstr_str_plural_category=strletdefault_realize=dummy_realize(* Referenced function used to manage access to global variable,
in other word to be fullfiled with mutex locking/unlocking if needed
*)letglobal_lock=ref(fun()->())letglobal_unlock=ref(fun()->())letglobal=ref{t=None;realize=default_realize;t'=None}letget_global_t()=lett=!global_lock();!global.tin!global_unlock();matchtwithSomet->t|None->raiseGettextUninitializedletset_global_tt=let()=!global_lock();global:={!globalwitht=Somet;t'=None}in!global_unlock()letset_global_realizerealize=let()=!global_lock();global:={!globalwithrealize;t'=None}in!global_unlock()letget_global_t'()=lett'=!global_lock();match!global.t'with|None->(* Try to build it out of the other value provided *)lett=match!global.twith|Somet->t|None->raiseGettextUninitializedinlett'=!global.realizetinglobal:={!globalwitht'=Somet'};t'|Somet'->t'in!global_unlock();t'(* High level functions *)moduleLibrary(Init:INIT_TYPE)=structletinit=(Init.textdomain,Init.codeset,Init.dir)::Init.dependencieslets_str=dgettext(get_global_t'())Init.textdomainstrletf_str=fdgettext(get_global_t'())Init.textdomainstrletsn_str=dngettext(get_global_t'())Init.textdomainstrletfn_str=fdngettext(get_global_t'())Init.textdomainstrend(* i18n/l10n of gettext it self *)moduleGettextGettext=Library(structlettextdomain="ocaml-gettext"letcodeset=Noneletdir=Noneletdependencies=[](* Off course, we don't depend on anything because
we are the root of translation *)end)(* Initialization of gettext library *)letinit=GettextGettext.init(* Exception *)letstring_of_exceptionexc=(* It is important to keep the name f_ and s_, in order to allow ocaml-gettext
program to extract the string *)letf_x=GettextGettext.f_xinlets_x=GettextGettext.s_xinletspfx=Printf.sprintfxinletstring_of_poslexbuf=letchar_pos=lexbuf.lex_curr_p.pos_cnum-lexbuf.lex_curr_p.pos_bolinletline_pos=lexbuf.lex_curr_p.pos_lnuminspf(f_"line %d character %d")line_poschar_posinmatchexcwith|CompileProblemReadingFile(fln,error)->spf(f_"Problem reading file %s: %s.")flnerror|CompileExtractionFailed(fln,cmd,status)->spf(f_"Problem while extracting %s: command %S exits with code %d.")flncmdstatus|CompileExtractionInterrupted(fln,cmd,signal)->spf(f_"Problem while extracting %s: command %S killed by signal %d.")flncmdsignal|DomainFileDoesntExistlst->spf(f_"Cannot find an approriate ocaml-gettext compiled file ( %s ).")(string_of_listlst)|GettextUninitialized->s_"Ocaml-gettext library is not initialized"|MoInvalidOptions(lexbuf,text)->spf(f_"Error while processing parsing of options at %s: %S.")(string_of_poslexbuf)text|MoInvalidPlurals(lexbuf,text)->spf(f_"Error while processing parsing of plural at %s: %S.")(string_of_poslexbuf)text|MoInvalidContentType(lexbuf,text)->spf(f_"Error while processing parsing of content-type at %s: %S.")(string_of_poslexbuf)text|MoInvalidFile->s_"MO file provided is not encoded following ocaml-gettext convention."|MoInvalidTranslationSingular(str,x)->spf(f_"Trying to fetch the plural form %d of a singular form %S.")xstr|MoInvalidTranslationPlural(lst,x)->spf(f_"Trying to fetch the plural form %d of plural form %s.")x(string_of_listlst)|MoJunk(id,lst)->spf(f_"Junk at the end of the plural form id %S: %s.")id(string_of_listlst)|MoEmptyEntry->s_"An empty entry has been encounter."|MoInvalidHeaderNegativeStrings->s_"Number of strings is negative."|MoInvalidHeaderTableStringOutOfBound((b1,e1),(b2,e2))->spf(f_"Offset of string table is out of bound ([%ld,%ld] should be in \
[%ld,%ld]).")b1e1b2e2|MoInvalidHeaderTableTranslationOutOfBound((b1,e1),(b2,e2))->spf(f_"Offset of translation table is out of bound ([%ld,%ld] should be \
in [%ld,%ld]).")b1e1b2e2|MoInvalidHeaderTableTranslationStringOverlap((b1,e1),(b2,e2))->spf(f_"Translation table and string table overlap ([%ld,%ld] and \
[%ld,%ld] have a non empty intersection).")b1e1b2e2|MoInvalidStringOutOfBound(max,cur)->spf(f_"Out of bound access when trying to find a string (%d < %d).")maxcur|MoInvalidTranslationOutOfBound(max,cur)->spf(f_"Out of bound access when trying to find a translation (%d < %d).")maxcur|MoCannotOpenFilefln->spf(f_"Could not open file %s.")fln|PoInvalidFile(s,lexbuf,_chn)->spf(f_"Error while processing parsing of PO file: %S at %s.")s(string_of_poslexbuf)|PoFileInvalidIndex(id,i)->spf(f_"Error while processing parsing of PO file, in msgid %S, %d index \
is out of bound.")idi|PoFileDoesntExistfl->spf(f_"Error while trying to load PO file %s, file doesn't exist.")fl|PoInconsistentMerge(str1,str2)->spf(f_"Error while merging two PO files: %S and %S cannot be merged.")str1str2|TranslateStringNotFoundstr->spf(f_"Cannot find string %S.")str|LocalePosixUnparseablestr->spf(f_"Unable to parse the POSIX language environment variable %s")str|_->Printexc.to_stringexcmoduleProgram(Init:INIT_TYPE)(Realize:REALIZE_TYPE)=structlettextdomain=Init.textdomainletdependencies=(Init.textdomain,Init.codeset,Init.dir)::Init.dependenciesletinit=(* Initialization from all the known textdomain/codeset/dir provided
by library linked with the program *)(* It is important to keep f_ and s_, for the same reason as in
string_of_exception *)letf_x=GettextGettext.f_xinlets_x=GettextGettext.s_xinletspfx=Printf.sprintfxinlet()=set_global_t(GettextModules.createtextdomain)inlet()=set_global_t(List.fold_left(funt(textdomain,codeset_opt,dir_opt)->upgrade_textdomainttextdomain(codeset_opt,dir_opt))(get_global_t())dependencies)inlet()=set_global_realizeRealize.realizein([("--gettext-failsafe",Arg.Symbol(["ignore";"inform-stderr";"raise-exception"],funx->matchxwith|"ignore"->set_global_t{(get_global_t())withfailsafe=Ignore}|"inform-stderr"->set_global_t{(get_global_t())withfailsafe=InformStderrstring_of_exception;}|"raise-exception"->set_global_t{(get_global_t())withfailsafe=RaiseException}|_->()),spf(f_" Choose how to handle failure in ocaml-gettext. Default: %s.")(match(get_global_t()).failsafewith|Ignore->"ignore"|InformStderr_->"inform-stderr"|RaiseException->"raise-exception"));("--gettext-disable",Arg.Unit(fun()->set_global_realizedummy_realize),s_" Disable the translation perform by ocaml-gettext. Default: \
enable.");("--gettext-domain-dir",(letcurrent_textdomain=reftextdomaininArg.Tuple[Arg.String(funtextdomain->current_textdomain:=textdomain);Arg.String(fundir->set_global_t(bindtextdomain!current_textdomaindir(get_global_t())));]),spf(f_"textdomain dir Set a dir to search ocaml-gettext files for \
the specified domain. Default: %s.")(string_of_list(MapTextdomain.fold(funtextdomain(_,dir_opt)lst->matchdir_optwith|Somedir->spf"%s: %s"textdomaindir::lst|None->lst)(get_global_t()).textdomains[])));("--gettext-dir",Arg.String(funs->set_global_t{(get_global_t())withpath=s::(get_global_t()).path}),spf(f_"dir Add a search dir for ocaml-gettext files. Default: %s.")(string_of_list(get_global_t()).path));("--gettext-language",Arg.String(funs->set_global_t{(get_global_t())withlanguage=Somes}),spf(f_"language Set the default language for ocaml-gettext. Default: \
%s.")(match(get_global_t()).languagewith|Somes->s|None->"(none)"));("--gettext-codeset",Arg.String(funs->set_global_t{(get_global_t())withcodeset=s}),spf(f_"codeset Set the default codeset for outputting string with \
ocaml-gettext. Default: %s.")(get_global_t()).codeset);],GettextConfig.copyright)lets_str=dgettext(get_global_t'())textdomainstrletf_str=fdgettext(get_global_t'())textdomainstrletsn_str=dngettext(get_global_t'())textdomainstrletfn_str=fdngettext(get_global_t'())textdomainstrend