From b92f950defa3bd03db8075caef1d4179447822f4 Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Tue, 21 Oct 2014 11:38:39 +0200 Subject: [PATCH] Imported Upstream version 4.02.1 --- .depend | 40 +-- .gitignore | 1 + Changes | 70 +++- Makefile | 7 + Makefile.nt | 4 +- VERSION | 2 +- asmcomp/CSEgen.ml | 4 +- asmcomp/arm/proc.ml | 2 + asmcomp/arm/selection.ml | 10 +- asmrun/backtrace.c | 51 ++- asmrun/signals_osdep.h | 30 ++ boot/ocamlc | Bin 1707956 -> 1715876 bytes boot/ocamldep | Bin 526023 -> 532314 bytes boot/ocamllex | Bin 251568 -> 254314 bytes bytecomp/bytegen.ml | 1 - bytecomp/bytepackager.ml | 3 +- bytecomp/emitcode.ml | 1 + bytecomp/lambda.ml | 9 +- bytecomp/translcore.ml | 8 +- bytecomp/translmod.ml | 59 ++-- byterun/gc_ctrl.c | 2 +- config/Makefile.mingw | 2 +- config/Makefile.mingw64 | 2 +- config/Makefile.msvc | 22 +- config/Makefile.msvc64 | 24 +- config/s-nt.h | 1 + config/s-templ.h | 4 + configure | 39 ++- debugger/source.ml | 8 +- driver/main_args.ml | 55 ++- driver/main_args.mli | 20 ++ driver/pparse.ml | 61 ++-- driver/pparse.mli | 9 +- emacs/caml-types.el | 4 +- man/ocaml.m | 5 +- man/ocamlc.m | 5 +- man/ocamlopt.m | 5 +- ocamlbuild/ocaml_specific.ml | 4 + ocamlbuild/options.ml | 4 +- ocamlbuild/testsuite/internal.ml | 11 + ocamldoc/.depend | 18 +- ocamldoc/Makefile | 1 + ocamldoc/odoc_args.ml | 99 ++++-- ocamldoc/odoc_global.ml | 11 +- ocamldoc/odoc_global.mli | 7 - ocamldoc/odoc_messages.ml | 144 ++++---- otherlibs/systhreads/Makefile | 6 +- otherlibs/threads/Makefile | 30 +- otherlibs/unix/nice.c | 4 + parsing/ast_mapper.ml | 313 +++++++++++------- parsing/ast_mapper.mli | 64 +++- parsing/location.ml | 11 +- parsing/parser.mly | 4 +- parsing/pprintast.ml | 2 +- stdlib/arg.ml | 18 +- stdlib/arg.mli | 7 +- stdlib/array.mli | 4 +- stdlib/arrayLabels.mli | 4 +- stdlib/bytes.ml | 29 +- stdlib/camlinternalFormat.ml | 269 ++++++++++----- stdlib/camlinternalFormatBasics.ml | 7 + stdlib/camlinternalFormatBasics.mli | 7 + stdlib/camlinternalMod.ml | 3 +- stdlib/filename.mli | 3 +- stdlib/format.mli | 10 +- stdlib/gc.mli | 4 +- stdlib/lazy.mli | 9 +- stdlib/obj.mli | 9 +- stdlib/pervasives.mli | 4 +- stdlib/printf.mli | 4 +- stdlib/scanf.ml | 5 + stdlib/sort.mli | 6 +- stdlib/string.mli | 8 +- stdlib/stringLabels.mli | 14 +- testsuite/tests/backtrace/Makefile | 11 + .../backtrace/backtraces_and_finalizers.ml | 25 ++ .../backtraces_and_finalizers.reference | 1 + .../formats-transition/invalid_formats.ml | 67 ++++ .../invalid_formats.ml.reference | 24 ++ testsuite/tests/lib-dynlink-native/Makefile | 2 +- testsuite/tests/lib-format/Makefile | 7 +- testsuite/tests/lib-format/tformat.ml | 32 +- testsuite/tests/lib-format/tformat.reference | 88 ++--- testsuite/tests/lib-printf/Makefile | 9 +- testsuite/tests/lib-printf/pr6534.ml | 19 ++ testsuite/tests/lib-printf/pr6534.reference | 14 + testsuite/tests/lib-printf/tprintf.ml | 29 +- testsuite/tests/lib-printf/tprintf.reference | 88 ++--- testsuite/tests/lib-scanf/tscanf.ml | 14 + testsuite/tests/lib-scanf/tscanf.reference | 2 +- testsuite/tests/tool-debugger/basic/Makefile | 2 +- .../tool-debugger/no_debug_event/.ignore | 4 + .../tool-debugger/no_debug_event/Makefile | 57 ++++ .../tests/tool-debugger/no_debug_event/a.ml | 1 + .../tests/tool-debugger/no_debug_event/b.ml | 3 + .../tool-debugger/no_debug_event/input_script | 2 + .../no_debug_event/noev.reference | 4 + .../typing-extensions/open_types.ml.reference | 4 +- .../tests/typing-modules-bugs/pr6572_ok.ml | 19 ++ testsuite/tests/typing-modules/aliases.ml | 9 + .../tests/typing-modules/aliases.ml.reference | 5 + .../tests/typing-short-paths/short-paths.ml | 6 + .../short-paths.ml.reference | 11 + tools/.depend | 12 +- tools/depend.ml | 21 +- tools/depend.mli | 2 + tools/ocamldep.ml | 25 +- toplevel/topdirs.ml | 4 +- toplevel/toploop.ml | 13 +- toplevel/toploop.mli | 3 + toplevel/topmain.ml | 1 + typing/env.ml | 32 +- typing/env.mli | 2 +- typing/includemod.ml | 48 +-- typing/mtype.ml | 4 +- typing/parmatch.ml | 12 +- typing/typecore.ml | 4 + utils/consistbl.ml | 5 +- utils/misc.ml | 16 + utils/misc.mli | 2 + 120 files changed, 1748 insertions(+), 744 deletions(-) create mode 100644 testsuite/tests/backtrace/backtraces_and_finalizers.ml create mode 100644 testsuite/tests/backtrace/backtraces_and_finalizers.reference create mode 100644 testsuite/tests/formats-transition/invalid_formats.ml create mode 100644 testsuite/tests/formats-transition/invalid_formats.ml.reference create mode 100644 testsuite/tests/lib-printf/pr6534.ml create mode 100644 testsuite/tests/lib-printf/pr6534.reference create mode 100644 testsuite/tests/tool-debugger/no_debug_event/.ignore create mode 100644 testsuite/tests/tool-debugger/no_debug_event/Makefile create mode 100644 testsuite/tests/tool-debugger/no_debug_event/a.ml create mode 100644 testsuite/tests/tool-debugger/no_debug_event/b.ml create mode 100644 testsuite/tests/tool-debugger/no_debug_event/input_script create mode 100644 testsuite/tests/tool-debugger/no_debug_event/noev.reference create mode 100644 testsuite/tests/typing-modules-bugs/pr6572_ok.ml diff --git a/.depend b/.depend index 9b6b9ffb..5d95a9bb 100644 --- a/.depend +++ b/.depend @@ -538,20 +538,20 @@ bytecomp/translclass.cmx : typing/types.cmx bytecomp/typeopt.cmx \ typing/path.cmx bytecomp/matching.cmx parsing/location.cmx \ bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx utils/clflags.cmx \ typing/btype.cmx parsing/asttypes.cmi bytecomp/translclass.cmi -bytecomp/translcore.cmo : utils/warnings.cmi typing/types.cmi \ - bytecomp/typeopt.cmi typing/typedtree.cmi bytecomp/translobj.cmi \ - typing/primitive.cmi typing/predef.cmi typing/path.cmi \ - typing/parmatch.cmi utils/misc.cmi bytecomp/matching.cmi \ - parsing/longident.cmi parsing/location.cmi bytecomp/lambda.cmi \ - typing/ident.cmi typing/env.cmi utils/config.cmi utils/clflags.cmi \ - typing/btype.cmi parsing/asttypes.cmi bytecomp/translcore.cmi -bytecomp/translcore.cmx : utils/warnings.cmx typing/types.cmx \ - bytecomp/typeopt.cmx typing/typedtree.cmx bytecomp/translobj.cmx \ - typing/primitive.cmx typing/predef.cmx typing/path.cmx \ - typing/parmatch.cmx utils/misc.cmx bytecomp/matching.cmx \ - parsing/longident.cmx parsing/location.cmx bytecomp/lambda.cmx \ - typing/ident.cmx typing/env.cmx utils/config.cmx utils/clflags.cmx \ - typing/btype.cmx parsing/asttypes.cmi bytecomp/translcore.cmi +bytecomp/translcore.cmo : typing/types.cmi bytecomp/typeopt.cmi \ + typing/typedtree.cmi bytecomp/translobj.cmi typing/primitive.cmi \ + typing/predef.cmi typing/path.cmi typing/parmatch.cmi utils/misc.cmi \ + bytecomp/matching.cmi parsing/longident.cmi parsing/location.cmi \ + bytecomp/lambda.cmi typing/ident.cmi typing/env.cmi utils/config.cmi \ + utils/clflags.cmi typing/btype.cmi parsing/asttypes.cmi \ + bytecomp/translcore.cmi +bytecomp/translcore.cmx : typing/types.cmx bytecomp/typeopt.cmx \ + typing/typedtree.cmx bytecomp/translobj.cmx typing/primitive.cmx \ + typing/predef.cmx typing/path.cmx typing/parmatch.cmx utils/misc.cmx \ + bytecomp/matching.cmx parsing/longident.cmx parsing/location.cmx \ + bytecomp/lambda.cmx typing/ident.cmx typing/env.cmx utils/config.cmx \ + utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi \ + bytecomp/translcore.cmi bytecomp/translmod.cmo : typing/types.cmi typing/typedtree.cmi \ bytecomp/translobj.cmi bytecomp/translcore.cmi bytecomp/translclass.cmi \ typing/printtyp.cmi typing/primitive.cmi typing/predef.cmi \ @@ -927,12 +927,12 @@ driver/optmain.cmx : utils/warnings.cmx asmcomp/printmach.cmx \ driver/compenv.cmx utils/clflags.cmx asmcomp/asmpackager.cmx \ asmcomp/asmlink.cmx asmcomp/asmlibrarian.cmx asmcomp/arch.cmx \ driver/optmain.cmi -driver/pparse.cmo : parsing/parsetree.cmi parsing/parse.cmi utils/misc.cmi \ - parsing/location.cmi utils/config.cmi utils/clflags.cmi utils/ccomp.cmi \ - parsing/ast_mapper.cmi parsing/ast_helper.cmi driver/pparse.cmi -driver/pparse.cmx : parsing/parsetree.cmi parsing/parse.cmx utils/misc.cmx \ - parsing/location.cmx utils/config.cmx utils/clflags.cmx utils/ccomp.cmx \ - parsing/ast_mapper.cmx parsing/ast_helper.cmx driver/pparse.cmi +driver/pparse.cmo : parsing/parse.cmi utils/misc.cmi parsing/location.cmi \ + utils/config.cmi utils/clflags.cmi utils/ccomp.cmi parsing/ast_mapper.cmi \ + driver/pparse.cmi +driver/pparse.cmx : parsing/parse.cmx utils/misc.cmx parsing/location.cmx \ + utils/config.cmx utils/clflags.cmx utils/ccomp.cmx parsing/ast_mapper.cmx \ + driver/pparse.cmi toplevel/genprintval.cmi : typing/types.cmi typing/path.cmi \ typing/outcometree.cmi typing/env.cmi toplevel/opttopdirs.cmi : parsing/longident.cmi diff --git a/.gitignore b/.gitignore index d36195a2..6c66ecc5 100644 --- a/.gitignore +++ b/.gitignore @@ -414,6 +414,7 @@ /ocamldoc/odoc_text_parser.ml /ocamldoc/odoc_text_parser.mli /ocamldoc/stdlib_man +/ocamldoc/stdlib_html /ocamldoc/*.output /ocamldoc/test_stdlib /ocamldoc/test_latex diff --git a/Changes b/Changes index 55c3b9a8..f1435285 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,71 @@ +OCaml 4.02.1: +------------- +(Changes that can break existing programs are marked with a "*") + +Standard library: +* Add optional argument ?limit to Arg.align. + +- PR#4099: Bug in Makefile.nt: won't stop on error + (George Necula) +- PR#6181: Improve MSVC build + (Chen Gang) +- PR#6207: Configure doesn't detect features correctly on Haiku + (Jessica Hamilton) +- PR#6466: Non-exhaustive matching warning message for open types is confusing + (Peter Zotov) +- PR#6529: fix quadratic-time algorithm in Consistbl.extract. + (Xavier Leroy, Alain Frisch, relase-worthy report by Jacques-Pascal Deplaix) +- PR#6530: Add stack overflow handling for native code (OpenBSD i386 and amd64) + (Cristopher Zimmermann) +- PR#6533: broken semantics of %(%) when substitued by a box + (Benoît Vaugon, report by Boris Yakobowski) +- PR#6534: legacy support for %.10s + (Benoît Vaugon, Gabriel Scherer, report by Nick Chapman) +- PR#6536: better documentation of flag # in format strings + (Damien Doligez, report by Nick Chapman) +- PR#6544: Bytes and CamlinternalFormat missing from threads stdlib.cma + (Christopher Zimmermann) +- PR#6546: -dsource omits parens for `List ((`String "A")::[]) in patterns + (Gabriel Scherer, report by Peter Zotov) +- PR#6547: __MODULE__ aborts the compiler if the module name cannot be inferred + (Jacques Garrigue, report by Kaustuv Chaudhuri) +- PR#6549: Debug section is sometimes not readable when using -pack + (Hugo Heuzard, review by Gabriel Scherer) +- PR#6553: Missing command line options for ocamldoc + (Maxence Guesdon) +- PR#6554: fix race condition when retrieving backtraces + (Jérémie Dimino, Mark Shinwell). +- PR#6557: String.sub throws Invalid_argument("Bytes.sub") + (Damien Doligez, report by Oliver Bandel) +- PR#6562: Fix ocamldebug module source lookup + (Leo White) +- PR#6563: Inclusion of packs failing to run module initializers + (Jacques Garrigue, report by Mark Shinwell) +- PR#6564: infinite loop in Mtype.remove_aliases + (Jacques Garrigue, report by Mark Shinwell) +- PR#6565: compilation fails with Env.Error(_) + (Jacques Garrigue and Mark Shinwell) +- PR#6566: -short-paths and signature inclusion errors + (Jacques Garrigue, report by Mark Shinwell) +- PR#6572: Fatal error with recursive modules + (Jacques Garrigue, report by Quentin Stievenart) +- PR#6578: Recursive module containing alias causes Segmentation fault + (Jacques Garrigue) +- PR#6581: Some bugs in generative functors + (Jacques Garrigue, report by Mark Shinwell) +- PR#6584: ocamldep support for "-open M" + (Gabriel Scherer, review by Damien Doligez, report by Hezekiah M. Carty) +- PR#6588: Code generation errors for ARM + (Mark Shinwell, Xavier Leroy) +- PR#6590: Improve Windows (MSVC and mingw) build + (Chen Gang) +- PR#6599: ocamlbuild: add -bin-annot when using -pack + (Christopher Zimmermann) +- PR#6602: Fatal error when tracing a function with abstract type + (Jacques Garrigue, report by Hugo Herbelin) +- ocamlbuild: add an -ocamlmklib option to change the ocamlmklib command + (Jérôme Vouillon) + OCaml 4.02.0: ------------- @@ -107,7 +175,7 @@ Runtime system: - Fixed bug in native code version of [caml_raise_with_string] that could potentially lead to heap corruption. (Mark Shinwell) -- Blocks initialized by [CAMLlocal*] and [caml_alloc] are now filled with +* Blocks initialized by [CAMLlocal*] and [caml_alloc] are now filled with [Val_unit] rather than zero. (Mark Shinwell) - Fixed a major performance problem on large heaps (~1GB) by making heap diff --git a/Makefile b/Makefile index 733ed99d..6c0e7e64 100644 --- a/Makefile +++ b/Makefile @@ -367,6 +367,13 @@ installoptopt: cd $(INSTALL_COMPLIBDIR) && $(RANLIB) ocamlcommon.a ocamlbytecomp.a \ ocamloptcomp.a +# Run all tests + +tests: opt.opt + cd testsuite; $(MAKE) clean && $(MAKE) all + +# The clean target + clean:: partialclean # Shared parts of the system diff --git a/Makefile.nt b/Makefile.nt index 648c918d..16b53fe2 100644 --- a/Makefile.nt +++ b/Makefile.nt @@ -252,7 +252,9 @@ installbyt: cp expunge $(INSTALL_LIBDIR)/expunge.exe cp toplevel/topdirs.cmi $(INSTALL_LIBDIR) cd tools ; $(MAKEREC) install - for i in $(OTHERLIBRARIES); do $(MAKEREC) -C otherlibs/$$i install; done + for i in $(OTHERLIBRARIES); do \ + $(MAKEREC) -C otherlibs/$$i install || exit $$?; \ + done if test -n "$(WITH_OCAMLDOC)"; then (cd ocamldoc; $(MAKEREC) install); \ else :; fi if test -n "$(WITH_DEBUGGER)"; then (cd debugger; $(MAKEREC) install); \ diff --git a/VERSION b/VERSION index da8c290a..9023b27c 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -4.02.0 +4.02.1 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli diff --git a/asmcomp/CSEgen.ml b/asmcomp/CSEgen.ml index 8cd23b0a..6571ad53 100644 --- a/asmcomp/CSEgen.ml +++ b/asmcomp/CSEgen.ml @@ -164,8 +164,8 @@ let insert_move srcs dsts i = | l -> (* Parallel move: first copy srcs into tmps one by one, then copy tmps into dsts one by one *) let tmps = Reg.createv_like srcs in - array_fold2 insert_single_move - (array_fold2 insert_single_move i srcs tmps) tmps dsts + let i1 = array_fold2 insert_single_move i tmps dsts in + array_fold2 insert_single_move i1 srcs tmps (* Classification of operations *) diff --git a/asmcomp/arm/proc.ml b/asmcomp/arm/proc.ml index 6b2ba3cf..58bfa427 100644 --- a/asmcomp/arm/proc.ml +++ b/asmcomp/arm/proc.ml @@ -219,6 +219,7 @@ let safe_register_pressure = function Iextcall(_, _) -> if abi = EABI then 0 else 4 | Ialloc _ -> if abi = EABI then 0 else 7 | Iconst_symbol _ when !pic_code -> 7 + | Iintop Imulh when !arch < ARMv6 -> 8 | _ -> 9 let max_register_pressure = function @@ -227,6 +228,7 @@ let max_register_pressure = function | Iconst_symbol _ when !pic_code -> [| 7; 16; 32 |] | Iintoffloat | Ifloatofint | Iload(Single, _) | Istore(Single, _, _) -> [| 9; 15; 31 |] + | Iintop Imulh when !arch < ARMv6 -> [| 8; 16; 32 |] | _ -> [| 9; 16; 32 |] (* Pure operations (without any side effect besides updating their result diff --git a/asmcomp/arm/selection.ml b/asmcomp/arm/selection.ml index 9cd6090c..4725942b 100644 --- a/asmcomp/arm/selection.ml +++ b/asmcomp/arm/selection.ml @@ -48,6 +48,8 @@ let select_shiftop = function exception Use_default let r1 = phys_reg 1 +let r6 = phys_reg 6 +let r7 = phys_reg 7 let r12 = phys_reg 8 let pseudoregs_for_operation op arg res = @@ -58,10 +60,12 @@ let pseudoregs_for_operation op arg res = Iintop Imul | Ispecific Imuladd when !arch < ARMv6 -> (arg, [| res.(0); arg.(0) |]) (* For smull rdlo,rdhi,rn,rm (pre-ARMv6) the registers rdlo, rdhi and rn - must be different. We deal with this by pretending that rn is also a - result of the smull operation. *) + must be different. Also, rdlo (whose contents we discard) is always + forced to be r12 in proc.ml, which means that neither rdhi and rn can + be r12. To keep things simple, we force both of those two to specific + hard regs: rdhi in r6 and rn in r7. *) | Iintop Imulh when !arch < ARMv6 -> - (arg, [| res.(0); arg.(0) |]) + ([| r7; arg.(1) |], [| r6 |]) (* Soft-float Iabsf and Inegf: arg.(0) and res.(0) must be the same *) | Iabsf | Inegf when !fpu = Soft -> ([|res.(0); arg.(1)|], res) diff --git a/asmrun/backtrace.c b/asmrun/backtrace.c index c72a2373..05e0d6b2 100644 --- a/asmrun/backtrace.c +++ b/asmrun/backtrace.c @@ -332,13 +332,37 @@ CAMLprim value caml_get_exception_raw_backtrace(value unit) { CAMLparam0(); CAMLlocal1(res); + const int tag = 0; - res = caml_alloc(caml_backtrace_pos, 0); - if(caml_backtrace_buffer != NULL) { + /* Beware: the allocations below may cause finalizers to be run, and another + backtrace---possibly of a different length---to be stashed (for example + if the finalizer raises then catches an exception). We choose to ignore + any such finalizer backtraces and return the original one. */ + + if (caml_backtrace_buffer == NULL || caml_backtrace_pos == 0) { + res = caml_alloc(0, tag); + } + else { + code_t saved_caml_backtrace_buffer[BACKTRACE_BUFFER_SIZE]; + int saved_caml_backtrace_pos; intnat i; - for(i = 0; i < caml_backtrace_pos; i++) - Field(res, i) = Val_Descrptr(caml_backtrace_buffer[i]); + + saved_caml_backtrace_pos = caml_backtrace_pos; + + if (saved_caml_backtrace_pos > BACKTRACE_BUFFER_SIZE) { + saved_caml_backtrace_pos = BACKTRACE_BUFFER_SIZE; + } + + memcpy(saved_caml_backtrace_buffer, caml_backtrace_buffer, + saved_caml_backtrace_pos * sizeof(code_t)); + + res = caml_alloc(saved_caml_backtrace_pos, tag); + for (i = 0; i < saved_caml_backtrace_pos; i++) { + /* [Val_Descrptr] always returns an immediate. */ + Field(res, i) = Val_Descrptr(saved_caml_backtrace_buffer[i]); + } } + CAMLreturn(res); } @@ -355,19 +379,16 @@ CAMLprim value caml_get_exception_raw_backtrace(value unit) CAMLprim value caml_get_exception_backtrace(value unit) { CAMLparam0(); - CAMLlocal4(arr, raw_slot, slot, res); + CAMLlocal3(arr, res, backtrace); + intnat i; - arr = caml_alloc(caml_backtrace_pos, 0); - if (caml_backtrace_buffer == NULL) { - Assert(caml_backtrace_pos == 0); - } else { - intnat i; - for(i = 0; i < caml_backtrace_pos; i++) { - raw_slot = Val_Descrptr(caml_backtrace_buffer[i]); - slot = caml_convert_raw_backtrace_slot(raw_slot); - caml_modify(&Field(arr, i), slot); - } + backtrace = caml_get_exception_raw_backtrace(Val_unit); + + arr = caml_alloc(Wosize_val(backtrace), 0); + for (i = 0; i < Wosize_val(backtrace); i++) { + Store_field(arr, i, caml_convert_raw_backtrace_slot(Field(backtrace, i))); } + res = caml_alloc_small(1, 0); Field(res, 0) = arr; /* Some */ CAMLreturn(res); } diff --git a/asmrun/signals_osdep.h b/asmrun/signals_osdep.h index 23165ad6..f3b4642d 100644 --- a/asmrun/signals_osdep.h +++ b/asmrun/signals_osdep.h @@ -130,6 +130,22 @@ #define CONTEXT_YOUNG_PTR (context->uc_mcontext.gregs[REG_R15]) #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) +/****************** AMD64, OpenBSD */ + +#elif defined(TARGET_amd64) && defined (SYS_openbsd) + + #define DECLARE_SIGNAL_HANDLER(name) \ + static void name(int sig, siginfo_t * info, struct sigcontext * context) + + #define SET_SIGACT(sigact,name) \ + sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ + sigact.sa_flags = SA_SIGINFO + + #define CONTEXT_PC (context->sc_rip) + #define CONTEXT_EXCEPTION_POINTER (context->sc_r14) + #define CONTEXT_YOUNG_PTR (context->sc_r15) + #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) + /****************** I386, Linux */ #elif defined(TARGET_i386) && defined(SYS_linux_elf) @@ -143,6 +159,20 @@ #define CONTEXT_FAULTING_ADDRESS ((char *) context.cr2) +/****************** I386, BSD_ELF */ + +#elif defined(TARGET_i386) && defined(SYS_bsd_elf) + + #define DECLARE_SIGNAL_HANDLER(name) \ + static void name(int sig, siginfo_t * info, struct sigcontext * context) + + #define SET_SIGACT(sigact,name) \ + sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ + sigact.sa_flags = SA_SIGINFO + + #define CONTEXT_PC (context->sc_eip) + #define CONTEXT_FAULTING_ADDRESS ((char *) info->si_addr) + /****************** I386, BSD */ #elif defined(TARGET_i386) && defined(SYS_bsd) diff --git a/boot/ocamlc b/boot/ocamlc index f6b63f10c387a411a6e9ffb9e84421eb88130dc5..a1aec5dbc33db078f430c8d2074dc7098a158a85 100755 GIT binary patch delta 163050 zcmc${3s{s@*EjCo_kkIh!5IYx0R;rbLIuM!8km-r7MP}%CKw*@6rL(e3rb5%6BK1x zTA)^1npj#l&y$8_rDY|hWu+yirKJUSc=CC&=Kovw%#Gt@@B9A0>;0~8E|>dWYp=cc z+H0-7_TfITqq6XsFAK|}BfF&CG5OB4qJnYLr_H+S&d}k_nl*b>mamghFZFMu6+|~{ z1wtI4Js=&>7jOe$EMOMk5x|pxt$-T9n}7p=qkyx33jkd-Yvuy923!f~3K#$w3K+e8 zw{}XU+SCw7d79!7QRN-gj9wm;>Htsy9RXl8e}n$;dIRxeLHObYYM7yhi3W#^zlPjT zh-kwZEwbasU+hRbRMZ*J2f!W42iy%<3Rn-|PP_rw3-|zV5O55@o%t2;CqRWfEdgqTE?R~^bzH%7@`-+LeZ>&H4d`1Ev5<06PJy0t*3h0TTf;0R-3sI1e~$II={oO9*;D zN2E1%hRxLmz`DH&a0_4zpa3uhFcUBrPz+#)DF?g^_y?sA6(gxMS1c4BiWn+R(XpXo z2d=XR;lIr{i#ft$Bn%TqC@sntU5$gci$A5mpWNV;fSv$0+~X@E??K)?vVqkuBNI>3tn2sTb+%D27r(ge}I1vkY5feoYsp7YZ22_lAS z#|ejc!gzn2m?y<|v~7ZjrGoL|GqINXOc4FWT~snbq=^xnlO}pl{RB}il|Si&iK0EN znJCi5m-PNbF;DEEL6bz9toVc5>n!L0!S%PN%1NSQlag70wtgY5LdxDT0B|E<1RxJk z2w-L32Uq}D1|TXc6h+j0k)|2*3q=oMluj156nA^%@sADC8<0ht%0wQ;mk1kqv`E(# z?1sqzJAf_Bzl8u+dJF)1GTl>9$tsaX8Ra65=2ZwsC-!a590`Ean85zs2f)4Hibnxh z>M&AQh$O8$E|aKgxkxQ9delY(D@24@7ga779WN!>x%zH^&wTAR@uJAmQjtmrSBMU7 z9#{Np0SE;YQg$)MP1<*ZDgzx5$>+YVS{ov!vK-g*g?ip(KRijspwweqD&Ie z8Y`eB&B%+4)ttDDrG()kR%BJoY7tMzPPTMi!HqBz`-uu*+y-DFSW{d*3(?#ZP~$k7 zNcrU=wY3|U91d6z?iZ_uy^L$CrSmIAQa3KhKg&*oaLrofVk{2ZkyHLH0-=At;G?EEfo&nc6ku9b-8^W z=$aqrc+&}RFCb8^z&iMvP4_vQE|Y4P3kMYqa@g#ah9YTkg-B|36?oWVxJ{0dti-W^ zA8FgkmIK>aBCvjA0hak3xV{3wDzMY;3XwuTcaSh8+jH|w5#5dZ$yVwJU_Gb|@{)s6{}Jx6Tf&){@zjtKVxxw;TRJF@%&1jHBFAaf%u0-2Xbll9w=sa*nudlr_<5qxjXrB_yS<7OCPZTKWX+vtTtQvZ7yG+Nj5B zkxWaT5Xl;AuAcJqFR zW$h?C01!wIydHr(_5q$A*gufc%j-pJ8vV40?&LuDodha}J%uu~0enG$zcV=P=tVl_DCWC9V>)nuqG2Mdq+d5h22;uo4r{JLpW10Ok<+5yPP^ zsvZv570g48>o66csl@Tq?fe25(D3?BWa!J;1l0N#m|VYMC(LCWM*)ysG(~`et4{%>)~Zhm|2Gi zC)avZ69go+HBm*#Ohy)8Oo`=V0PLp-NsZv1hQ><0o7ICD+W5NC_Ll zJrq(cT=u5n7T|~*U&KQA%yUg$buLFC))^NLqpH{tkCPi`V8I@wveV(Qk?b{$vVr)T z?Kp-?H0g0(g-fo0Ny8}n3E?r9b`Z7M0Dv`5VV`k4JhnGmn!CUY0G=IB0@%mW0jB%` zDJwF;4{9@7{&i@S2wgGHgPEC|namEykO~+9V9((?zX7l`-2cF~z6BoGRswKtlhaGv z@|EZMxEtIi<=kYqwPM$0%~%>|QzZf%? zp{AV8h<6zATSRPMD`r@>uykSJYys{kx6bSEVgPFM;T6?T5zA!CMhVp-r4_p*7hqRn zGLP>(fScmBhST~**u_iRt^4b=W{eMfCUVkeL1Y#jMKO10qBwLa3ASvf!v@eB& zi6~QPlmhA7SsLO_S{mZza-fD{ObuPMC~L^)hGqmQLVU3_667u3YLT93nVlmQSBu%$ z8)*L1l)Fu&7PAEX0oI0_M-00FTZYXL94)>BEl}zvp9ej71am#?6PK%>#X|kJ{iT8L zk@5eh0iJ0t*FZGwd>P~OvQ^Pr+eC^vk99-ov;G!i$#tvnToK&kAO21tN`5JzmLL6W zab_(v_+{ZLZt&B1eZtD*uw?o4a9mr;wp`%9QzqwgJyy9WKOQV{Bj^~<#pd8)4g7Z% za|M@EqSasq^4Xf)5e^pZ0qp-4Z2_)30ywT(w1qq?WP`v`a&LnRaIcx!EIy}X zfL`8WN4H}LwJD$B@KEy|@cf^QgdL((il2>buZkogexa%wG0=#u5f2H3hX=lJUO}Z_ zIBlX8m3-k$;cJKC{fAg6wO`RlIMu%idQhAVnaeA=-3{d z4VUf_rxkg=8NG3rtF5tSuc%VQzl}coaab4mA5_9xvqmfrt=3fXz8EQgZ$^oEwzlOt zH)8Glfv6W3jFTUTMI!Q#%amzllpGK_BJxk<@wPCqzE;M`I&nfsZ!=nVhu(%xeJqmu z@p*>?EClec3?Kj&t}%iin`At|TCH*ZWWXQP=a9(6+2hq^V+P{vk_@c;z%dm@`JW0;EBM@HvqQ{m+H+7OQ|V!mE}IE@ zFi0bfzA#POy5K^zQl~5T7&JzBCqIE%rbHXMc;Y7 za{>PVyag!x-s{~9Sa-(j4L|Gk?g3GKuQKFjr702O- z?Z`@V2|AwEJVv?&bxDy?M%ve6z7Q>F%Lx(Ni|@*CSH}YW1z-nC18~8J%jCuT^CBxw znlpGDCmy5cNii5v##s1`Xep>@g5B2d3UIRRSY8fvtawgYXKex8Vh?}=!0yI+Q~~_! z0MMvzMM#pi8Qs?Dmv2Ryy%pr)92<2!CE{x>wG zEo%qaCjBa01mYP%INz%b%!hk5g@;o3!YjR@Pmo)zB&iX|qi?C-?nX4s<`#seD0DmUB&Fc49~WpBupS69)L6U&Et~(LagxGT?az4sP6KHd+~AGhiR!8-PUr z`Js#Mfc}7+0pkD_fc=1zfIk4u;a(j8{7Arfz=MD_l3pV0X%GL3`|cZm#q$iJmr?(3 zF;$Vh1UEth$=yqe~7N;Dk;-Prh6`6eV)}5=Nm1(qDFM0_r2n}5YGz2vxD${LHIR6cz;2O03KV_TZ-FOHlu-x(>d>-)T;AaQtV8JQlT#o{{7Wq8vt$H8E zYK_OPh0hMcM+4_L#r2?F>U~>;TVDBld8hK2NH11>Ob-hv|1q76mZ{=dalgHjvV^;rT8x3TsaHJDGwnQ65iVES>y#O>jA23B|Wm&F6#GQizxE8 zlH-fh{5)KiqcNwveB(M;5mT^?<@VX^tYH3qz02$6lxf@!({HcE@)viFna1l2{_TFt z>-_}K>K(85Uclo34qn{>*P&20o_cBDw^d|ww83(+0xjA9Nv>F#ar;9kLVzdV^Ll>- z?AY)1z6;QlJ&>j)${atY@k2!+G$TOm=Ws=M;KQ_=o-lHPfTrlxQ;tJ*mIH*2JrnF**2?OwS##!vJZ2=ClB};6r9}yAd z-f)ML?RG7I9S`Fw8Db8nZOJmJ8`og2N|AC+4D46zjzxap>xTjSW6dixqsr;Ig;{yA zlK`-UxEa^{VhSNo7A+U_f41|91l zOYAo`(Ju1cWYG-ptq~%J>N~-pxs-5~Tx2xwDC>k6>Z9Fk(x|+%+ysX)*@pW_4QU|V z;vn@H&MIiMZ$)!#nA`m6Xrz2_o&eyUao!jl3an6~jQttX zA;j(USy!2=jRj*EC7cuwLaeZV~y--+`^mn?a;5Jzc7HdwdN(rkoI~9 zTgFh%4RXGH5qN#IAG$#fvoCH!(+A7n?T zHzGDZPDgK)Nn%jNO>(4IMx$qv9d<2r=@xDmkky9vWNMA(=$H8vmlHX z&*A@6V^O}W7uwS(Dax}~cxb^La-Y~}3@MP+ir8dam?(S5(C7U^KBSk=bVM1$Cd*Mm zzJRmGL9(rJV2YgK5zkZhLvk3Bl@G}?Vl$O2keTq*oeN}!c+qHFAb*x(t8wxXj9|=A zaVunVVeDNZhwDCUSO{ja8BfS+BneN--$0FC10LV}mO?peWiDt{Yb7b7ntE2jySLH4 zD!E3!B&c7h5+h!wl65jxZug@*81>MBb#j|{#VA=X=e3ouit@z1ZH(Br@rrX z%4|ixjuG1e8D|Wr@e1xByg`i#O1XH`SeU4k3aBR{NlCNsL47`d z8oUCjT@*P3vK2@WPsqK~3s@O{xIw`4?mZ~J< zT+O^L#YG~8Ss5(eqamG@Nyg}oN|g}%nI%WOZ-CZAiVuv1=?dnX4>2()+lBi8 zN^u0L^QRxt$qZ$f_?XJNDH-x0boEM%>AHt#X;-Dv{fVFNQ-6Ax`g8;TXFmSV1&v$f zYD3-^@Lb)QZpumb7k<7Y{`4r-cUR8vv@{TvjQrxIMsH?6ZD&pU5$kd(j^d$ZH9aNIgd?Iqd=`kXLaa0B&=|WYIaceO572 zNrN2eBb7Y#x@@G9D&#lt=ZBOwbYzqgEx$Df47I#fNgh862klmAu5D@%et!`DR1m&3 z2;Uooe+Qh3UyHyy2Dd5+#n})#aDD%6&`$N4Ae?u&f&Alx@Bu-%BM5)fzk~I6v6#Eq z>?mYPHLq~`=V!3+NkMo{5Z*HgZxe(c!cB=lf%ja3qy6Gb2zam;d*HwV2ZQkaLHM2^ z{Iwu_dl0@k5a%Vz2HLqSB7Wixfpm~Fg76sN!Q0CQY^xpMWo5C4zXLpQclQ)Aa*y*nkgSDHjWMSHk0i?PF{x#U7$a?hQYbKymA`Q)%BY^G zU@|yMRfS5D^9PjT4Lnygi0TTJROgSEkZhBc%x(=JaesMKMgh758UtuNl9_fcfEG;& zQ!wk7PF8I0p9AQ8e?q5R&a36TUxV^&RKj@;$ZPdmP#)Wb+c{4z@VNgSl#P8J7tNW1 zYJU&Pize4p}USzYixwo9nistNQl0KTEM8yb1o513{ zPvCqh31@pzF-lN=f+E$C;9XBAbPT&9s+uxJc)j~Er`FZpU&s;f%5S+ z%NOdS7dLf`H;SAQ7F2-umP~g9(b>J2?hK;yGMee(L3H+Jrt{(GMS+I-T$(dnmt^>! zjbOSvh|aSF(^~}5qx|%iw04@35gCDO9$L2oc(1~fZzP?ZhRHCB5~eGYsCK$C-@HGZ zBI&L>m9~joYey90v=h=oq=7rE&NSpsC2c~Qp9S~CP1Y{{lpmU#j3Qi&tH|)vyZX~^ z{3xKCaF58Rh?^I$%Z@Pd)X3Fx9TH*Y)NO2_g0XHud_$~wYsjnaB zl8j$%j44toCGI(1n29Mci#pCyQWLYm#p`}}vw2%J3pig})2xf~b7ZVhK1-P|-2IRl z*zaqMggMG2Df$!ABxCd4$`7dizs;UUUccWQagOa~p<8E&KM zYizD=RwnC$1?S)8I>QxOj*>%-^Oe+gxt2hvo3oMt9Ld@Nc$wvsD*JvVRSuOL`DwxZ zN}MU06%lT>s-PWUgX7fSucXOgl7`+PqhuD+cX9HY^?(xBDbUcY4u0>E1!bQYjI>GX zz%?qnM)O26+buwOG1(SivYSqTBOX{)44|_QD5=+T6@!r9A20&IM|PG)_?j)k6Szg= zYn~L*Z_{^1qCD3+**W3q{*qE^(v0n0!79wTv*_+n==z^}#g*a&AgUT3@PwGQTMk`hh z*I_A#V=cSpI3xEV_?x(cRxeQE?FC@->0tK)rH2?#=NDjeG=Www#Ed@C%7mPPa=kVW zomi+uyC((GQD;)cG)_+3Hx-9h+0LHJxuy^ptu68BQ}5+&Y@ z@b^g?_gr|4d!C;aiK)2xlwAth?x*@k(Z2^M{V^rhU5wmpFz}DfQ$k}v77v=dtsg=z zEB6Wj+nF~q?3mn>1+?ukB}p#ywHEm>Sh=G}%pX_w2$htfvPF~t*(hnL5Rb^{p$0 z(yo>WFYBbOO(}BzPVzEIZ*&te?&aX&;lLiowXA4r#U;xnJ-ANB;3a96U9R$@736vx zT}fM}#8LCmkZAKbX0^#9o?sKiQt{(Tg8fN<^Mh#9<2Wc-(}dPPj^V%7SLsv!N}u+j zm439!hpzLXa=oOPA4JCE;Tlt*XMBx4YucMqN|k8woX@Zu*{~j}UZJ?`Y%Dg?CSTU` zK100V!!}cWDTc}xANJy9ifuKsX!CN#MWtnUwSJqA_a)|yr8Rekx#&chl8(a~)2Fsm z`f_EUa|gOB8_s$@eT>&hwo86VQXtp~ZQZp_1hF^bg`t-NQXRPXSDC?~z>m;mHlI(9^ zioSCxy0-}(vJ$iUKAN^t>2dYDpmMZU0NkbbfV1HHEp7w}&PxGsxA|we-TQvYKJW?p zp@~LO>Wv{TqyH*pfNnqFuVt=Lwg%29>S)_jN-Z6GTA4qATl*aO*4ShGiy-_+5PmcW z|1t>wDhNMj+^gdh_lz=Cel2kf7e$rNC=ocT+3}20Y(EJO)`NrkJc}^N zM=v&@Z2|nV=7g;@<5@&$9K$@P47|dF99BwGE=n=ZrPz_JF`7kUZbISiF0|G+6l(NWc5 zo)Kv@W`qsncZzgS?M5ZSe{fWG3Y-nVA+EYfsYUYEChRe{R@{&0jpseDxa3wmPUyis zN8F$Fa+BO`{A*eqer1@6qCBaucL@`5tje#)=A@wDv)Wu*NyP*(PL zhHJBOKsdh#&I<}|0F%=eWvVzsqh3@dVXE5wA`YTz=$99jOsf9G<`~Bt0p6W)ux7O; z0=V-d06dY#`&0Hw_Cv0i8#{|ec)H_JY&L{$u)-1my!xJPMYD^6DjQT$!q~1_k~xLV&?^rn`}vo4W++%jLKZB zI7?y2>Ecl)pCk^zi6)X6HA+&`=_t>;R_Njuj?~5wcU#1%Ix$MnNqR_P0l{B~b3wg`y7}qt%v|4PKrBq0~ zp+r&bZY5hPiUH(fDOH7DiUsw|9%Yc!6nbNs=v*F~h?gzj!aP_&Rc|SSrLGu1yrnD? zxGy#T9i`yPj%Xa+Hy1_KI1a;Q(@~iRM`x@TcHR($Z)jZM1q;g?XdcEp15yF#c(aee zgXbX2bsYB;3!9z$#yk!hljVrDvqc&0O(nN$o-0@YMw9$0#{|Z$G{cXlQ~vE*TKVBe zU9@PX5>2!+!bP>OhuXRg@pI$`q#RPYM*i`Bqzizz#x^LHBg9&&IOG;8Az(^c&5co zyE(B@Jtr+JEFl!HBDAEQp=REwP&EawJD2#dD$a{E^Q29o#C)8vG=!=)BwSY;)&WP; zWB?Brj=%)~HnT_Z%>&Vt8>VKW*`;A>5ne*M5T>pXPFn3y3-D!_3l236SVyP20ZE+` z#8~PYuBK_M1%=X`YP=aNjnZ%xdW=)byA(zl&0XpcRkl{>_*N+Oo(Q!>wt*%GsW($) zg_=(B6>2o4wNvNNqG&aNipSz*fTX4xwbANMK^xkk=7z~=s3=Cob}|L%u^2Vk*)gC*CoYjAoJM}E ziuWlx8*jB%afc8_=m^z1jk9f_jV6?;64cF?U`eznQN7SaGS;?L2g@e3qMf>d_ViTa zjM{c;zM!ODkRdBYorapXq^P*bYBfafcTf*pf+ZP;uTT>LI9#b}B{;UFvS73?)$|;n zn1s9(%Iv5ij0UF{iUi0SzUmtH)%9Lc7w{7>e(rp1sJK ze3gp#37UjHdXw72sLfDS#dL=VN*}1E(Qn<={77~^b~ldfJR*3+*(l*Uwc6P=K>yvS zLr--L9k@=7qhmeQ0nVNQnY}2zmzoD%mGx4OD3?@e%~Lj`q_299ynG%Z592dit@`_X z5B;32uKcg^xA#+bUy^T47C0mC3msQpqn^Jc-LSlpHJ?I; z0zET8t+Dq(fBQiy1P|wwV-=&TN)lz6_=Roy$1yQPIFa~Rr zk&HPv!oizRg3W%$8B<-3It=gYB8jJz8n|W7Otq`|I=2co z7G|X1uBJ(2_BgeJq}n{Srx-%{d2p{AeaTI}B*&NJ`jVl(FEZjKY zzA-U>iaOGHM?i@Jqkamvv*K9+nX|FG#gI=eQnQ_N zK(~T3-r6ft4?6D-V7&+Th1C93JQD)GHbWf{J~x2>UWkA<$i#h=JX7^L=LM9TPwBHT z?bs-{R2@y;yHLFOY=lr7&7ZAqa25x!mQcqz(A@Pz?_JnR?b5lX%rf-DNCeX)^#4<=#fqXF!X8Dr+EiU?m4z_%1L@l`rj zXDcv9D(_V{$;UAfE`%q>FHo~7&kaR-4di+6gR?9n*E|HdQe(zEeDJSz87ks+({+BK zd6~t2(hBrul-=FwF{dN7w)t%w>gC8|# zC=9|>n*A8c+K9)V`549u+W8p9oH;0)axqQ^Qt1-a;Vwt3)6g(`E_>NZwxQ|y$@KdY zwWC<&Yv({Dwo9Xzs`IU70mcGhEc7w59#^Yy1X%{Fd6%iVmKhf;S9?-r4lAKl?I50{ z4rS_K+Pi{{TLfx#ncC6$6k4|&>S;P%h6O-n0I7<~mSc6Y&e**iQ)&46fUFG{O>j~? zV?Y;~Dw_7smdUHtBKa%^K^)#qEPh&b7<*Q$!-aefwog~Dro1+ov1dQ2uGX5$7|B)Y z0wFglwEQU;^0$$Qe5EBgB8oTEuGH`-BHzeoLl8xuLU7Dltm2*A^(r2FY-)4I2Gt8A z?RbV0W5=_qa&ehJbsI4OTdYROCN)Xe9q0}(*Ar>R2Fx-!8EE3b^J6 zw$17(NegNbAeL;!e>~6NDWJv|VTsDE2w^YKplWq58h33|JyL8oI=rmnbAMY{^;za& z?TZTC{{#j_?RNBT$yC?^QL`(h#j6pH6xqhf^Zpx zD?zv#glj>#uClAPZ*5L8P!+N-*=F;E)RM}kU|P?4M2%~6IllfV!^1vAr3e3MkD|>7 zIC>bn52)pMPgtd)aq105?&+Wv0TML+)*q995kPk z0ko5eHflVodNf~rtAAg_n&&G6sH|S~xb2YII_6=Uhtlvb)kU=TD_E}KOPJ~eUp4;< z6QWZk_XIV@9gZT|VC7#n|3^cPsquE}uDOeH>k+{S<)mAsH}aiPrXgGSiqolM=%Sk( z^=fQWnMhxmfyY#rjPjK+gQth)e~ooVv`RClHupV|*~-Uym|0_dtmH+NGS*-JJ;&7u z^G+szXpD8+hD)$E%nru~bvS`)>e1n(udQyj_0Zz<)$*ogZGuTe642Ck>eP} z-mlekJ1(=9f0z$1?Z~ zbf49r*yuo{o=lY|5MR2`pp&NQOHN+2XRIx$$pfwJKsH3-L2OQIbo8W}YOao~Y-|5) zIwU20qsDeKodYGfB>zSO_&y}lxhBT109*-Robv|I3>2kF-$8Sg->7AH?=1aWwbb4f zJ@Hk&?_2Dpoz(cPnqlwOMD2J=O)SihXsC54v)%VC_U)pq5T_dl?V8VBaY4i_jw9E={ zr)(rYA~ybYs8Gw zyb-gTjc`55&L4^MwYL;mW-TnSua-+TGrX|zaW*!ZHS>gQE*TJrmAzk zPMG_0I(qI>?l4;VQxgT;xtCyze`+dgwr0Du?uwtAvQgC1kM96r?$2t78q*(LFi(F%MXRQdU z0>jotGX$P&-hGwUL$qM~vQ-iRT>ns&x^&T^D88$<`Y)L``!kPq)e8TTIn19~)a^2v z!~L1wZW^yK`gGS$L6qbk+8$oTobIV{sE+HUZA9``FO5&H8iAQZ*AkBxYfUybw)NId zDdHAm_0{MG>Z;4q(vVj4)3!%hooa^?*1BK>W-L4>=l9)h{WUmrKkb4XsnSQeuI}U= zpheKY{#qgG;#?s|`Em^8bP)1Z)qJup>pE?Pu*s3(+5ns}<9alna4<>bw`g%< zg0bxuErtE}vys{vDJQDs=l&5DISGxk0ap2Ipm`8knDhWlH)uE#(rAW+A3Eam^S9Pi{q<#%UXi zbN#KeVp#%ihiT}ZX`etEYmzk@NaHcXM=gOgu98oe0%_c{z-PO-4U8E2@DA)*aWQsaJs(T-4nE_;vP=0lANgZq`i|h z96?Oda3VBO!=2EHnhTGFG)~k?vAr*uq~(cuR6j`@DdsaViAEP{EAb>qW1%)lK7jdf zxh;x{CTpYcnG59OtC&yP@Jiu)4gXEnx{4C&It6t+NGqpkmEs}lIu&7M0c96~HLubZ zVaKD5rt>VMs;SyA@vtu|wGy?&Pt&5sBh+&mIehmq}E4H@X);QFGv3Ad}E=mlj8(AJtqY*D@dR*qvyp)OUSg zsutHIRT+zugblh`7FoDqT!i7Xg5`*(%2`lZ!(`1xKNq31<(+zVV!G6BVfj|OJh1|>Ly$gf15>4RaQ+H`& zsK;C_n~b}lxg~R9?&>u*EXMB!&wB7AajkKtPBu{E-CBRDy<1Bc&+v5)HQbA4EmhiR z$vx0v&V5=3I&hCxh&7DXkq#_}ZoG3L!-@M)`lLCZ$r3 z`Ow1-nlT>^@Cw%uPp2kBim>~&LGo3VURnv?oO-`@S{fGe07}%*GY>$Zf6y-vz-9hP zgNor;uhBEbF!WB^SFBAEyNvV_p8j6PIj^=z)Y9n(wRo}Hm%Kq89zyvyY3@TPxQ7ls zg!bQ}o(oX^ZQ8a#i=}%Opq+R4IuEbxxEA8=+s0XpoqZU!e@J~E(H4jUwEGbVSw|6zP{&6!W|20JJWJ5YhDFfZLF%{|WBm~A zUW`cl33Yu`yGMLVTOP&8Kg`K6bG3^XbRI)D@cr{8Fzo0haIY`;x=0+M#wFI}KV5 zWn7?XtD%fPeAu6KVKwr+H2w)~k;E$h_!_N^&NG+L$o-^tlav~bds4d^%Bgx%OO=XA zZcoq%oOX?tAXPtQ*cz>?)J*O+v~i8rQ|e}QcZ(1jwHAuQ`RY>`0SETkT*6MdPeaFP zPeD1qRiY1R^Pz)zPa%+p`Phu7P@O~b1?x#`q368k@!!C87{*yogAYsar?sgv{BkT1 ztrBa9=9F6rzjRSmC1RG_*JgZ`mVld|*;VLwOLDD)_4ikSIfAb@;AZEJb@1{iidYW@ zY{1t;Y0*@*9!hV;7#{8000YL*kPYz9SUR);3~@B(S@b9V8LfkCt@Vov5gHALQsv36`RLR9f{@WCXi zdk#Y&nX)&+!0o7P6Es@85tVpefIt4W5&Fz~!LLvEXL#y^7l<|h+q8p^zZi{Tla8{y zNw3=o!GGSQ4ZzFOK5gebua$_7RQEiFZzo@V)(cQtXUcy8>P*8EI~cO*RJIwq8@w61 z>tf(KPl&6iaSH}j29>;sfz*|1UepfbD|cmEq5kf4dMg%AJ*Y!9oS`SJt%g(gqVv@V zl)Y)dHfORxSF_jF;e|ed*{+Q2N!B{W9vr4W*aSYBmkp4q`vrvKXi0K_R=)0h6m8gn;dm|8>_A|;j;dZoX!GvS;^aVIcKqEq9?E(}TZ{*Bro9U7 zHGE==5ZCi{hP*+ek3O|sX$GLdCJFb9P(=@UqeguX+j`5JV5Y+e(WQrNaWY4v7Z2O6 zk+~)@Mh^97)*4!NyPILdrj@nut=5xZ1YW9LTs+PH%$C+^7+9_4Ge7CW3wvwf&UPCf zm``}BCau#gfuze684;N8D>5>WbeSTf0`q-EZVe<|rpRr9`Mx5f14)-DGA1zJSLF6U z(q)Q_4b1ly$qOW1rbvEZe#H@64yEnHddjzva^8X5izdMOHNL#G&PJP$*dm+-$h){; zegB9p);S)ernPNF2e-$~F?zx!mGB15Iq|QgNq;33UP7v`z*0H>E1Qk-c4{u?WMnqA zMR-Ii(>VpCixS}_Fx)0RYO^_~g5Km{lzy8dg<>BJb5PnYZGd|kGWpRLJAgM1HMDS- zmgJrea#PP)Z&bAd-^8e{!+G@P2T-_S7Zzi8()nGyroW`&j<0K3&KV$Ccb{u$##L^- zSn|3yToE(r^c#qSHRO0xi}_qYyj!E?S2?ew1@CA(0q(7t_$d&QLeE{;D+$nl<*B_Gsi=3qU_T**E} zCGX+nVSz7M=t~|p6Zwe7U%$kI-?PHP>D+tT-PmFj?njhfOxyNDm`CZ*ek?p5Bi9F5 zW}kT0D3G9%xL~0CW|sk z_z*%Z=lmoe?+WwUjFjb6^&z%9D}Bi-YWz?eDJx)%e7%h%xI(_(nT}1>@%@$qsBATD zJD|NLpMZ987(o9q&WlA2l3}qi-?fEoq`v@Xenig(T-mnC9 zW#|bs_+u?wR%wI}Yqh8CA8RFYokm>-;tQnBEAZ}3-ra78^C5Jfos8A6p5`2c`ZrMB zL4^Bfuv+Pj`=|#JrHfJzVaf8WM*UQj_TG;7GfEF(Hh&KFjc1-i*lum4(}%S9R-0hh zz?%lo1LxXbpoCAfa=F=OPRbb@l8osE%jzw@UcAV?NMrwW(1K5~yxd9`KE-5MjlaL5 zdE_=sA1}-HRDD<*V1Eg9@~%9F@~4F0uPuD0^>n}NZ)dwd-9h6&)B4L-&|Ze#8&5jv z*kOLAtro9R+2>dr8R$)K*q{az`?cs*sRK5seiyChe1X-~KVX_}dJI*5felf^Q4IWW z$~^!(zedxJ^3;Ar%WkpL-_|aF`Z~;Zr5=X(p^;9MNcsHe5t7dn~>a7yu|qmGxFP1cnm9rcWC!9 z*nBV5AJg{BeON_yl5Ocgy>?!{tI@7PJ;pe3TpJ|hduTt-79;n=El%K(`l%;CeV=xm zz*zXe*XD00;2eN82gyDrx5=R`CKR~RrwD1RQ4YoE3KZ5l~Blkxf+sX#hHV8;)X%iISl)sDVH;T@n3 zmv)`hbfe2}+9N{hI{o9kcAW^R__sDN(uQL-p0NYPm`7z^xLy3On#)-9Z=5}dP~*^l z_%t+(9DgEOEVzIG;-H-upggCqHOkqIL(tzZK&v9$09S^2G7{b0qqU*hS=g-YQS|xP z24$=IBH=Oisd^5+4G29n${5Pf^%CrcI)>=+bWqnvA&leNz;5Vdh)&oI&9~_V_`^H( zHhmBFKG9A+iT2v{KG^%Hp?Zo;fM~fceEuR-&&9)-RiXL<@;Gt4m>H&bz$Ry!0~Ige z>txyzrsrX&<8bInqCKTM^h}Y$44I;Xk8iI7m0ZD%@OCCHLdTb_oca)vN_B2M-Z})Z8&rg6>aQ|>X`w3u+ne(( zfp;~~79M=-M)|$*d~$Jn{7o%PN)DqkQpe*n-SNB@+OXy!8~y&S=Cb#IeSBd(VWH+J zk3VbUZ;?@oM?Z=^kt-7w#YXF0@de4;XnnT8&ZsU9ZDrEZc=St&(MPrFgDQB5$nVj% z2k@ynyJBCO6QggZ196BsX|Z}7woF4}^;ns$(;H*$ZD>&}#Og%U{yRMIsz?-s=+>6hJZELHikT*e3#y7(*UJvE#csw@;OXMW#W5mrg zBSTN41GDi#<=1Y)n^!+4q6j`CmIT$LwS{W%k+!C)ZsF@pfxq=R7}#(Fr&HxZ6isx*V(1@{hDO_|BLqvbUoiPH(5^v+z!*S<$c#dYKqU zRozgjw}XBX_czw|#Ym_ght6i+iOIUOJ+3mY)cJNtU4Pw!+Z|PhYi(5Q7J&zhY` z^@CB#u`6|lm}H#2QpbQVq=b%ohIuam9Oj;pSN6Pj^xct|)={5?`xJ*d>aU3@RMtta z7E>v^vtEj)^y)ez0!(KtmMYWqEm-moN!RD$uV3y<*GGyOl+XqCo#|6x##OMuEZ=p} zRfr0+eb#7RgQ+~{Fs8ux3_V@W@vGx5R!6D0yP~VU1jqJP_gz%f1(vDp3M0?;jg8E1 zQ2xElQGgXRhD!>icGo-N^xi5IO-s7#C*AY?9(KP!eSk`O={>NNeR z2It8H+v62|;GxTC_qFhI?^u*hy8`u;wt~FHeJ~_(hTjxFijN}H?`3Kk9qpsnV#y7c z$-)ljXkQG}6|7o(O6h7iRypmy8lh|@rDy3$a+QudU3h?IYL-5?RRww;IGGY~p5m^f z8T~L!T4rN#tTqN@>zM7Ipxk~?|C5{`nD^6Hi#0Uu8q~a&j$VVP@DvA!B+Bcr&%iRA zy;N4Bu^g<4z5R8Uy9$*D`szAL7ywb%8-oVuEd{>g#oAqREwuaEKxp^awR%VStU0>c z;9X91J(HUE*W-LT-N-u46q{I`xG!@ZhWqpE7{hQDZ~8>#K&W){rOL$P{Y`4y!fH#U zoUgHd&l`lGievg{IQhuy;lo>L{`H7@)s%h%dem^eZWG(+{Pl=ZFEMGVd>K>X9vH5& z4uAKw_6B_$j_nayGH_!5%wPz5EC)tAHCP`)X}P|u2+A3vM+?IjlS+qRUaT=(H=;@$ z)~Dy9<${~^K{&DBaucS)*Jwr#G`o}Pb0EhqW+=vi{kB}a5(oCVLlLca!$09Wt$8f7 zT6y@t0TuJEyR9F8(^qrtPy*fAI(m^>;}fsq?qDa!2a1;*>FMq>k4G_WRUTItuD~Kfp1~;P%}p{XY8# zeqrJ&-0&rHdTU5>;OqAe=;1@!ax0?F0gAXyA13Rd&d2aorp=!tMl?9#^_6*udd6*V zvX6}1(NJvLk5L^TRB&Id8Hat9-?ZUb?I30^eqA=6$K8=zdE}(ys$mQSJj9NQ=a86c zj?04EbzX{tnnbDB;myYFx5I{?`n>kAPV0U~6gR#0vmmeioOX=WQ?W9y9}ANl!Tn!E z&7%~TuMcy730^kCSN`-EmE>r5F@mpm&vL5Nba`S4IO7XQ`|J zBlrjUr2s?cM@kjp8QhgSGPzB%HP-q6>>A=^eFy1IL#wp5>3zP14Vb|Ip4tePrnGAhT*NAmUBc zucYlC;ZS?(FvKq}!4cyrhiAC$ll4)uS%|rDq?9T85Q%#NcTLg9N(mySP^pCY)}l#M z^<1g?i5fncrXtLs%lJdfkKoVn?wP9Zka`H+J59e6Rh*uN_++C&(=mD5sct$t97?V` zF_6PTXy)e_$XOp?mxfX4Fb^smM$Mi2MuA%g`7`u1>~_m$V4>2S4gr%ch_D|;;%Dju z65Uu-@k*WVQ?o75P4nQ^+AOx9g)>p6C7Qv(4eg(a)pJA$t@}`GOU()1?wN(LSwkIW z>3JF-Y2i%!O?)A@x-I_bz~))d51vPw1sQf3jkENPEs?H%1OrDzRV+pj@PwFqUL$L< zUL|q&q5d%tTcLj5?Z$+dn-L>(37oxcEF|p!>ClGhEpb73>k#^AQfQkNZG!0WAvEsS z@EF>=6v8CX(WUUrMDPTq+gBgP7U@=U~Ny_Tq8mmdEwq zWP4vXXzw!JB~whq+$&=5vJA68mkub(-gAXNz0#ki`qPg7w39#WOrw_TCm>Is75Y?r z8mPR|*=1~70mlzd2hP&J!bWRG$1C(GSlYExFKBJPKLO%(fFuAflB|W2lgd`=J^p(Z z{NcNmh&f#-VHGBr=JW9Fg@I4%*^wNmq5=H&FFuy$!jf3+2lo7Ftk-!Kc?o6^@}6N5MY)?!$73urBojS2ml{a{mY zfB5~zrv6a+Pxy9y<@+v&lYI?m2WEc?sj=MUnQpOKT`fR1Tb8?RRmZC0Yp$|2fG2gv zt+JfY{G2jabQX*07yXva*_tJ0DQ*L>UkLy=@7n{UKZUt~Z@lUQozp>O-Lne%unJny zuBY@HEIoAp-_t{}CG-DO4}3cQf2;@iAnS?s$x|olp$CRW*#F0xiKjD9V~LhUT`RF} z&7v`t&{-DE=cEU%t;DjxM*AxDfxuiF@6h~U5VAiE>KA6(=efgWn*lP&c~BS`=guV<+w#Se+XHpXNyE0 zejHpg;W%aie?ikRptCsI`ALgJdUU=1&sKfF!#WH+nDPMcM%f#%=D?S^BWTeEJ)b8C zv(l^ow$hTFIGe;C+(kW}!C_ODIiF>lzSY)9dlp;GcCAneyDUrB?{6!rPk^3y*(uu6 zk0LS=3H}mI7I{Tv2QJ;LKV>)K)E;QoJ(B+hhHs?3 zfQbJeKmlAL5tf<<;5FNI=oYVN0~J~Tobv{9Ud8jeCvnhaxUTVYUC()xzA?g+c*AAb z68vm~O|}`Rt$0Wf+bv+Z8Nh27OC{_<*8@0GfW0Y?&y(1**g5!9RP2%e9Up(IjO+FD z75|qNvcfJ`AxFNzhC5w`kA-76__ zvon^aPIHW+VZ)s`?^&#OpxSKg@$)w8g|wld1zu8b#BoE*)~fFctI=&dT zmj&YJ&GDWaWKX&g424K7xHz=a$KouuwhU_&Wk`60`RWaul{LqeS#uJPz?(wojT=H^ z+FROX3osA&x($FW#};DVoFHCylR#b;(BjPv;I&-k?|6p>@UooT=HKz&?Bi|07GN3K zGg!7^J~}N~=yr5!2LcOI0N_sZ1jDYzIQwj%#+9f z#GTD?&vClV83ml>Vs98oxt=J*MlHU!1*Ih=38n=pE0mTNwoqDHLSPuj(vr&3O;bv@hfP~) zwX}4Tl1*DJX?4?zlG4)3;{Bev&vUsKt>628-uLtJaeVHanK^Uj%$YN1{_8_6!!`?G zmhLz>CW8NNhT~SiW#)ol;?vt7VH`=AOT48k2*Y>^3hQH`WqX-Xa`||T9{Z_n^Lk=_ zgfJpYc^2ogv-{&Vy&bOv$l}oqW-;@I)5XAX{aCFY)hY~LE{es+V5%?EVn`bvl7!=+ zp&^vGNW%fQjTqQCDC*VDTABJPtj}9f!vlKYu5;ckarAZcbn9LX!p-vzI=?yS0C%(v zL5n<}7z%zh0P}0FVLrxD_j=G4acG3~Kt>(*L2&9)#LU?e^r8r1qB5xTK`c;g=F1@AWz76kX64Cv{-$YaFdBClIokjeXhV?GI9vsQ zv3L9qNX7o`7>79M%=VyK#`G3OzZmEIU3^ylJ*dRIDk17U=#lCxp#zXA2~qNP1ntKs zp$UUt2bDHq@C=?cah~LSTL34&jhO@oHNG7*+dOES{ymT4_afU#|G;De^7{v7HykAI z6fui;isIzF;J~#}JA-n~RLy%Kq1i2vl9FA5*cH3DP;`73%qWoXj_@rMA7kG;u)9P; zoN;dg(ZRbh$%k0GMNS)ci^%6Oi3Q+_J))cu@0k>KBSB%>dqLw(6qWz*q%_4qALb z01q9&{EmZ?T7++Li$HzG;~W34pu-4@{a8d<__3(1?H>y)`aw}?IiAl7&*#uVfhFOP zr}pbT2`X%Ma?A^kH!civ|r(epX)`J}gsuoa%q$ySkk(C19IQTaJ$>O@|0-C-v9m`C7_A&G}> zX5VokN^6e?;Z|)FPA2_ROny3O{C|Z&*8Eop!ukIOtrJa-d)aZgs25VO^9vy{&J&`1 z6(@q`3k*G}^iA07C*Fh}cTnm{QLxIBLAynI?ihWWZ26ahsI_03t+NM#i_j8Z1&v1P zqOVwrjPqYXVDMeg7BmG~&1n7>GqNHxyI;F-wtGlv7xi|$U5HZdccKKlz7q;1^?M;It6dGpCuE#`rTqhoyes9_zd-egqz?<<63A8vYy5Mz)t-xK!Y9XhgrC zzV;YBtSLDHtMe0panCYUs&z&8y6fNY`ljF4#lPJ|!O7W#A^5q+NHF~jYx<&-p7{u8 zm2Jhp)=ZD-JKTjD!C>y|VgUBd_AK7t#jP@-gQ7VGOr%Q|0pc4Y5Pq&9JUfzRclUxk zT+)Wedwuh2{Q_6J-&h;`a)`Kdiu+gGwlYU{mw*3X|4ZUm9rwQ^{^lHe)QUI5 zH=fZhNgHhTnV9Ru6HnBkNKv#zkwWZucpwHK*mig)O?F5fY9W#`h5hiXhC}N|W!6;irWT8Ga`r<7+)YOPFzLkrcr!<^msXFEcH198 zEi4P@W0a4SbUT)TD=(Guu{70oskFmpe-!nITe^+C$x=Z#6el57s>Y{j4KCw5kSev> zkf5n4IF1gFks3K5ov+W_6eJs4(j?rJAt00NCmtbKo6F2m9*X;a`Y;!9PYRZ z7jGnwMQiY&F-pctO#zUVq^qUbwk5{utEICx`%-QweT>cHrE_-sW2n2)FpYOkkY?H+ z2fOa?5kbF>l(7?WlpIE76Qwr$GSRZc^#f(pc%6i!UX_|Ij-v|yNR*)MI?Ri1qOj{B z{*}hA>!sizFso&J@0whR*BlyhC7!e2mkWVu zG}>|@UXE%c;pXaTp4Ra^Y;n9*(j7Hj@!`paTcw3AUbjd=qW*9^++0o*r=o3OqwZ9Z zLnVBJpG0C-;#TX1iV_KC;Oh&=&Jic(t4>X28td|;B?D@aawKAnf|JcutV&h@?$sAK zvxZvSnJ1;Xo&wxg4dHg;+a$Mx0OoOqr)cR90<;n!R!|;LMW{2L7TqRIc03JuC*yc0 zb?wpdI`y0;ML3>8SSN>4r%5lmRsrOj;c9B1Cb@?`3owtXtP-<6i-iMNj5WFBow<+7 zhaPF9h51sv<2gj}D_J=0&zEEbA42eeHC^(nho2epykD}?57cnVC_w$ZV8-Vnas6Od zYk?H$TH6K9OLfzw@S9%l0$m3`BVUg%_Y>UJbS)9r3eyWY5W`-M{};sf)+?1xm!`O0 z@ddGhr}UI=Zj`DW8RMhhE+vW^Of!(4g~^XYNRUd-0DENZW^An4d>e*s%Wjt@x;B`E zb+Ym#@VGXb;7%F_&5$A;uLA6?6q-Ck${4T-Am8fS3_q8k0pHGA*givwbG!ynXFlyS zq?n~N=t@Z>?Yt8b z-3WMRIh!7l;%g(*^uf%6zafa*3}?pUb*>bKzj;9tD&GUmvZzo>cWgsoCySd4rIf(! z00q~T1i0;QVI_17Hj}3nNqXqt0cLbN@a;S;P*5c0JDU8E>?@LHINoL?i0$DO)R~(m z-6bWs{sFje{q3ZhyCnC3U0uNMz|Wbzi*F}+rCUNxG`qXR-{V2^UKjBDCYrr|X!2%B z^BwyD>MTayC}@B@H4*_~bt?Vdkd8s*sU2ZuU~b2N7aMfSF8gG=&Z z*WftEN4_8f$iwZf1AzIpTq>R;Wjk5`?&QOsIiU7m0C6>YINUq{Q!c?XoN_2vKWF$c z!aLj3=n`p*>mWeB%s)iuOQgubpL7BL8-B)c7+-&xZ!d+IPA!#EspniNggQ#3h{2zA zNqy8z-FmUq`Hs&4?qqV(G+aPE_iicG@gG0<_PfE+V*qs)y8Uixs^fT95a#Ock&>?b zFW_7<9uROt{=)S0%qd!%I7mu3`87kovrbESCK*ImGER4`YX zaML#cGjF^K#?&ULgEpxO3(%EuW&O=py=Nrj$oy5_3 z(rCx`eo@iLaC_Rjcz}D-y;7{>v|pe&VYH?Zv(lUIl|me6{4h4(i+=0}zxd8!F1!(t z2eWD9eduI=L||t-SaBbSI_rmG*L`U8=loC<&zCS=G+%N$e(DNmd!uH)G}7@iLcIOF z(L5i&h?uK?$pnj0NXmK_yIIyR@0%kY-HPm z7}>y3e;(KNI3&dFY>nH?q!Nb=P^Wm8E|kLiGB$3%Ty&;F=^7={p#s#|epWA($_8ry z`IbS4-@@SV!@!2r(Cz?v$u^7TE0V#!;hn{D`W6d9CW_Sqas7%FNj?88w}t z7D=-m{Q&Wb6bTEzb`iStNWeQeuze9kBMKmI718L$U|+N!sFXqd{Xpv%OOXR&0P?mQ zlR#EUJe)-f5n_vT#*e^+8{qj2^nBvP$1%tcB}6)s%6Jq~`-l|f80?E2mjp;D_8~HT z*xk{Kq?`cH&35rJ4PTD2ecGcK65wXAN726wMLOTA90ou0KM`LqLzq}a4dzg zyvz@tz7+j&GC*F^Y4uVpCymCX2N+0QPBr*Y*<(@&_W9#?T<;V!*J&s~4IC5Bg-rDX zU->)1V?4oWzZ0BJIgd+gXm^z~2+E8v`Ju=sFeGjyoP9+vy-Z5S@72p-OlAUwmz(0+ zA;-82L04Z0%DMn#8&BRm;lEqcf*dCH`!a!t`?H8fFN=kI(0MuESgeTAtZt#oc+}$&dmOTN1z0nWe_=J?< zngkH5ht4*ySEJ{e>>JZqSSaHs z<7w1#DNUK;^)7_hk!yJoJ%9?n?T+<|wphM9iktRzn}pep1@yxXr}lu>(_UrSM)nrr;qvYjtk`bdBE#G9gO^OZQLED#ZmTkKpF!^q6em}q`>i5*wKNro<$=?+=b7ffmKocbC@}rK?Q3tYgR>D*9bh$dVw{m9%HsD zT2L?H(QRW-J!%f#_UEM~A`|8Y6U-jy^ z^TAayFJTU?jgGt|Em3Boa7-Y!`5x+l6})h4*r|RQQ%i-^@G{6cVRTz39kyepsr4_I za%-dQuSm&)of6*-NIf@TVhtDSZjjOtr*s1bk5!cOsuV{@lQG*EzELXm0OHBmD6K?M z5a{Nj)V~h3v}lub1k*|do26wuleSr!Z@1E852Nng9Vnu231s#L;4Un@9ageM%Jr?* z;H}aqE@DUR{4f%0+(b-@xQx8_9kUl5=8>~e+N>0TC~k~*8G9Nf!#->l{M_mAgHHU%sd-|TYo5i7|EwMa zlgT$M#g1RBo^WQDkm06x;Hx74&-r(xvT`QbB9+OuiovB~ z?ZGfE_G}c_*Ix`jSB4e-C-|)v#_{LC&mEW*UIIUBYRg{=Kl;LQFW_zfSaIUxh23Mq zc)(*NoNL0k8C$SUdAexga`1GRnE#uu8Vd@qn4_FdtZ%2}|^WEi_?CKClN(*l-`%pH0{Z zA6U5w!zAh)Z^jiSaFkEPhfEkNcZO&BxSf-N#(+}14EViU&FWWgSx*1gb1cx_=H zivFk>Bi$#)5)*cn4{WIk8|wpm%!F}Ex3E8M!dSCguw^D}oDZzh12g`!PrAvD)t=G& z(Lm5{Dx0C|;1Bxe}J14H5?FHzxe=^V--0+Ms)_XpheCx*0x|>;$ks2154A# z=pI~Ly_QHaComI#2>k^FXe<^&@()Rq@q6nbOx;&O%}ef3PGHTfA--sgRiu9cwpG!@ zPhcz{?Rcau{{+gjiq?K2O$~hlC1Q^8UlAPVBvZ)0L0&bD|2HzMq0)b2fV-TIFi+%{+h*CLo(2V-u;J4T_AeyLaZrEc948iS3n&Lfz; ze2(TF!6FWPpMs1u8vQBqPov^b(T>un=2LW~X>{mQDKhja;P5r!>)=pogR$^$3yW|3P7RO2G^NL318((ZY@Ye$7%YlH zns*!>Z=unC9O@U|gfB$yO3#m1pQg-S5gNX17Az?T}(UMA>0f+7#l8? zY2~-lK^K>SjVdqwRB=km2;@%9M$O+z+2n4=0IQG&wW9(Hsp2~+g*w_{+RY;QJE`zu z2)+YBvuNLU(v(nN^qmD8{k?P)%Yb30AQZ695jWW-mT)=h)44gyb ze~?CABvR!M(rHAh_z|shIj#H=TrQ-RAF&G4l?QFK^sKb#BH)N~(iWg-K8JQbhuY6c z;TMba6D-SFwDBh??INM)e}Wv(qRgK!8oJ_VY3_7Cvx4Oae_S>H&)`(_i}ba)E|pRD zhbxBT!DbO0XNC6!&toNoYuM`57<_^n&PyZzKM8 z%B>K07f5m9O+ks8Z^O)O_HR;>i!Xs?d5(eO&S*8&{3fKmrUN?qSvuDNQF-pE3OUQR z2LHRCIw}_+r*xZ~jWy94o1At5ih85fChxQ<&w~&T0UHBk5Mb;HkZ0R$FVLt!d5!%= zOg?mA55TEFIl{Jy*EH@V4KnzE2`BsmcjR7jv~6Yasp z{gBcES&qaJ)(TnPZCgj@6*-a$6*&h2)TqcAIK&FjZsjk)&x0GCauj}%SC#ptgh~xT z8_Xaa(BPoCy1b7|>yY`xL9qi_;%tFKF7(sU8vH$yTsW!~r2$boyPH;E zL(@CgU5@O_dV{N)1(=b&=7(%lupC$J8-?>Jf@5-h;hgk!B(>~GQEEsL$BlyHELf7Z zAPy5|rMG$k_WNoO#G1n-111u z3X$8Prbma$b0G>FL*>)()%TL;dm@~L&lx7K8pjrZW$Dc@DdQ$R z!!C`YmSfS6BHFLm*B*7O}Lyzkr{FV1wV~`R*R5V;LLP= zgdA>vQ>NEu>wV~8gghE;z}Z*M@)Ia7Cu>A&QA;%CNTU6CsCaW+Tv=N;L{5X4 zrVo(|#Q@(%1z!ZX#lDnTv}cG=b?1i26BMt$riOQW#8LIk9UBJQ;`XA%%FwXt=zPvhuM{r+m5Qba5=^p{4w)C~1lsDQ>f4#MXQncN6@_ z$QjNJgj<5}Q^N=_8S_aa&`DstF;eE?!swCE?N!Fik#ew2;WYe*gG^6jsxR$Lm%eVz zDA{&_VS<^WOCfcbVz~@mO&QHhMoTTDrO80H$=I4K@3kSY;&L#$jkaDc&*wdFH{6Qb zdor$&7eZK?u0Vf;2YpkJ0GpUn}!R~IPC~{>*^mNE+hv0=OtEFloAJrXkw+>bF1Xj9nzlGGhP(ljd7Im?A8$*J z9OX%wOlfme*)Mra?fy@&E%OGs#}2k3>O0D=`=EL1V0On;u~dL zUQ|e>lh{6@%1NN5jZ!De9n86#-d|3XA^IcbzF~e?iOg?O}JQ7-hf*&j@%04(Dxh@7l`YyJ2|I9 zr)|RKIJpqxyscAZz8_uBlPCN^-&~p}#|3h`3+COs?m$l$+<-)Vxk+(9YgwWADLPU1 zYn1e`=H}}V5Aybk+l25hxJ`}|CznBu&|9p(xa(y;Gf%m)0%3;BZWnj#T*a|)Tz?YP zY?j=vT>NCAiHGCk(jg>IgE<>t)y37&y=25mS4HNlO?U7KDRDK=xGvg(a+o zR4`LsCotd&=|z|}*l`w$FmjaSc_arDQ+Gf`*qSM-5W*Tlsf8XT#lB6nv`|hN!J^B5 z%;sXayWvP-G%NY_2yQ04nG?VUE^KaC0+vj%&)HTqPxTkgC7Q6 zp@_%?SY=TVz!_QoU(9#3QSX9_9G45kmB?SdWPraz%rDzT>`#JY9L&z(pD22gz0VDH z;L=PuGwJ7Z{)ZhtgrBtw7l5mS1DhOCz>}$j=6rQiH5Va(2Hcas)Av@ z#n}QF^VLF+pO;+!DUMj<%d&rfWxp5wGDmjSE~yWx&3{Udz7lZ8!?SitvX+@umVyn@eTqtu}-)JzTLdaK6&^;}8Dyd<#Fv<;v;bCGLN^#Qo$4 zdb?Eay{F3W^0#Batl^10M>wFFz&tSyT47WP(S< zTL_Mx_K(;IKQmbukv$o5Tvms*UE)4WIrqT&zm7`pk;6l|SWI3X9H(FfgbT?LgnQk# z-vg6=Dz$R_kh;0hJD-2&DR~B>ak6X8?^JxP3|~bYCWigYnI7=_mg-Eq2glVuaSod> zt^&q8%?#rI;D!&PNakFGPn8Pv}Gd|t|zx}O$K5M)9?=bxq4o-VDa4_BcmxFMoi)+&= z+m3HMFfeDJ=!va>DG2Z_X=_#CWaNjG(mNR1?f#ZBNI96~eM>{%3 z;X02W;imnkqhmPEaJ9i*i34D7!A0O;+4XQ0aNOj5`Sm7_<}psj#os@{T?5B|?4J$C zeluOU02Z4-rl0>ROe9trn5nZb0=wCSF)~ie@vZ`l+ZAVKrDs8ix=38TE#E_}FM@M8 zrN@bVVaEZpkd`8hGh?J50?u<8R_0H3IpK$6RQF*XYzD2r4`x~_wcRJDI3Msq&=(2l z)NK1`Dw!|Kq1$lY&lGE~R7X?ge0jpm>&+l0ZJrN?dYlK;;Ai-1A9xDj47<+^Ti_G+ z&y$^D7U=|7ZAomH=x|tqA2uTmG!Z;#ejhTwi_Gs+_%agK5{FM*D5dWK#)Pmr%HQec z_i6LH3SUmoo!p`m9pxhOAT#iG^ZShXwMxj5qfNwv&9E8f_fhlvnEAERK4<#t@#PHJ zoY;g@oK}-!>ACrfa(}=WMBtjY*fbD+R^OJtJN&*9@FUs;t7j|x2>e`XUuk;Vggpy* z5gdmPfQx27?YUp>IlKz-*&73ANilw2Qg0?*gWudm@gFCzr<}C`?(1H}PtG|2?oLGY zO?q_~{}!}lmNibk5suTbOg{iPo7XaxJ|IttuE$S~@|OAKEZ9HG{1#I~3(os@Jb+mQ zT=!Up5&WjwrqA3)Ng1Xc@WM~QgP3IR2Ig{iTL8y@JkPonjt_UX7^@$Y4+LS;Pw8R| zOvRcbhkJ-P{s?BY|3&GK$|;VI!4@$cV3cGwS@cpL5rKz+O@#M^M6Qsz>*7WbkbS}HHI z9i^F%ffub*`4~FP&#B=ttn&PaKQWZ{IA)8FQRy-~_aPpJ+y6M88aj^K^Wdaw`Bicr?poYlg~(r1#1k^F$%a*9;=iL> zP8FljZ`i*MH!U_*%R6w>Vnq!GbnVnogK2>87)u-#)?zNPdM)-X_Csm7%VyIR_b)C7 z)u*ZSNo0QbNjx|9;&Ke(aS`KkWcLHM?qQ+pM-I-io%P0wLUoH2k+pIHUUd?`OKRnG z+``yUD^Ifh!k(~urkLd64n+i9fff3wdeFC-|2Bws;dGQo>X`SQ`wqA53Q1~ zrn&XE^Rb^Oe!9aesjJ<{YEFSJfGJj*j@maJG7nMFM zZ?N|Oas0O5$mcM_hXeZ0VhSUz9`kBDo|7lqL(FpHoj$&PF?|iHs~3|UM{(Ow3vL`G zMJJe@n)19n-qzQse_qD%;(p)&KianA1)1+RKmP)% zFba=DLCT_O?Tct;{p;4E)?+Aktz2e{#il{ncmq72fz-Md@#An}8W9IkM0XfftV0fow00dRPoi$?A+^J) zay_PdM^NK>%tzsQU1qZH5ER4@Jo#9oRWhY+;OXwWM_l1w$Ppq-7T*bP`&xSUpO zz>?M#q;Ev4OW}{_UA9y_@gy&?Uuhz$eic=8H#NKp?u?@NDn?e6LIttTfv1K>}Hgg*>5mQnf6z?(te{UUB~_^ z=h`Qko=I<@fla3NH=rQ4@$Z}X_YC{ZohfCaSFsWzn1pTOkKh(~E*=+U3N;z1)LaT_ zL=D_R3mY-5eyf*%6^$nUrc&wOz`%}1FffmD{sso##-Q1@X>{aosO)@d-zGmbd!KnZ(;)c1chybEZojP*f&}e7)Fb>q2gwE0DHHAX)_r`8O6VisqeDwSa-jZ z3f_XSi`T+1$@La^mhu)N7V+;CoRk;AyWf&W*=L#DIQn-v)$=;rZ0v@V3+=_70TsA! zykG}PJBPOJK;tO!piFE6%2E^kD?Io976=IDx8C?+J^S5eISw>gg2uPSL$~C=7APy+ zyRv4zhZ5eFm(aR*k#^_XQ0nt2_aBg~d#U~($P&lrcbe?Mh2#ubz>q9lKE8D)*!KXX z?t%bfo9r&Mm4(!>3o6uP+JhAJ4jBDss(c4^RL)WG(9*kdC0_4Y|1RX|A&S}!>3W!I zb_4MuYTW~_@tbTo`5v_gnP9sdK&}>C8^+cex;Rn!k9uN?_wbhR?-bioP7p^K@5!0= z$4u6(c~7pu{o+yYqrETV@JL$rKJ-te=eM}#xZ`~}6YC0@dqK_D+}kO0!TaP^ z>>z93hjP?V-ajGW%c=dJP;XDtpbzB3xJ$g-epJZ{%G;0Sil=Dxel!J~uWp7?A}Vf1 z)+?#88S3k48ucO84W6On9|GAb%J~RIUrkLPVL9|!N+J2omP-|mu(ZGY5)s^#*E5#yQPUX`-XcSCTs8oT_nkCzTuuE zuls^7l4Of-xF^Y0U(iL8{M9$yljIFw&_$9MzTuuEjlQ6ZB>9_fxF^Y*zMzXF+2$M0 z@3J|z1JcQM@r>GAejxwn+5V2OP6Jdt&$a^~udV8Ro~_9biNO2zg`j_22-@if63?>* z#{|itY?iXB*@bYg{80L*a=hame-MuT_Rc^|E5*D1!JJ~ZKd2aor|45T*0l$4(RU)b z$Bf?hsT|{Y4`8n#()my236A&uFo;_c62A_WY3^rotYa?%JGr#>Gc?sg!+BK39TNMD zy#L4GVos}9GAu1EE|7PUh8TxP5=H@n9+I?BYGq~_a)ZZcx9Zq$HDyPNuKbP zAZ5W<(9u=2=PNl<>=g(=1dBOURQV&6pZjY$M;v7cC+AL_LRt1T1_D*I`fHK0?Q7_I zEXlV)0b+Y_o4FOiA5X+L=wz|k;2WqCtX+R2&lP(PIFcoHKrpMdM+6=8tl+w*Y>O-T+ERpT+ty*!~09j+^0insE*~ z7#ur?eicV|eiBSh{|O>E2iq>uuRuJ0#x{m3Y7WBg*p8pk|6_OdTqD(q zD>zqtry6Crf0Yk0C)I^pqWiB>dQeQ5l85*eVVulZ9i}V`M1n#6l-V}g zX;;IH4UtN&P3Qn_Ma-4X*3|Hll1+ut%0y9o)^QxpQaKLJBd|5EYHs6Lw6cqLoz%Cg zDYf}ouoqkHa&Hj-zmLDilp@DcH!b+L_j6j6d zCcWzxvIui_ppw|vH$fI6@wjcanV{^AI3+7ktRS=LU{Rc51{WIGC!TEkgYbr-N?HJz z)t&^w0+UCLP*$OA%_Ec;=Jf~#_r*bOFJ&P#&R?o*<9cpPR@UH4xtA+xy_q~-f{lUW zSs+$MEG(Hu!{rKb>hY-x)P}J!RWZ0$)6>v&%Eu^8p5KJep)_SaV&tSNWV@WtXfb2B z5G;K+!r9;~4v)ZZE+~&M~H0DkC;SnaWaAk*O5g z{+Ok8aZ0?Ac(t-L5a}8xC`$y<*NHN$y-t}Oge;ts71rTNlNH`{mB$}=m)@k5iM>}$ zPJb%61`nWS=LgEh$eWdPL@?$}QBDIZ72T$=cB#2dN&X#aJaU^-jTpt#lr#q`WL_3y z12Kr|1Jp>$zXxwtoI2-{jZ@RWNW^R?U{dHvfwF}$Pe*a9sBO9;I?dZft1Y;lSwV|$ z2MZ8(JKA3r4Vu9PqskeAq9ZeuNGf?%V`Yio91kIpN@q`7JX6URH1m!Ht_H4qF7GC4 zMUZGbR**H{#v2W~)mGetlYe(8@|9d3tC@KFCm)!%CjgAcvz&_;MqBSd2{%#Eoyu%M z2e%)N!7)8zaPm$R_g}`KLgiEd3J^A16fJ$Wa!@3&ns#S`1Pmq-aaXZ&7?o82CvFN= zbbJmJFeHITYXO2b6H3ql_Qfd@7iLCQWPMTYzRH7j+S7JnYQLCcD zte(YNUd&;FTd=>DD{(?dEJMv314&uMaCPUxF$SIy_YD^UQ(JH>oU)!&U~?LIPby^r zRvnyrO34WT^V6ReDk4vOj0I1lrorckRZ6+~JA6j>u=kI9hHzu^%gTC|iQHF&Jhi`~ zxKVCX|2HF`eS>lkW>M4YO1N=sqcSQ0o`yG+L?f#~S%7Ql41_>t%M1WZ0`R<0)SHTD z3sE;J$i}RFc2C@`SMsK^5y)U=yN!|Clp>q`AZ7~rIizjdl?b48K8TC!PHk7hB$Qj; zg>Lf@wd_(hAW_9TN{syzVeinkca#>}zm1xAp*5k^^*zdjZcP0?^y*c{(tS#{-F_I8 zsJML2IQ@aL(1vG=N}HiIL=G{={$^!uK;N$Fn%f}v0iL#4(;}M3#uk=8-0t@=`T!`M zgWM#IoP)}eKs--+=!oca=6xzijQUKOFGMZ5PR4~~)$MqFV1ICT-Pr$`vWK^buKXPG z+G6bbTqzIqs}kJ3M zIQkfq+7&F9nAI@#d!>dwZKs764m+dlfbY;5p?>url=;!D^sWGXJn)zd7YB!)Q^>D} zRcn7hBZ7(dqY|eag+;*76Eyipt_>4Ok^ zf_ruLdq}J}FYwl%XQeNkkk z92(uBoV8Uwm85RN|7|LiE$y+X+4zLnRR{#7+tqx;tGBB$_EyF7ve;3(y4Hey?tvLQ z15{Y6Wwanroq@0;fhudEh#(b;`vet8>epDDnkcKkcyv}TkItH*scpz4M_0KeoYz%W z@AVE9jg%T4On}kqP$$7;F-AGn>;NHzy{IBh3-8UMbs5}$P%+%&aWyheTBs=nHFKb+ zx*CMw^2$lH=qfdgPKC=M#;FiB%4R!mID3IikeeQ*#$dUqsSi?YcB`Yfp+~8bjrI@2 z9Y=|Mup_ssuD75E>IRqi_EzidUw9g8_LLBrPW4vDgV@skYBH7d0dl7}G&!2b><#RFAnJ=pt0)JS|54pG_m z(c{%JQ3Xc5WDIu!$DoG2e`RNh(H3kg?$)QWR`7HQ4#C z=81k!*&jo-jrwAlfxXop1jZttnp~h;>G2b)3PNiZSvWT9F2>%rW+* zF)Lf@t`g;rx(ZU(f|neDx?K^srBX*TZvQABD~HwYSS{1n_d)8@3h)To*H@|B{|j57 z=U6orzrkXz*wV2om!fj4nu5=svFaA!T$rJ5hS+DTar`uzu=+cVy_uQnGCVHVo+;`x zY@BM1BwJt6Jx8G}lZEX7kCIw3PRPZcacV6VM3FR{=3lMm^=A#tF}MY=6~V27H8Hme z=JXkK+ShCS*dq0w>_9QH1kI^g>TD3ZK1*H4nn7n-VeVd| zvX!*;8X;(H*QkY}-UEeBq4KMACoQ^GD5cT~fnvQC#&4e;Mj_rHcVC{M3>09v1;O~XCl2uIRG{)y&m%g9h22eQ6|%$ zf0McrB|di(%MGo+S&bKMFo-cw)LVFu=hSyttO=MRssqGlA=-i|LW1h2s2QSKR07 z%TrGw)sfp&gEF2}!)iC5!c(@>g(hj5rp`qMqw*o1h_j~v3~iw^1wv>CP3Nkmh11bA zFuc57oh!=5`YO7%VhW+rTmYQG}l(BsP%@>0@O*|N&8`Z^Xgw1{)Hqtw|-+k&p$!VPU zliE!rpQA1Tws|GoOXF7JQndp}8}CN_oT$4;blGk9s2WE-H&JrXl;A#}-pM6^3)Zdd!Eg^mKF%N3T^wL_?J+VFApIGFrGmEy1U40h$-@ zx#5~0Pht0~^MSeMel^1fMa?;k;(xhcEfO*qL(X{BGdrp^DX zX8N5=_H+C;6zL_ ztaBR7Spj{A(|;9endmyjcnYyuzjn?7G*zf0FN&C>T^w=LLqb=~d`R%6<{{N{;u`UN zv{UOt>Qt00^~Z_X6TW zxgoQctCS5<{yl)2!_;tN_hOh_!>uEY9D#qM`UUftMf_*My}v2pQBl7+j|vsr{-`KG z#1eIikcfeG=~B4DshH8Y$!;0u`$}SZ;I8i_Y?RQ+CF)e6S-EZT(3MFP@hQC$;#sm( zXv~F6)d_ylxPR)5rf}tYyyuq+K}mfKRwcydF(E`p9ur1W@#8S+Fk!b$O%c=$q1MM# zY*=_u=-xfcgoGp8NJJ{Agl-TYG~Oy$EHIp^{45&h%>fwdKd3s5o=>O++%hrCjbkXu zx=vIrP;RVNH`{TfBYK58f~srO9HCx$q~p7uX@gua@h1qkHDNV%5G(syI*ee9ab z_nh_Pw>K>;QD!Q}%p(omjOsAI-OX>X=WBBsO)tQf0}FE3s;heN(Ne3eGRi8P(;VUG zNntOsCNRdo#8!C^YHC1VzGxi`=$?f1@pN>Zy51hb_giIwI@2iH#VUc z!a#fLX4cA~2GYK$Vq+8IFv_>7VSxj<`nZL0@wv#waK2r*2%{Q zkz#>wE3WxEF-8khxlMD*0c!1c-Fg|z-d7jf90QTUGQJuqVxKz25eE=kDqOLRRIyLZ zb_@cjlUYX?G#DU@`Hdv*s~-YTXQA`{sb)FiFN~Go8w+dac*SZmT6n+*YLa6p!mREU zNIy_x9K!(WBoMd8PjMvrA&qK=ke&KKl^scbQN>zv_3$?R&HU*fH4cNHvOaF zXD+j(jDo{4Gw}$`<#fJTP3(OIf;m|VzC7vN$^Fa^K~XBeom{~!k>OPPp&I765^!&s z_*M-_E5pb5!OwiCCJ#>o$cq(PgjGQ-91|P_$D)#sINll+byfb68sfML;Ld8Q{|MN| z{sA^i)n@o&Bl!TNC=(#B6d5xQKnX%8*0-o`J9Nr)ttYluwul}}T*LTFi#pyLaI}q| zxQN$eqvT(zZXd#jAGtuR8vX=lQOIyE6vLUNmo$@!T&Mae>RZZbF}{h8`n zEwHHZBBJ)s#E@>~QFV(;H;n*`uJPX1j@LP-U{JB+i(nqzVCgSQbg#kGd=eEJze)`m zdNXp8;kcHr0e+@=8r+X?H^Ffj{|W6(nV+jMgReECc@(y1*vWY_s_}5FSv=8eK3A87 z@+Nb(^|=164rdM}{0DZx1f%9ZYNB14=q>V|<7^ig-Ttcv+w9jtqg{o!?l-RqbsAY; zs7||8XGY0MSVeTI4L$OPFV%^{1i66ShW-`mpG*EJ0n!s(A2+YEP*NN_HnPr&P}_2Npc5g#6oMu1;=OPb)dz*g4-pjo(1?zEcm2?Ew}! z9##~54+|AGJb!L9R(=l}#H|E;d17RL9CMFL(eiAQsNxL9o-jD@iVN*Oqt3HWhUy(^ z?@zx>4jzQvlr=wKAmJwGk77Jg^P@1-g-lCl)pV2_dJg3*BX`1b-AA^*D#awRE;+B!W^G!(Pp3)Fvp1A*rv5aPXSGg?SByYTr--*3TyR? zMLq}4N966=?}~hYHdVO=m>5eT)dXm6aBY2n)}h>LLR+Yzo0byly$b;mE$v+RMxeIH z7V4{nENa}Inc~es+HutG3Q0Q*-B&6jdLf;Wwb_oTK;PLD7b{x6D-R&<4=nVJbVSkC zu>7c6I6hc%!E~>x#R|(f3^BRdSR-)Vc+GmFUDYCOuG>s(JS<_V@VJMr9kWkU36Coc zF%lhGj@^}yNW6jBN(^f$Ser4Vpexwc*@v+9L9ozH(^Wpv-j7n8+8NjFW+LujJQ=3D zw3yyAx`Ity1F4}0&Z5=2v?09cifc|+ura8wmSG!E0=QR#ET*D_TtS^Jv8Er0Ej3Yakf&<)^%Ej> zvY$4^!P7qc$02T-7^%gT-)$!FilUDIaQ(6!!rjw7h{vU1-d_ec*G%UvnNK>FF^dsw z?lW_(cK!{1bHimA@OHms9uRqrhq@>&dBDAZu))to((gJL*1%R9&X`1l4Qq1fV|}*JV6pkBL`|c zEsH)ioHz72>BWKC5dfh4c|?6YPK(1wAEb@MCw-7mF1drW6z(&>Q|*0d^B|2cQfUUv z^&s&3)h9*u$HS)8-(!LzYp@n8^mr&}iiTsxF>T0eFyz-w^@Fu|$De&mLPsvwus`O2 z+PSC5Y6w;_s*I2!pcE7=h}RA}%8}e#@`0On4C-BW6ODYtdt1^+2B&@aE<4M zi-v0>Ez5$o4A*i{#NtsJPj8`v#WX{zhWmL&KzBerj?f|pb5E9U=7FDHv*yAcZr2EH zDsqS#sg;4i)g!eDp4{=s?RNrzdOq$h`FyhJj}pO$hUPD9R#w`mIe7s(1jevXd8=J zW3)8U%?DCcDrR^#jKGU>*=bsis1EMHx#(OS7CS8Y?UcYhX&P=volZ4ZX(O*$intu) z+xN4+;jAqbz8yWI<}en^$IP@G4=;L+1#3}R_;gWlhsFwSi(L=l8QMHHKx;BJo+~|< zsgdJx;IZ@+?(ZKb8gKJBQ4OB`pyM>T$1=oXrdVV4N{l?PK1+#LYq6H#uA6nG**lKMtTCRaaLhzC%K(gjg!35~$Cukvj_7>b3b4KnZmclQg zQXPus*aU4MA{R{5GQ^%aX0e6WqI(W)p9own)P`87;H2wN=4#5jPJ7W-Q+K^~K+N^? z$O$`xH+OUU5yzs+Oc%tFo((z2dS5m~3+orz+7z+tjU#Z*Ebo?O%ACgvM7BqMbF`6u zrl(hB83j4oHv919zV(GlWX%u3!OYf@bCRDF|ZQqGThy8CjY zagXIvWf+Kn6B`TA5v_jUT$!7c6l5 z&sD$V8&0i-T5{;i0I}`F)ojh>5H%HHb+Y_YY){HA(qeI(X3U zXVorI#9dle@4s9u2rwMu91|Mucm+SbmG5~xWy6J_jTeGmy%4m?57c@^XpCbsKvr|| zJmcbM@QWo*xx98E=yg9(`z$Ss5?|CX(LP&C;4XQ#mKDfd`Sp0&Q^&#N*=U?@IyqZg zqHYD4Tf^Tao(b+lwZ+;fXsSKM+KvINb6Iwo-#5dtxNwdB6=^IPFElp(36_ZWl4*;f zxOb~WbjZ0S+9}GvJ6QHE58@{5QY~NX;EyL~IV_)prP@p{21^UW{JC43f{E|7ccXvx z23rg&tedON_ChUjC^Qz%)oN|tTdldan0%pJDE3~2wP1HBv^(Afz84)m&S2c9VFM0y z^a7YPEynr<+FahK7_m^>!uoEZwoZuw25#UnRPmseBKi%smbl+wa+nv~=O*CdzkqOs zLF`6Qf?bLEEH-`z&#QuIhrp$(6r zpLLV|I72D-ajgVhBc3#gsoin6Os5~$MvMCek)6nk7xjW`bBf%TUWLn{;u(xT++QQE z-Qd0;0FHHV0m5H|dlGk3LE=nGmoC#%ZmI!j0~{BGdwfpDQ8?Kt!1<~y4&xf|4Oz?m`&#_%=26Zhk~Ds*|5P->M{ zjSFx0RcXoQ6_yRB>~WO%gqDi>DtC5cks$rS2lur?Ud#YvE6IzCd!Uef_l-O!B zivGJ%7F$uc?k|qzcr^%~MNu^{$RJ5IFoI`MsmHg}<7@Kx4tadeNiu>amfV{=8fG*{ ze-pp0hK-e#O3AHQ{Z0#2)FfEF(3j~?Y2|+NQd}z@4bt)yTCbb- z)uH$&jC6u&`a3b#uEeaB+o*UNx&{N1hG(=g``@t&`je}d^1iv?h`nh$FfF?5RvmlY zp3(3Q>nd#!B5z!!l|}CWaa`BzxcRUk?zIx41GZ7lD$l49dy!Xbv4K1<9YpERi1#lV zR*Tk(qG0>yvl?z1riy1_8DsOwv#4}zo_Zgf#J_%4i~;56pm1OmKc{WOCt{6g+Ldci z0M8y{#Zs>xFD`G;Hbz?q%CbNgGbkF4#lV^$!1ko)wH+6kIiCCiYM_u7@CW3)0G-@K zNiU+3-!^hz)ROu3SCg8qRk5iq>jNk?ABa2Wgj*5QMR?sZU|ZfaPk#kqEwHOPX* zUDG>savcmv5gJLSZU~lb?;4ZWqr|q|RQVSzD|8Q1a7V_5GS{icI8KkmHrX|gxI)PN z3SkPS$s%GHfR}smlHGi zBTCu`ZE=9cZ^SUDh30KUCxuR8BL)I&REQIjh-WoeH-)?koxwqPrglDx-BBj#x2@12+`=RnrDX{BWCV09fAg0uvMUI-ipag zSWSNw(zfxh+>UAK8{F`X3IqBR-|dZe7*XGAs}wt4v48Ef zh6fFP(sbk4FItmicH0#VQjD=TKwod?IL|*X^)af0^pH;94q0!saTqS{9%!sl^*ue+ zLtqXox?k+IcjMai@*6P!v!a+1e%sGy5myr;qV=iPRHAL%Wg6aR~hgs2#t z16|W!Pr~o!{(1}|o$0T~dqN1l#u&Xki0|RW>vlIh;TUMlh}HK6B0OmbC^3KHwh*|#aj@rA^dePCZx`$BW zzp+a;KS>XBe2P%Z>TIONN%{mRfaWAU80z1f&yNnsm<8CTSq6v39wy66ghG>F-Lg}%%L)o#Y1WOj<43h??AJ;wfDEQmHM z1L<^%z5thO7pLkt4*dl!yiz}kTbc64fB-x!GX^p>t1eCFYxGmo^cgnX2UMS~CsN0l z9(rIDG7mHkr6cZOE>{lx%u}mI88#e#i&(B2EJcsiCpfP8t)qigIv2YQJE8T>wrglX zh8|B_rejx3`7GQ-^h-}oAI_SXtJN~?g?SHuJRH{{uA>vzn{gAmm)ix^m*c6V>)^c~ z?k{j(!MPBWLG2lOnsN(%f-qd7Gb&S0rmrt^Vr%Lf3QT}ZJ?e7SN$i-()^GkY4VGa) z0Kd76zOZNt83#ddQ2lre8uD*Zjp$K#rmspY5LSVAwT=EH()3uVlM z#7R-(z`*@egUqtt2OyUfmq?jq4T&BJe-zxs2=o>$P02uhpGs3Z>Vg zv7>#Qn*e=>hZ?>M#4T094`HY_X`;Se*w;3sVtM}(1+YfuSTDOykM|4y>W_oJ?iw6- z71s`v6>VnFhA3X;gr!V}>#L-yjb2hHD*0eq$gW6#gy9NmH;n{5C+Mw?A;Arf{J8(TrZX3e%ihMADHuT|tz`0ZEZ@Bt%y zqO(L;#J3}=mw4Xq6v~L1Z{PV*#p9A*OrWo2#nHaUmWIUOKK9cX=3IgM8Z^U+{`Ixc z5Yz=;a0`dl#xm5YY(3L)#t&n94*HBA0P5t+yd3m9CumoWKGpRjLRjuCle&?TZh(Hx zr13ZCCmd%H%4^pimWfx|tMA9opTZl_yArLuQD5gb$U5hjwP10{Bwcp=1mg9 zY~})27pJgl)fdhfI?Q;TnRUBapW2%<=U|)pwd2c~d`t^&)>Cd^EFth(!VrL9&W)wk z`f~KH@w%Dl0?qhVchgASrsx@h=w2q;u0&gKrYguxj*nUNiYfYpp`2S7K-?sJrJG@# zOhSCG$cjgzuHlBj%(O5u3RXQ_FeZ*0jMc(?!x){6L>60N`V?a9Gi8?Mbnu*=l?J;T za`m|0JYmS1jZt!TRxnX>t{yI`mU~)@ohmT+vJq=bxBMZNiMN6k=t~O9_iNr9Df|#-7h%lR@gf*`fk<3?M{t8@9FGE;_fP!MjuY=*^gE|8tfcw zL#|fMv!Mm%2ugYYmzSZ4g#8qcVtXZC_;Gq?$yi6SbK)NQAneqP4ARBptSQkI{h`#vx zP|kFi{5W(rUFZ2&=k2glvAOYfJ$op3D(tKxu&K!+#xljsWfftCZKa4AY=0b=b=Mfc zyTKv42zTM>b3N{I)|`XkhQM76HKV#X>ZS`&b2rWLJ*aV+X2MK8991)ZChXIXY2i$L zHqG7>7;y_%3;+4Hd*3d@YBFq@PDH#II7V(YXf88YCJ5sKu<^hu3hy=-+1&%I(XcN{ zZekp@2#%!z%Iyw4GO!nZ&cJnPN_eQnASRAWAsVG%l1-)dJM{2zJV;^|Ge4M>7Mp$Z zvGQipCm;@!&V9U9q*;`6C#n|QxD&kjm{#8Tzc_mz_@1lwf4uj5W}ChKjqx7Cdkhs;rbHr1aP%Wd|OlCN3kUk{aznWVvyzRt!s z6MNs0_-4W0_im`@Y!unMeXN?(jb4i|(t!sv58s}Q@xrb{7!ks6{+-+8`-MLm$3OUo zTz8M&YQRs8?;pPnV8lr}9Hk7a+ygL0aI@jO>_-z$3TNpPWl4c%4ZIz3pTW(;we#2F zn*X=qa-q&v!I2JGT^dZ7o;^~JUCu0reOD_73bbI!(+FzXs)rCps`6S{;=*w8&I`K< zVc{*m2;a=wi_dhwy_Fr+wEoxjg? z{UoWn0|#P8d}2m-;QA(M9R#ZWsEPN4qnWCM%)AMrrlV++L7mZ(I$4|S4??)#9MKMU zx>ilb+^Li7o(#@mv58U{6&0{sP0_|i0D8()h{$MJH&sjS&^gxOHIgRrFbIx+s>X6; zDrR_OkXDsuBW{Tcl0E-U!^P)ynTrj#ayT?LD_@`+UAGvSqr)Ew#C8Fk}o{YxWkI0VBwZ za%6^9jPSzSwdE>%qK4Uzh9gS(#|B`>_Z_eR;B0p>5Q6h-Ian#$^Bc@1!-}Gzl%kp1eDxyNbcD>n!(2$sJtDH^PVF#)D(_OT)-oNZ8t&5an63m( zfYdM1lGQF4yw8$_vzvQMw5Jj4K@PC@mufh;*i{bRt&NN91{B0fy$vJMk~1-hjjGlx z60VXDDUwu;Y43`ARQ}Pkv|*k2YAdOX*v^I{)sO<&Z)|Enrp z{5@i2a4VyojGPCfU|Ou){cuD(8TS(w7Z%QgB_JIs3B4buAJrJVW1d#x?+FS@jP54m zW^3*3h4Xszf24I z&y1B$RVFT6E7Mj3;WHlskpyJvL$K!rDjxR8155eCaOh>w!`fWTa|(aa6P0C`+>EW- z_n_Z@o~5NDeP%hdol_=kFM%bPC9b~*|Cu{=OTBvt6Xqf z$F+RbH6(zpa8w`o=Me*zhacCbtNr5C0oYvC9_K!Q5l?75KVfY#Fa>`?%j(K@lHv&$ z-gb)fhP3rhpfaJe_;Z(OBOwm!mTB`!1c{iAuoS>7i(w!(#hDrS5x&913(v$4j_hZ_ z=Wxh$-maQ1_|0x-cTo#H8!${44$}?aV8<&IK(EsSsQBLhBmSK5_=>i;-G1DY+Kis( zBAC*#X}MH;Sg$_e@fA;LiF#jzaEMbWBx^Z3e9%)`dPg@S7 z9LFsFd6|h+C1KTd&vLEH$#E6!@T}pUwMMjle&d3k))M0eg$MZ{aHViN3_kOoh6PY$ z<R_oJ<$cCQ^66d5=Xz`%5 ztQAebFFiH*DhGU1Q}D}91x^yqT-hY!5vPN!YzmosI!NoeCV5_dI>^%JTm}M)RaadB z$WUJpufax08W|p~D7C)1iN)aaqNDBL^T1TgQGg(MkR#b~SAyssZPq4|bTC@-R%ro! z3_wBxOlGgbq7l!$q)5#w=oOk&uGTi|V*wN*XeoR_!-}F5ya*i&0{%rUpw>*g;(9V{ zjvui&UQ+|tL8*IDD*^=6IqnLA$~R1cSy)KC1{ekOyMP19kF5T zC722hO8P%BYsV44f2uKi)4OJhM6A_#d9Q5(tDc1F{fqyNAN`SA^rk-LTTD=a2 zm8)E3W$!wz6rht{#+XHwjf_c+i2Bk&IruWlg;M$o6dsNFgX zU)41KwW>lL0i64#6_nu578cs>)S_tuQ61a~K2b-US$I$q*POfx8VN}6*R&M>gjifE zivw^)uR(o5rCvjU*qOXuOK!;o97dRdY8Do6uYkdR&{n7^3)gF7)v-sS-z(x1Ikq0k zkuKvmXea2st_}0)8UKi_}zu)sZbbcI`e*h$2DH?(PL!%nhndxOh0JW{xD zBb1lxrEa5^sCKWhHN-D{iYB(`X0bMDV^q@4cuR$Aotv=o$|0eBSXL!(YK189@S9$N ziEn9J5K#Y?7ZAHyo9~~9SyfMeH$}pz-e#yswK8K1dS#OA*rFx&y8&gh_-o<*3rBez z4@U<3+bQCxRxl2`JaE!uW4 zNVJ`~9p(88W1Y(gZgG6yKcwt^5c+trs-bp9eV~nPvIT$22U@=BmJX8n8m@6T^a0l5 za1+l5$h214@1$pE?c`GGLCLKFOCGdm)@Tu!!`h`EW9rtT2$-NiEAK8pUV#e>=cTlY zw~y9pwUPd5YyZcICc?-$Ft!mZSO!f)JX~BY~0B^w|SrgJDVL( z&LLPaz#1fe%@?pJ&qPpfM1c!KV0R*{p-I}8Sogn6#(oJIRDu}R4W3h$)PJcZcQ0*{ z39HBQ?smbc&8VtL`W`G#AN?AVxLT&{fi^M=Af8rLEsOVP*>SVoRMaw@R0sD!d%U+1 zWPCj!??X_iq7V@U73Vb%bZ5zP5Yx0-bDKiT;cp{xT}ZvwKJI?Ros7V?%z}NuEFTC@ zF73b4cIxvG6so*^>?;WV*7Fh8NDE=TBzFb&QT4wDcOp&LtIgII0H~oO4)4{<^#{ZA zlCpi;thj}4Rt@Ou^0g*$Wo|IL%)!r&ueG$ehuq*0+U)3WG~AxNUxt3Gt&e#a(S+VF z+IN~AQ|^7*JHFGF`yq`B{{x{~E4BXtD`Hpf4;uHB4gWz4c3tGbqAC32#EMv<*m=Z@ zv&(+aMnuO{guV~_S6hNtltSP0f73qaxs`%Hv}Hb-(^to8`3Y@<|51nqK45(4hUVJK zrk>Xp*Si(A)r*_OJm#j|Cr3Ky<6@SCKF4;{%ONffcGQo;+ZWWA`Ip8z*S;-J(x*W_ zC3Mm^V{=7aC!O{z2$X=Bo%O0X?gflTwUL#=2DbQi)&u<*oDd#NT@-&D3$BEtMTmnF z;abCQNS>6ejl1-q%K+S)%r2S@Q>Wf4jc{lkXTPO z58{QAoGyBaEa|N$N#X@M_B~vnCy^)>`+M5(<4SsV_mt%)P!-mWT{8-f65%Sibhvyt zODd}(61!6WlmYc{P{3$w2p-6nzS2|CQTX;(@YMy-a2e(i80c zsd}mp7rt0M^jZG4O`mu!Kuwq{UQ$ojm;07WZciP%HtZQa^+2TWX}j!feMN--87LDA zTDOz+(=^SVaIPNhlX2NPIIAykwy=+$C5bus{JxJqR`&82B2xX&!OXI#MMqiDSKo%G zQVRQlGFHj_etLiZ>R5?;pk+I(?#4#9AcjcTFTkjN501FSo~K*>7u}CtA7g{qkn{9( z|C(5}L#KSgyl8v*d3u)LUj;gD6N?qzPYpc0b&(%e2o2QBVqOYi3U>kSm01+4Io!f<1g?@dj<-;}CLbnaB`Jxm{g zovO3xZIN1d&E5uVc}Z1!$sVrf`rmjoP_3-L<2E_w5d0*d=3h^<+WstMp|tJ3_UtyGsAv z|GtahpRWc-1q7QXajp5VsA$O;r}tHtPH}LcnB|>|(d7Pe!l8=nj zxotUpye{yzj0eN;hCfhuz>dB~FN%rT=@o9z{+k}~`D=imOIvod*XQeteK8+~V#nX8 zPmO5tk^B8gwA}d?Or(dV=%q0qhk$1MT_5I)sSSPaxLL;-^NGVxpE~@sOYu|3HWWG> zK|MjkhU|`&OTlZM8OLw38~d}n``cr`e*ul;$wU9p)7v)9Xrh~_S_&R$87xnH7`M&W zMdQImRI5Ro;y6VTYF0n!~c+ct^``cqDMbt$LRZd)>605c7}y%?X|wXr%I1J;UINC;ylUb~4>E z%WPBr`!AY(;#U2Da{(~sTAu_Y;tqY3(!9@*BojMri|)|luW7_h7;9Q16G~WOC>f5K zo(hKiz0a+i66pA5w=n!`H#}eV-2u4|gcj=oHFZLy%8~OqmPF`pB&%4T5O?mUCr+%{ z)$o$}eyJ+f^V@DgP^W*LIFS#x7OoDi*=JZ!lgyd=*2r%787*1YS^=Gd8IcqLw^)+y z)cfO^!tr-vh)Afo3zXhd+TW#b?S94Q&Z(Ck0P~VCSrNj$Z+xDy31^PjnbG?)yHqdoAFGpJOZ9v32G`8H^~rc%@4(&q7%b{$ z-J|#NfAyt(>pl8|zQ|o)o;ZPbU}oznk+JnWUekNF-b?=*9zo8>u|fdN!_~NWB+m-zcN*h0c?^Uj`p-)~4iqyj+WZ zQEF#T_-Sx{xE=_n?iilY6UdnH{5yunW~qZ{a2)(6!+Eeo^+v$LQ~9y^?*g81nbUoqyLPj zNTVbK5H{TMb+AMZcter%klck%zn{rG*Jp6CAoQ_MG^;S|l+vK?DT z33UifWoh9hSIg@8dh$7}02N_sQS8B!z<{+&n#N1B1$v7Auv>oi0=+jLPtAQ$?&&LC* z$Rg36@Q|LsJ1S>94A#l9*FCHc@wfOD`A}v2@j7gNZzGA1=xX1Wi?NO#(smX zX}OMjCs*q6cFHsQG{62k`rI2K+seun$QEkCN_`cSa#{DB-pf6wmsfy2#}Uu#Lw!Xu z{CV{HaXI|F-m4R@AY;wh0*V5y`Fh{(kkJA4@eZ7ftTd8_UUk32pf9fA& z6J(dQ`gVLBUaO}l{mknc2dk;;^b@`llKQef!heP)x4*1E>-)q`dPRr%r${nweJ55) ztM#-PAHjZ%x{bBF7N2W zBEUa|?~(zf>|Moc)$fAK19IeDeGt6f?}0XP+VVYpI==S3hhYRfx?O=x+O9xq{)J0n z2d!z2Dd!6O_wjbUt}E%6whhWQj!cn26Bpzu6&h%_c8AhFwfA)zbhF-9i40cqVqn$SQ*+Rp{(TJf1s~MQ2WCslveI=z?PN6rX`>6)Io-BJ-W%^ z=VAjfpa&OCQ)-j~p8KKBV^@nm)cg13PA!iLJm#cLk9IKP7sMMnT2)l>5vpD!eLq5- z>m(1JqWvhTxdtOo@E;Mlaqc7C0$*(SNEfvgqpw&KaGmGWkM#uJ#_{85j5EtV28XIg zQv&k&$2y)53K95dOwDEy&}>|Zq1BZ1B`x~5cu!|dLLCbxpoK~{UkWf zGYA?8fv!BDa?ZUNqwkLu<)fbm=o~M*3qz$1vtk)2%n2Ol+^aEl!1K-3l zsub#JiVlW_=i_NQ2oAw@$8Rz#njjsI>OI-aqmb=~V(?t+r;&c`S@2o)89c2wszuguy;VC82-D0wR)o;mi(^IM}pMj`XQ$KL;qbd zJaux1ppyR7otsrXH63kIQ83y33FVS)RN`04R-$SXPeAb^~w?T}t_c|FV zV)~6#W#|oMj-+R@iBjnUn)CfeZ@@0~8#Kq%`i=E59f37gBVQIr7c4TP<0$HsfEF@zi$gP78@XyXIHl{Fj2T!>SK*L2rbYI>Vk_kBTa3; zq+BB1kWWdERPG&|)oW;?T1SVvq8ript+a&+y1{*0Q*>i8f_Cf1ptvA#&%~@F6Jt}W zVI((3!DPdj1o#@m$X1)iD3mF5yfKnka0<>eS%16GG;qq`ZwDQy!Jak4gDBai; z+8raW!{aBM)@9udSku^mc{~w%XUu zC<4IPL{NW?<#kyDH{=G5fVu&LQN)oqk`>9!pur8RyMsosD;IP4Zqy39`k3AvQNG0CWLB-DC;nkG1{G?3m^34tkH z6{XJa3SNS=x*D=`Z&#yGiDHEcDg6mIR~2Mr{U3r#j=eD!R*A-_gSTz;NaHk>@&o=u0PXXmek*5}Ao8kuL8jBB zLq(Sj@`OsL?*t0Oga%Td-y6i-R8!s88#aOlcplc}ww`Om`_6U3`-s(-ib5Y_ln*mW{@&Hc=>}zDl z3_!PW+S-{f%o|G^; zXwA{{jdYw(Q)wpC!yU6jjrOu?8{UkW z;sh)ij(|N`0Q|cHh?^c*##F~Ebi7-nZm^MfX(YyI%6W1JJB>EJbhut{gW*QNO@g}} z?m@WaaMf@-;OgOifujJSQ2K{tU4Z5mIo>qKyVdb-tH?oJ*IWSkKE2`R4E!AFyIuW% zhx)%*{XY}`50XO{pyThv&!BA00R`RF@Uuky%)bzdYbk!JoUxRAArjmzwHKnb_sIB* z5T1My$aEHe_wmh^MHfMG-zznU@!dxc7Lh?fYwQpsp=6Frx8%ESa1n6)8w2OV9t$cl zLAW$H%BxG@u7SG~?s2%+;l6~}eT_mO3X@Ty1_s?I<5<|2j<^F88#f~azR6=A={`K_{B9QONB z{_Z6um!g=*oZs8|dr26~Qs;NtWyte!2WAc0<$EFwW|Gd1% z>xmPu!hHqzU${7&N}CCH0-~`_&xEXNlupAkGImX^0GW&8UTu;f4 z%Z=ry7^h3G0CnINt1FD48pci@Cu^=SoSnVrmRB7NO6*7@zLB^`KRTivqpYWoHi-M7 zBaJkrgL;FHr!i754c9@vu@A%HNL0zyn?4?C8KGXpL)Kf)S`UZJsxut@2VSb@KaNQprl-5SXjF6dkyAG9*Bp=Ph{>jAd{71U5lxN zJ9MwO*2wZd=c<{p6Ch2zxsZ&V0Nu3d_*p#x;{{Z+yfCewa`Fy1Y8ON{F~xzJf&z_j zkvu7nYJsDSE&K_ay4UAHDq*gcXYBPquZb@YN4a)hXH3CZKj3<(SgVkhbq1_vMp}1O68@=e>xvKC!6~EiXwzp|P-WC|<=bG`jfyDMt#8WyosLEowGA;8&A- z;1ApaRcEba{R8>0ljHv|QvBE`_u(UYo0w$Of>?S*a*9BKw!Ndsi1qucHTmN>?h<)b zleT}D9o?NU3AY(5*qqyp?YCll^4 zddF-4#ZW6WDt?7!Ib;Yzhzf=8bmfjaP*r!LGN{;?;Ud@C%nMqJjU@l;*pqpI)=>g8 zjiCU{n+YbxO6N>iaUdq{RC*;$_|xU{JAtbrIdZ2lHRcVJPLk;$xqD%8opqNHAE_4C zB<}_-0Li)TE-+M)U4IwUTJ&z1JXJRSljJF+j2A{J86ppaXG+bJFtSD5ZA?BBw2FJ7 z`=Ph*RVshYy_j)_Z_s4c>_T-%SD?Hk9Xs;wgT%u-oA;^a=H3T({#L5*Gp63ybY+2k zGttd}sPJ%`fH05MIlym1KPox_j5id8Dj0@BfV%WlHb)sMcFzGnV1LM5V;*p%W}QmV zt(^;<6HDrI*%cM{s~La#{c7YIdO!3$Ow{g&L=Fkw%m);Kje^(VO_!)>pJyeBNCdeB zFM0q)K~Bt5nGKi+y~LaD&NGfQno&|Xv&9Vpt!h37eLQkGUrnVG78oP13`a{is;KEw zq!2Bf`BDV(+k*+84Ff}Gl)xQ`@M^hf0n`FcH4`NBIXtnZti``CK)-wV984WPvPxz`*>HP1w!g%8s&7$pv%Zxf^ zH04P}oO7QvRt?^Y(kO~a!5%&BgV>-n;x~!3H5>pHx0&oS?TH zm5r8qdI3A>X#+=wp$WxX<(&lGOJ?DWg*4AB-$j-l&Tus2IU{%#w*Zmc2nK>xrL#M? z1C+HSdOesF{3ahVs~zE4HOYhV?@QjZMq|Ox2O@L(du2C0`*J{~D1^I7|Hd6!8=- zY{%Zeh}(CHxbS?xcH&D;TktpkBZK|_BmThui2qi_gI2;xC%lH=g=Zj@ZLRpB;UQtf zS;47TU#&XtbBcahL^dA7jkyF)(XV*u9*|)5Q?jY)b`JB~; zCB0sNa2CmX0fyc~Zh=k$oUT8aL~{i3_^0w=@m?9fAkdqMLZC{= zHO5(JXD*JDD3a~=#X*T*dw^H!jO0BLkf@+Lm((w8+3;r?L?{W}e z=O0J1QTQY%QS=AC8U3f5Yp9kkI+G9=1xMHunhgF3`&cKugoVvBq&~w;Z0Q3c!t?X% z^5aX!KYFrg4mK1GOiz4aa1FI00s##;Ec++aQQUg)Ps6z@!Rvr#0BNAo+(gT{VIi_n zV$vcKm)e-1;-&^1G*`Iy@`wU(s8tI0=j5Ow;V5P_(d&ibr$S0}qvCnNgW3qgrzY^v z!9MZCOBND4j7E@)aFx16qk=Qn8G#pOAHY^tQdPk)8&?RMjN$NIYoHmu_{Sg)$`PV0Ydtus|zz40P{=d_79{ID$=UjWWVm z7=5tm{pNuf;$Kx+cD!OFD*p0n-UcbcnZwhhl8}V8Cr6M7n0o-Q4K$N(yJU$N6`jy1 zIz(|^blaxUi860BHh^ukJ#pG_hoV=zc8$_>sWygO%I0#AAbOj_d8$exK=H2;#j^6m zVh$V|&>jGx9%naIRO7D0;B_scTXV-E+e^$&gd@7J$)H-zM&e&pGeT@+a;|o#H0><) z&7gG8dKGgWyw~y?%!1f4`kK=2>((plMehwzdTZ@z8(<(&b{h3GFm~GB-V#sJzitf2 zR;4!piRaqipn5Ee-%u7uY|zDhJ#Q$(#(<4RN=yK4W;;4LtF$G8ox1Zj8oSk$4bP9y zY!%~*yuE6Gvgl2 zkQRxm!fmDg7wmLAvBgM5Z0g&nCAMn4jbZT<+3+@Sqf7nUC{LH@cTja*`o3e#izF@~ z2oJ~M^MuF*D^KshAn>liD5FoEWY}=slK-ZJ0Y%hc~NHUTTfviOi2N;h$P#3{Y2$bd)Ltx8-XbKBOUf2f^`=c@*16 zYCtA!!}NI-&Tsy8lFV3K)3)jZh=mCssk&8ur1oW@m=a8gt3Ec;+=A*qMozdks+J}j z8y4n4J~w9Wr`S2RS58vp6jom#unM7Ul|b*ox>S}Vvm39 zEsr6z2xPU0(*t3zBhvHQjux6($pQ_ zB=8=(3|<(~&Yz}Br)r*=IcSV`?ZLTML?%k{YIf=& z1BW&=ne-zzV@2DkKhZcUGUaDkDlF0ccy@F)fe zym@mBCi-YOe9ZXRAs9SKKGq+Po;v(1b_|7NJ__*$U3W!j)^AX1aDL}EqgY7+MzgBy zJk}{g#{RC1maBhP!^*+mfq&*_N$8}9J?=QnXV@~ci@jorJ8+~T_!mm+PW6vjpB;$5ZG#aR}GHWa#Fk&?N~(naA5V zOL_#BQ4ZYzZr-k&?frdqb&XHke!wkpN&_Z@OK2p+JuU_s_K6f2X0HzCHG!f;^K?-> zXJ?oxfUGx6&?fTX)`P)t5pc{KS6-NA|B^=Aa*@NCi0TUGhw}z$RzW2>O*~=$DxPxf zH1SucOC`KolQm9N0gv@h7atnwnZDebmndSH=`o?@XDNFUBsR4YcpfwdWca&fZsN(7 zII|bL!*S*WNa@^`-~#AvTUwcu;bq2~3&9PW;(>5{!VgGt8*>K2mbNiBL&LN2tWPU{ z2OhiOKt#spU-&rttCS_0DW?SSkg7niKGRNXΠ4hXnisTz{Y%N;<2!^FfNZ$jUzm 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 ZhS@cBaB1|#3Tu-!Li^rN@um?h_b-nMKC}P; delta 158943 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 z zl(x?YNCJmfW2(hZ2c@*|6TB zz8u990A~{bPAOkxs9Gh}diU3hcfmvg;M2s~TQteWl@q zaI*W@+Ft5HGQM^&CkuOKdt_^^7jMQ#`oqUx|mG^yki3~^4M@aTY zqo2rRTt7a)G6GNj%)>s}%^Qtc_e)UKaee8+glxQ7@+$1|!dXOKDv7%8wE!xDb_g};-o9l|Ju z`Nsj5%>jxw89PyGr#F=Tb2OT_kSMGE+T)U+i|HnM*Z?P_er>JsMY1 zybG`jrS?4|RrY=0jgqDB0*pdg$8ehgb1!ckE=S%qvcNW--c!P&;61LDNZEVnv?@2Y zAC%_cz8i$?z$zhlyV8hpziKO$Yb&8NK*Ut4E|>Ve>SPn%M-?S9`+XxV>@_q>$FVyj zE`n@8(qcuQ310V|e&2Y+r4|Q!A(-9JqCB*g!7bR4xU@n0D?66M7-LFzp+703GB%m- z0*mgD{9VQ*b+E#bCq$zoHOOUL|7J&VmYqANbxV`t=w=v5ZCxD z{m>``|9xaEY)_@P0}5yh$3Du!$ShPU#=@sA;=}S$OlWK0o{x;$P^gxbpQ5Roe0jSK zY+IQq1)mu|pbgod8(gza++*|$Czv$eOV#uUyw1E)w-y#6Wzilr&Q$JE^7Hr}BU34J zog{rotRGARlId2SVoPaWBmnTxKg6V$mz`9$&*-QXR>vF zxN&eSgX1Gn?l8kdF~0%J;V{uR5Xm?~aT`>h6W?&;YPb}OO*!8hht)MI*!?mTZ!ru$ zs0NR52f1?Vt2~H>QxuVP2;;T7u?_E69WoNHAz{c%goor+EDV}cSyJsn{3UjLOZX)J zn`rYD@ChpfpxyqA?=iS>nS@yr;TY{S4Kv#BjbRsWK1)tA76$=BP@mlM!}&_{75sp9 zL~s?Ee|Tc;m(WyS;~$LKE_$nBa zDGd0k{|9k_auaL84qK#uEymD^GOrf3;Btdnko`Xr^)qN)5}7452^@ zfg@&B>#e~&^AGeRY%%)7NKr-vs<0#&MNy1DX~iEHhSH_x4>dtO`G?v{knyJq9R4TT zfV+9{<$hZYtu4j(Cx$s&pO`)wx^~^4806j&&nXCyiE{iDG2-iV+Gyq`@BR%usa`rv z%>_Ji^nPeblR7pw180483g@%yjOj`cbd>UFJbyj^n#SRa)67Iy$>KZ{ldHwE&D4v@ zdWnFZEdgixnVRhAFh5(`PR!&G-1t4g^enD3yVoE`TiPO8+o z&2W{5nj4zLDEop+BICl$rKkNh5P|1QEzd zRMNt{lW`K$*vvxAyrE_fncvvts9e+7q@A^QxXPN3D;V)rFK@@ApLrt8$?!@dkP>4+ zgt-$Pc6Fpl)0(G=IbGdG#`X~T_0TM9Vy37EiaH}WIUvf#o`FB|1Ua8s**+LG-p&Y( zhRG*C8m8AYkI7SR_MLKh9XGG|xm)SsU6F&Bb7p<^0o~;~vX{sv-CXN_7uz{bW8OO50EW^_n_{+d&@em673Cc=@kC_32; z@KRIrc9e6vDX4%GuFcGpE|oTGa)=Hie4%o4i+6vFx@w$nR(3Rejkh9kLxX6 zA4o}aa}r9cZT^2l2O5&sMVp!MEcM#I2?vJ47_+y#u!(rD#)9{;>+x*P{1`J^4WG?} zhR^U=b0!KXABK^a=gEB=W6gQ)h@Ey5&vw7!E+;PNe#H;{p@H`+e&mFn{eH!$h$<(6 zY>8KwHSUk+?Tn?Zfb~W)u9ewKU7SeGZ~&Y$^iqIP(p3AiTeafm#AGpAn^DNzwzbJ? zwCt;CX16wbf!fBZmSnCM28r zn>H^AQpG>$9!&y|_mQ@3OehC(xQ&UG24A;iBtcuIwN=7I4cP13nw99$)7qK)6j0=O zM{*Gpg)*+aIZ(|{CXN|%!>=ZLWO$!R_Tnep{kz%HvJvc!YrhsC2X*9)r z1g%f+U{V__?_kn^7=E#tpmsxFY8S_@Mu12HtLUtbs#S#-E4jYxV(`xYn|!#Fm*c^b zj^^kj&JKWgMK~hlDmeczgMdV-Fkt*iOEtrl1n-RaWU1~G5rYzjrcF; z3+PwxiSm4>S^_8cwudA4a>}tAHBo4=70yaD<0*w1|JeoNKfgfyp89w$%&R>dX;on! zX?BU(!Mzu=QL|CB48Fu{>;6K0w3a59gnMMgC1xk}up|K`-H8bTIR`%+ULcT87#k5d zUND^#MzKl^vUhw5fCAGwjc$uLmdlRFhVRpG)y?@Zv%kJ&XxOwgGgM0Y{HiU~6Ln-aEUR4f`gra=WG! zgmWxmgT6gaO^iQ?p#jHkllc2Pr0oD7#i&1)e+Xd~1UP1Eoh|zwLHOqcW5rjVWb#QBA1%oxI%lW z{h}mid4%mKvN=QD2H|6$+JA#f>T0Hq`CnkF01QzCy5ai41+tlAOGa=Io3X}YD2skA z{Q5Ow9PT>vEZxt6)t-4c=a-;p_10EqH#2Jx8JN%{!4bMZMn{&QZ>Q}J(-X2^k%)}$ z=V7Vt2Hkm%wC!$=ZgU*5v{SL|r1)?4x6|)`*W`unW?%0KyA*gfnNN0yvcih^$BIrO zt{w$hmtn|Lr!?_M+ht~_c7g36KLxhKVTCzTdzl&2ibBw}}3U6!l;g^}w(-M^++{b_&6c#KcaxDm^BNv~_AGwphh!By%ulJp-&Z=&;Pd zWd%#|_3j+ALagBb*Y-!bn9=^s*4CLH}qTiWou|1|R?I6z1h-g4QS~6HcLK|Uuf;P?4vJ0YZvqoPQZ{&;yTUPA?f|ilrxf&K2*z? z^lCUZW{1q^Z^qr!uv8+(Njd<(+1@+gR2I}qDV+#MDNn{_nnrMp4=PJ)`=eDmeCAb{ zsDaHUT#Zkhzr5Pqh$d$ZK$C1MLBd26FMJI!hX4nga4zD=05h>2aox@?x5i~jCc?$K zoYq2Z$~IHfy=)GOhu1NzR%UwNSPf)mw{< zKt>3D_m{F{BW3Y1GebRRidE2oP_!{K83=jj*q+&+P3a%v97A;o67 zFqWv956%^w#+tAU5bQ;C+m zdRiaIgVu|SxAIKuMw4z_*=wOPovmTAWRU7V6@y3~**l2+LDiM!)Mf2c8h8V&HIXvz z29a#d5p#$FH*u{e*_S)ST*=KO$8SUw zHu4Nr?HU4$g=M%9g}gB+mGt1~7Y!GPL`RM}O$??Jki>F$glvFKMDqr-}*nyI7P6uXA=7W1(5<3b6+9BDa%mZjvhnvljK_{s! z&==iocJ(ibvyU;jM)uweTm#Vd~Y#_ zBTdd&7%E_cvYx-@zNHA~0u~LM#Vm1w3%zA#A*8pxlDD(aT!2jZw}RsfW%sSNF^1h!w7tK4b8Nf7&9#9lffo={;u9j6wC@B$ zL8Ut}^QSSu8Dd<4DdHmPKamn|h2DwkT&3g9Q-*^G{U)VH=9yf$$x#T&PZuG6M%VN+ROC2i!!NFhQkSFoDuTDkh*WEB=a+kh>Jw z7TpD#V*O|oY&K&OX510fKqjdF9baP#;^|iv=Z0Z@i z62R^-RWv9`uyNXNin-CP_9}7E<>1Tk5?|C*^Ars$=6%4LOJ>~%oWw}YeV99qki`3; z2E|Ir{TN7hNVn;b4lSg7x|w^%>0RtqngM$addmzLZ)+supHR062?%jdqnL=6HXt~N z`%e=qd=mQrH2p$f!2>YwpzL+U;90dXcAsmLY$<_JZ-+1IL6A-D8R;qON->Qa`!93J z8TyctWM~VOJ7>BA=|0o!7Z!tBL!_bvG$@{F&H`K$DjFv*oRsB}uCqXJRQM2dOqpd? zIKQVpWRAnSJ;Jdcu|{fVo5_5Iqg6_?mXh|U=}{Mff+C7L9BqyLH_qR}{71nGT=@!8 zH+}OSrG;#b?3!b)QjayTqa@)aKA2-h-_|JHw{$LsJ$Jk=ci)eL{8jVJ@7%5GKRgTP zejg=A9)n%9wH=!IIBf1Cq~vk)c6WjumOCxdb7tidKi`}W#IBnUrDjCw0!Z{tQnSF^ z0dMsa<`H;{o&+U;kSAe-Pn2~F!45loiHppEAq_4jpC-!oTmHV8CNWFQw>Q06*Wy` zT98rb5Tm4Tay|8yL%sm1%gv1uZT+FW%gnJ6?E*hjd{t#;4VN#=pEv6u0m@gPd*fK_ zO7jG~ycfW)X)gdi^t~6%wVXzreo=LiidE+1&a~4}{Ie(C2uES;$X5z&3Oq6hd+81- zSgl$!do}ta9+_KhCWPq#zp4Rh;!^KW&zd^w!ebmw}YI1 z1-!9Fiq@OAwhn_gXH*OO~ zI9IA~(HltP?qqfIg~kUS`Qc4-HYilI83J_#?&pJ$?(EyL1PVqks0GF-e!h}C@FA}O1a`a^Hp~YY!8Lu zEoJf!bAJOtl3z(3QPx$0l4r8~-b!;1Vj*TG0da{RC~<&??2>)OA3#om6PE47y4_jd zY?I?VIeC-pUFbGdQnX8T(4r5`Dj+KBBeVEo&TgH7gDgy9kuL0l>~@aUKSB( z6uykkI5RphchB=jUw-yzl&cEw6%<|YiJ8#Zshc46WBqWfkbi`yH?nXTwZP@EGTHoY zGgIpmRFrB4vmsPvyCN{U^q0mdXIRoQ15;Rd2yAH9nbA~?o7?4IdH(3WXGXJdG6Wmd z@BGpIgQBPGHdC$(M9Ec%cE(AEWfD;;S&QuJ$ezF&uMR5m@NRQ(^BSb(x&XPI2q%WW zl)TR%9|lMfJat-xvlucv!Olh@_-ChF_n8@|&V;j0W?mz^KQmLjlsWuk5K(rKWPR+3 zQD@Gt(dCKe(b1Cmxf!lxQ>K*sjFa)BFURBFlRq~*sl!QBst6SSScqeY;;=$c91z%m z7Wigbrpu81pJR&Z)bI2v%xd>Tiru~klNH}EdseZ5$U843vjl<}=7vi{&%-RbHlT-R729+Iqp?K_&{d*yLu9NgHfXFJz z`@-z1ls!W3k*rmXVr0b^X1?osPqm-k2I$=Z$?Lth?Sw*32|B`caIsGN1a39IphxW{o8T-tXRy+qy z4(kWU#yjkxFfJAQ%pQ&M6kg=Y#OP>c@L?8K$t;AJNj2%T-|VHfa3DmLQ2l*CdG?Ozo&7&UNN*f*Fz zGola)2&~h3hOsX(jDIYELzL4fhq8rI_6^L$XJ{43j?^l<%g$aXN58@3Z5Y}@RvQkV zrQ#jVZ_UlHn1&xTmva;1>hA#B8tHJzoURnrK*mvh8kyKj=m;(y3&g`Ihs<6|HHDu2 zy%vL&hmxPnR2lrenwo$2Jw`~pQSbvMBYNp!OsyOpF}FYN*Qt9GM~4O;HambZrW^+4 z!=&Ocv;Zt^{|Kd=SFj|@fgce+O2U6KM+Q~oV?{2+tUF>(jTqr?TBoC6>=BZG6k5_K zIeye!)rAs;eTU>hI{$dca56E&9r3XSXmm^Zci3IFz9pV@J@Q}Z+M~q$AA0#1Df}Pc zT7&DR%w9KAg$W7BNrJG)l75t3SHh7H6uQJZOGbrC3ubK`9oRqafKyaKWCuw+7KQt! zp1@JjUdPONsIu~yZEd|t(tn25HMrK?#SQj}znH6_E>`{mN~#%?BEFRT4|ji!HbP9< zd>m?1mFzvPY-r|hKnu3){bt_YA`ntS;RwHxQt=yl115#PL8;7FUqOipu9J9_r2lR{ zqQv?|Qr;ZXl0Cme<;Nn%3G|XpGW-N4{7{5Xm|HPDD>wNDE@c2uDP-?%>j4ZtZ1f!$^KpI9r#jP_5{Cv{(No+arw!rZ#_l-jNJ>M8Kg zrq@q%y~55h`7bPyZIZIT%wOHN=&}LUM@f4oB;1ML`L{X4`8~Q0T(+t7G&YO%_}Ufa z+g1njpcC1|+lEaeWNEX6GSir84-U04gZCl~gNN=|*xtKu%R3aR?RHY+3;*a?pNzF1T zURfr?>dQPD=^a?#f17yoVB0$9c`xh|jrDjJ68d$Tw;#M(%{v|FnV@@U;v>QO35Ig_G7`->L3>Rqg(Ywyx8vGQ8xi4yLykJT*xzHof`I?-QnXi2HWS zJ~qy>kNF<)dV7bs?*I}$YT8DAi1O}-#M|E7yVZ3o2TZDV*T4}6Y%BpFlGrt!a4wiQ z;Y0?*$HI~D&SpBsv%F~djOU*UlfyCI1CV}|vEI26ciPN7)R*7F+ax4nJieK#MvCIS zJ-{!k-XVMM%ZZP;TN{dwYjEa}PB;AF?kMxuH;xw>+DMmgx_NI#DOugUD}agbx_if>?Ci_H!n_YI!)v$^ zTz0va_Nt?odk5nIs;pk&A&_4c-R z^^?lp-jUIRPS(|ts_aIoaKy^hCuPGyY~CJS7A52Rc$X#p1NBg1#j{i3k3-;8ggFu( z_r^BZZgVML|Gu+HxHb*R96QMdYIh^$z!l!%+Im#JGeH>JD~ead{c>0DeW5D;+uk=B~bX!LK=TZ?@#^!z~gA`=X-9 zf(k^QuIl>j$Af~G^!KJ{^Miu?DHj9<10tXH1cK^WNx^aCDsQazB*Mwo7NN|mQRu>; z+(6DitNn|D!cjyIHT*j`T^tx)I>7sDP;6;nta!4${YD9b0%gpS2H#IL_FQaJXv zbwP#JUXNa|^?Gkx?d68yY1%76l_?uf<7dNTwe@F)7w3A@z2yiGY$om|%k?G%q4(cN zLa3l(+bunv>rD+}&y7K)XXRlidR0pDyb0dd8kGOKl;@#C`s_06Np?KXJ0NM3oto-4 zk^V-5+;2+$AaAZDTnG8Eb&$7%_djQpb8=7v*xo{tdh{1e3`r)>&DOS_5$=l_?498% zu0VtzE}QGy0~l&{1nTVz#J_Wa_-*HpFTQB|`4e39?girCyFmPo^TxwOUwPgHxUB2~ z@gH0ue&_k(xkRw*dYM{!+zcyU(3K z#eWtUFJ(iZBckhCUXAifZ&YE4mX~FD1(sK0d1aPYVR<#mD;;WOv%D~){eY=#%7Gfh;h^Z6o4h@4`Y|xb?sksu1dJ;|_|tjPP%u0C z)e)qt2d-#@H@W*!1O*DZ|Jq5Ig}t3}_J0V&KTFCH1gTx#*iyZY*~x8D&#MG$gMz5U zwcsvjiU}6>b6{bTH`1G|{SuUeIBP|eTL*|~lVN>ZDT@#8px{PIXjhAaA%Szd+Z z)hMs@CMzl*n%tj3<*2IVxn-CU(Q)e!vEg_5H{A#($5q#y)G# zwdR^@uDRxVuT6R5J*h%0RgL##2p#zqsaln*6L@T{Tn*zriC4t^NiNx3`s{d0n}8_s zc2IzlPq5>SD2aAZfGC~qcq2*|J19Vuu6Dc;CCLs75T%~sx1&DH`9dAU*u!90b>1D?oQLeIs0z|pm zj;FdJPw(-)0b&Ery=&H~Ow-S;4Ey_-erwcwjp?_hJo}n{q^5Ue*+%yRthtrSoCN#X zpGHmcWL$SGF!s?^Rx7{1m484h|8)^H=~*49a&NHvifrKi%*YM2BjPQ{FHJ4ezGF(M`CPECOvhFfI@H*M!bd5p?Zl?!O!DLUQYjjKR zm?m%CWZe8bwgtJv`PiXzaWY2s`GBMKGDkd}@9?B1+y;vzi zLJEN7!h1m^VJ1G)uzsdT(bi7!^b^GK5j6cYzLjvX)U(So0pVCV*t#;)W3jmv!!O^seHO8Q3vy&wHdqy;66;7rP>7M z@fIE)+mC=_P2qJ-i-)FgwMa{k&7=P&Xsg()7glT@>^FteS=F!A=QX@0Fh{4fUbyDE zW`>6khnLUt#Ayd+czOu|vg@AZ!RN7&ftK0rHwz8bJ`GWa3oc$g;-@S54~522s#kP& z;T6DSz*x(zq#4#1e$F?`K7^twJS##9Az)U%i4pY9zp)GMNQK8Q6p=F9vp#$haF#+2 zpo6nL#W3x9 zYkJ4AHEi|Wo^yhF2Y}1~3qA^t{}0eMRC>N?D^3B)pT!Q^<_A3&fv8PbPTUp}y zMi5GCAM@}fhNB+CLcm&T%#!134y}x(qmOw8!XNuMM%7b69Y6i!ZOid4h2uPwz;Q}z zsd^cv6jnU$Ii_F1&jbAgD)-UDUFNxkbGZzw z4|s=>=ZuJjiwjS91_@=_z$ZQXLar)D%9gwbuO-7b?u#D3 z!&89}Jkh~+N-qK2&gGfnnGG<02FPHehnPrNFL`c>o&y92ZBcM~n6zyU9HQUk=}h0e zR3QQzsgkUkVb@}FVIDSv{$mjwCUu?M(YSXY} zxnwp@#?IX9QN;NX^z<;;z*T!uzmL(jy`H|}112o=4NsK#U~>Q`l|3Vct<8PI;}91_ z=%3jT7wT`X{>2bZJeYjAYmvsKho{l;{V=H&6!jLC0V}kDZ+W&0!m+Ifu#_e2*ZLjw z9C6^XV)tRsdIYL|-!oKe_l~DQfak(7Pa=gL@ocmGpB2L5<3{db)LFidv+_Nz0D9CV z;v$0&t@j6P#upph@jbmqJx9bxje1Iz$1sUhp@IA$QCwmI#~t^S7*w*g(2qS~qF5b4 zn?_@gL)ND-E{|zdpL*ts;^P2ThIh~+Pk43+VvQO3%;%o-5ZkFQu;R0nd?!7XAXRq~ zi%g9u7sMm(j7>FFjL)W3>lR;AO(3n`x1Re2*K)J? z8>oJ*gpX@{2h$VsgatH~+bH!!xJ08HJ+F7<5`_KMxngl!iq3F+7bo8pqYeKamgY*{ zwbRRFy8z@^>p6#oCXDf1R-8Rn|0kie_}CV{^|AK{&p3TCEd9O++^KrbQ;IUwHvH(B z>wxIG{erdP3N7y!v=zZDBasSjlOwgAzha?Nzub_&b$|JY zG)jc9QydbG3ml`mAZa+-nR7uB!M8YAN*13%$WhKtRJj|wIX(-P_PbVFa;5sVQVe1r zY%AegzGG*z$;C`%iTj>5zhSs zo{M3lR8iYjj_j}r)cx>rZQ(aRtTQh~(6AuIt8I^z((oN{_|BsFj)<1R0!XGXTDpLV z?Sc-{0Kintz zOn+SuF;ZLNlQxLDMB`{|qBIM+JDe!(5nY-|2Oo6n3azN1UP*YFx43?hB$eU<$GmP* zZ-;AJQ^@LMsaX711Wo;3Mn`0@;-*8pam~ZnOqArH6lsTxRi4}UL~6)~3cW(zu7KiI z(7Y?8WMR9u?h43L++o&zN2=s=z1l=PB~=uViV9{u z-&K2+bXMH0$L@gJt=v~ji^M&KHKirJrC7@9Eh+TX)sj!#+X~!Ee8V)m2pA^1-bAuo zNc(6_AE~!%zv+F8PO|skruP7Kz6RcdruRSE#A~GEqVTrn?=OAkh-S0m1rfF!c2lEb zJ9OI^eJ|x9v$eZ_fRrL0)(vwHIzB)u5#KR9TG@3{nnQS(>i#Cp6^>}J*Gn~`@E$h9 zBc=BvYIfh~)m9IY`U%1Z)Nq58Bpx+YKW->ASpRTQF!?7qhtgL$(A~9kAx9dD*Weqa z8nn-nRlRSw}px{xpR7CzE? z-6ll}B5wH`a5ZLi3U8OzxIVUsXdvL7FXohEdG?kgi%*p@dBx4OT>f-gz0vcCw13!63S$L@K5;MUqcALGDSg zG{>}Ulc1R)pIC3U%0bhm`F)X;ESmp&uvi zPmAx6hPu8q5!gy~hjd){FYTBjt#^IZ1T8O>VqB-1yh}?F=zml`73TMAT0Rx3{tf$Z zHPAF^l>W^&Zdlk(v-EjyC;P4S&3&|Rnv|?>#fqi6-8f%#XqwbnJRL!gl}R1MZ=tYd zQV;PvtL>p%%A~&H857-TqQ7rKH4fK#zenW{A`7k3BvCCp=#N)q4z)Q7XKR8c`FrGl??i7HmbML>8gsv?v%K_pEebTMs#R&TFKIv+M^Q;i=8*!002sL1e%I=qN z4WXMnFRB=u-!Hi(&bEjERvRw5^`Y3>zVp$bIjG-4Fnx?t9+G0jAh*$Bp81e;3t;;n zLYrDazK2mkD{3FMd9=)jCE0->IgfC&tCc>uN{y6% znXB6T<8U}7_g(BEidc$10u0YmR2#5UzYKY8XNZBmS|)Y&u#BuR2mhBy|9s|wo16*_ zt(BDU76GWVR{Bcsw(S}E1#X;zoDhLu^zNNwRd?l_?b z`Mfk+a7k7uEoZ$nm;0srUyv>afyn-sq%2)Eom3YY9-}2~MmNYMTj8m3Ix1cE%P0!; zH3q!o=s+7^MpaVXHM@smSLkAV?InAwwBH41wxrU0Bk1)pMg66NL*RL`1mi}A(i18uRL_+Qdq8uSp1=e}2@d_6c1=etr> zB=)jqZ-;sqqbb zSD`hE^K=leM(cu+El!};On(X!%%4lKV5Hy%ocG!JIh0A43BKhaB+_r6qyG1%2*vkDDW8Hpkqha6kt@IuiT9$t&4INX6nlc^k5xAG&B49^H!&SgN0kNZX4VY6w0}F^z_~BJJ858Fu(n2-WfEr*HYaXDK$O| zY_%>s))>D9r^YiV=>Z%%a&$H@Y>ck6u(lHCSlO3>54;TgZx)>1Yn0Bqt~b5dzyCc1 zS)n<9kV1t!28uX*_Wz4xFNqSlkZ#Mf?o6qy)3hh5H#a%TVQTzzSIqe2#m6Sz^ zIp>_Q`SIf26;7tuU!?7@PRD-1e2hW^f0eR%%~(%bFMj;zNa>)$#mM4df?eQvRf0ux z3+&!uPX{{ktCSYasq$k5Vm~ix1ySs8n1~rcYkot+m`?BgCao23buWvT(U%t;xC7z> zcL*zJ%kP-isGx@5rATq4n}&%95b=lPhDrDRfx+P@y6}fo;~I?wm@#}w_#)cCBAVlq zla{TQbA+Oo&&xl9lGZ57FnO7@I7r^<;qv6C1WuO%vg4xSBCQynj_jMIoiE8DtJVoSNGW4+HBD@Oaj&`=y!oBj9qHCfRjs{1`sIS_bD5xX) z*ejz^HHv6Qw7eS7f(|kUCF!ndZqN$}~cCenf=IX{@qUK?^hjB9i*CdmtdTi8t=i`U6+oN=oAOire(6F9*+w!7@R zu?)d2Gs{B+Ha2W#(JRs|W%*y=r`z#V$6Etu0A!8WH&J7ENZ&SX&MgBMxo%Q$80c^h zIZ>Qtm@F+cS+3*TA~vLeR~$P_k@>5U1y`Vq_R;(+nw@h8ey}%=hnn5??!vD+yQV zXckQ7S`Dk*eZ}uQ?qI)ZkyZ?gcYD0p{Rinp*P9LI?hGLIZ>`bKf&D!$9)`b zxaZa8qUE`pV)5#8Pk?~jl5xPw0Jta)4W=2)a?p<=1z{&X6MTj9XN{m@i-Y%w@c{Ycu2B8ogOb|iA#;~DvtCF zoB%b%m-QyVQY;~Vq1@ZG%p{jdRfY0dkef9THnNs>O_cizL>DF^U(2<;A{moV)97Ha z{0&ZOhrQs6so9v~6rV6AA3Jge*{1Vs1~*g8=#v(snlc%R?pk3_37_D*L*C|EX@@1! zlqqtQ>#3HojZ@@)VD|JBIY}2<5c#gb1X60Ld;#31Ooi>MzzTxir&>5w<~#H1Hit&i zfvISUaD~A%v{nDG%4h#Hc@?G|O3GwRN*W~r+Bwq^#w>t{d&8aDf$4H*mLiH|k$$NW z8+a>UtF*;4<)dvO&WV4QM~Zdsn(?=IY2UZOy{O$>Ia7FA^UsyH^FhuFcgwlrGiaCo z2=i)%_sG?PxEhmNH-~t&&?+drxCTAzzlCtdD-h|OYdA_*8@YJlj9p9wG zRtg&Vkn9s*u!1}!_ksZQ_U+70kMl-01201IY)jaFaDRt8v|N%K0p|`bm$KFDb;f@- zf~=h!w;o}vs*0<|dE4Y~H(+|L>|uE#dPMI%EU$2FYFV-?7Re35OEhn>ob1}%gsNYR zeuB~7VR82nIZ@w0#!1DK?@3%TGIoM!d~}Cddzp4Tg6LbDqBlMwPZ2cAe^kcsoqPCv zlKxTXANH6$D)%)eXKELsUsC*tte86q8vcpC+kz$XMAs`#giswKDYP2Jghlyky;;O7 ziQ-1d&Tv1H=7(9>PIc8_VTV0tBK=&A&KV}QACt4p38C^RTu{%kap{2^>w2|i_(6}$ zIj-02uo%)FmsjfFU*T4U)z1=e6_wP;vq8S02K^dzc9x=+?j-jz`G9MeNdw1=m&t`d z4z5K9uRqPHl~?I|P`JdHm{p>vM1(%iZd!!Ly-Eui4nCH_Js{X|t)7`4! zR%{+yb6ear=m9w%nGT}Hchtx$xGm%;Jn6(>4#vSPGHhL$3EfY-mdlX?*na2~0A@7z z(Cs9Kz|TE(J4tStEs|}iaWWf*CuH6&(C-N}T3Bv)0>*j_ZQ~dAB|Rx8hwlMPR&QSa z5@4LZ?gC0WN1QP|S(^W(To}#sfewI}8!qj=mUwGd$d&PLSUwgD9?M3&X~C&(g*?u+ zugU9NDX+);+?JK{Q1LCJ)6@Om7Pb|U1AucUnR_M7k-==beUg(oI(V7r|FPh-^eNc# zD(&!7Z1pN=`6@Xv{%s4}D$zq0oIYL!rP7-h)FdjYLpyhv*43eUy`w2lvxUR*&1yMA zS1Rrg_~H0rrrxEfHL~V9Vp7YbV{5oeS^F$h4AY!Xi(y_G_cZE4R>vTx-hY43O^-d` zz_zq!uA9a<+l zgTK*}b~C@HjToW-gz5g)oc&q*Pc$c}=VJW+GVmWR13!Bi_&E!%?Rr68AgDjW z?+1OZ@7xz>Rx#|@2&q?4<3#A4PyUPE{S+o8%{LXTn^ZFos8bp2{EMp2vP4DmP2 z0&bRX5HGmtiOurcXt>Y}#L)d)jL{3a zC9k3l$=)hwMqdPq#|vyqSm`*|oM|(Gja%h%m(UWHt;v}#u_bJkCO3lh>TMY6J6fQ$ zGuz}+Avy>^dpg1PK)7P}6*<-zizjxphAM1Nto}`tYLWZ;wh(d*_7#V2m(K}BwL8#? zETOa=awRU4uHOM`kV%a@&|k?U_p7>fMQ*c$b%n!Ry(3aP^s0<~lkGhE7FTWkPWhMv z6z17>xzfol%vwE zw&HJy!1ef6xHLEs&dNiJJW

IWb&s&k!ULE{yVc#%AZq_D&CXczAHi>geY;joK%V z4CV={P%1duHf8`<1{b*1vG{Mb63hr!MK=7M;5bo>0iG6RqvMCeB*XKV@LYM3;wNG6 zZOnf3E5=aDemPF%MESAGgGq+fRNsW0zac9ww*FVb;R2L57h`WS94A(f`#ZT| zMI=LfwC)Y`nL^BRA4BiK+b0d7pn)x#U{=K>IPS9xaM^Iox@9u>KMMR!SoqM^i6Aux zrQM3&Sj5}7z^SYOtIBbH3|$WW4~+v`;eRv-ZD3hhfw6HXJ9%mIu$2v9?~vK8*~_Rc3{2!q?}4+ z9|M>BgWQd_zayUq=`HWdslofX6F~kK(Y?6%uIvZce*_7;w1Ok@W>NqCE=w|usxIK; z;=MnR*L38r8Y>0AS+cA^?X67G`48lcu81ZP)E|`xiEfWRSsrmr_H|-i;8+}+)rwV& zOPuxl)8A>BEPF+dhaQuZ4ixtrF7F!mVYqW`#D_BPvvz+ZLxlSY?@C%Q6#M(mENdI4 z?fFD57xY^VSTVWh#67A)IPRL@2OQID7_9GH&IY(BTWYFt#bcMXs@VPt}Wtabj zZc65Tp?BMs!zX59fwBmn6g>0=+Qf?XkDcg1WhWthy{OLW5U<{WUqZXSMC|?4@TDI6 z0$%!9QKY&Y=;(rT(8sZ-+v94B|MD!qR`Op62#J<{#SKpFDY@7c*~C}*DS0DszW;$F zn#cdi*&?rOJiu%w@5yd z&V7qf>ln)UPQHkaOU@Zoh%s1Ml^3|8&Ac>FSR*RN80yuCUfUS0t`UQV)|$>ejDqQfR5ogB#hUO@>;x({ix3#9Q;ZCO6_1P zb1UB!+WwzWa}hG{7fg=FG>LoVFKAIP#QGKDK!5#Lo#Coq<;@bSqCV~eGpstX9^1Nm z2UmI%k5#|1L}|-!nAR9WoiE6#Vn>{|$PDj<&wyd8_L9yaQ8nY9a*CZiyk!huWM7P3 zmKWrHEvB!e1SaahOBN zWo7<;p5mpULCQI(kUv;S6?|HGu!5x_d|a@tGE|7yj?cx5ZfiR}iEMox(G710S8 z(xIWsJPh;qhbmKo6Ct~9v}*$H&KMh}>%rT*a+r4L&+(nIY!b zI*^rs|F^=ijJZ$J1v2{-OSL1z6~1n4OSr-x5pcKHU#0DpRI#gvp6-pi+m?I@qcZjr zRH!5Em6hPXJVIG<$<~S_@Ztwuwi}%8pKPt@29v>CE4sHRV!C)cc0C+$D?R};Ij21e zYk!yo$@QRqlCnr2SmWzDXoqT2i=ENj4sxbBgIpw*?v0@!S*a0|jh+Z;veHdRp$1t= z?ZgI^pHEL;yqNxN%Zs$;d`nN?(XPX-ozVJmBgqDspRciWZujprm)9B3d98(?$8Fps zTd-?>HN?YV$fBR1|DI-=xM;omq;9D}kE~XTfD=tGm~vVo^PR&PavJ97J@=EQ`a` z;8kMcpE1!^@LKr8%wU|*y%ZaXLv(Q;g*Yp(FyTDuaPQemw@P?Sm_@4%{PukR?*}6e z%cr|Zi!-?&@KC%N-opmJ18`gXgffZV_1gqXmWfU^_?YK&AeJbTPw-1c(N ztEpF%GS z_&p9UZSNKurfp1Ce8Iw(+Tk>1xTE8jENMJf!m$Fem%G}`%9rHt1)Hb8619!Jltw{F z)#|PW4C_5O;nxEP;I4N~Go(s4V9t ztd)ZlzLm1yV6gfntr@HoVk*@+M8Vd6S~&#f_Dk9}1esn-<%PjT$cgYy0o)@pRhU`9hHD=GM&IT_7{KqZrvvP$k; zCBZQvuCQD=k%r!UTU8|&7Ktlq0vr=%CKSA_a$`m|!LgoLqF{s1GfdyYF`oTww>isf z)tF9OM;m(S`L@x~EN4bs5`Y%3#?X638fI!fD-3dmGe>MYnd<~fdmY<~&pZ?n)`wx- zbGJCOxPUZTaM2HbeprOeRR;OKz`bgz&$b;*Ssjqd`mb=jr=N#68YZ|nHI~IdI=lsk z`4_1!x7rPU7A`*)m2|2<8yrpD*R;LPMy3Ddspz+OI>~>=gR`QI=!I^4MRihTF@|Bo zOO+ga6cZIFOYtJtB}$l4dRclUXEDZ8RTpe2OPvb)!WF+gHT;45|5**POf~T1ZAtkf zS~yjStK{23SxoV8{N@6%!z`^~EgFF6j30nF+>rR-xNJDX3?Iu^-a74l%H7Cc*-(NP@=02AU_A=UzBJ_iddN~C(D4F#x< zy2(K020-N*s9^z6Hyfzo0Z_LXs1X5Bw;HIC0Z^k1)aU>xoMU6=#|A*<8>rg?ps;C; zV~q=dDlkyv1E3}tsKNlKi3X}D0BVwfDh_}uF;J5OpzbhGQv#q$4b;>CD15Mw^HmlA zRc@fB2SCj*P%{IdW*MkE1E4Al)a(GLIR@&k0I0tksJS+jrHAtj)ZI3erHA(zsLB8+ ze8-Hld~X2MeU$bDP@kZ(S!vvlV0z7`{3p<7n%^9PZ6nu)2U>=B&>+7c0QrRm>Y)Ir zhYi%C0I0X87bM-9}H0H|sM^_UH1W$AGPRTBWU)Icq>p)85k8Yl{YT5h182!MLh zK&=RXT4|u33V`~Dfm#&+RcD}{4uE>bK&=jdT4SJ|4S;&iK&`c*EJ3X^P|w>?mNc-@ zfR$){0MrHp^@0s$5q!}=Z47{_H&B~wC@Za(4AkZTs4WKSfZ+HKmgQ11NEN(sJ9K&p#Z4E2I`#vsCNz2kpQUo4AlDpP#+kmqXAII4Ah4KP#+nn z;{i|~8>mkLpguKFp9MfQ7^o9Al%*S=8>lY=piUa7F9V?dYoNZep{yzJQwHjPHk6gt z*9PjF0I1Uj>e~RQ?+nx#8_H7AMg#SI0Mri#>TCeiIRo{h4P|lolY#m<0P4Jf`o)H_ z*!a~z{boa11TPq<-vglj&{5utHk3sWCtE$s6t7o6XVL1XSvb+eIRfBtn};4RH~_A# ziEC%WSzJ0zoGSn>#KeULz=fGO{vd8^KHHnPhyXaZiQ~`tw2mj4I5_}LF>tCH0O!?w z&nd^lX`DOA7k>w©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 delta 34607 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 diff --git a/boot/ocamllex b/boot/ocamllex index 02854fa1891ba87b8558d95ab13d7ca91b9756a9..80acc9ea3a4617fb57efe27eabce0f5292b669fc 100755 GIT binary patch delta 17879 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 - Format.eprintf "%a@." Ident.print id; fatal_error ("Bytegen.comp_expr: var " ^ Ident.unique_name id) end | Lconst cst -> diff --git a/bytecomp/bytepackager.ml b/bytecomp/bytepackager.ml index 3348f46d..05ebac9a 100644 --- a/bytecomp/bytepackager.ml +++ b/bytecomp/bytepackager.ml @@ -222,9 +222,10 @@ let package_object_files ppf files targetfile targetname coercion = targetname Subst.identity members in build_global_target oc targetname members mapping ofs coercion; let pos_debug = pos_out oc in - if !Clflags.debug && !events <> [] then + if !Clflags.debug && !events <> [] then begin output_value oc (List.rev !events); output_value oc (StringSet.elements !debug_dirs); + end; let pos_final = pos_out oc in let imports = List.filter diff --git a/bytecomp/emitcode.ml b/bytecomp/emitcode.ml index 77df4611..e9a97765 100644 --- a/bytecomp/emitcode.ml +++ b/bytecomp/emitcode.ml @@ -143,6 +143,7 @@ let record_event ev = let path = ev.ev_loc.Location.loc_start.Lexing.pos_fname in let abspath = Location.absolute_path path in debug_dirs := StringSet.add (Filename.dirname abspath) !debug_dirs; + if Filename.is_relative path then debug_dirs := StringSet.add (Sys.getcwd ()) !debug_dirs; ev.ev_pos <- !out_position; events := ev :: !events diff --git a/bytecomp/lambda.ml b/bytecomp/lambda.ml index 4ad8e9b4..5d9fb593 100644 --- a/bytecomp/lambda.ml +++ b/bytecomp/lambda.ml @@ -537,9 +537,12 @@ let lam_of_loc kind loc = Const_base (Const_int enum); ])) | Loc_FILE -> Lconst (Const_immstring file) - | Loc_MODULE -> Lconst (Const_immstring - (String.capitalize - (Filename.chop_extension (Filename.basename file)))) + | Loc_MODULE -> + let filename = Filename.basename file in + let module_name = + try String.capitalize (Filename.chop_extension filename) + with Invalid_argument _ -> "//"^filename^"//" + in Lconst (Const_immstring module_name) | Loc_LOC -> let loc = Printf.sprintf "File %S, line %d, characters %d-%d" file lnum cnum enum in diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml index 876abaa9..ef7d82cd 100644 --- a/bytecomp/translcore.ml +++ b/bytecomp/translcore.ml @@ -669,7 +669,7 @@ and transl_exp0 e = transl_function e.exp_loc !Clflags.native_code repr partial pl) in Lfunction(kind, params, body) - | Texp_apply({exp_desc = Texp_ident(path, _, {val_kind = Val_prim p})} as fn, + | Texp_apply({exp_desc = Texp_ident(path, _, {val_kind = Val_prim p})}, oargs) when List.length oargs >= p.prim_arity && List.for_all (fun (_, arg,_) -> arg <> None) oargs -> @@ -695,12 +695,6 @@ and transl_exp0 e = wrap (Lsend(Cached, meth, obj, [cache; pos], e.exp_loc)) | _ -> assert false else begin - if p.prim_name = "%sequand" && Path.last path = "&" then - Location.prerr_warning fn.exp_loc - (Warnings.Deprecated "operator (&); you should use (&&) instead"); - if p.prim_name = "%sequor" && Path.last path = "or" then - Location.prerr_warning fn.exp_loc - (Warnings.Deprecated "operator (or); you should use (||) instead"); let prim = transl_prim e.exp_loc p args in match (prim, args) with (Praise k, [arg1]) -> diff --git a/bytecomp/translmod.ml b/bytecomp/translmod.ml index dc7d2d7a..a2944f3d 100644 --- a/bytecomp/translmod.ml +++ b/bytecomp/translmod.ml @@ -83,21 +83,12 @@ let rec apply_coercion strict restr arg = arg | Tcoerce_structure(pos_cc_list, id_pos_list) -> name_lambda strict arg (fun id -> + let get_field pos = Lprim(Pfield pos,[Lvar id]) in let lam = Lprim(Pmakeblock(0, Immutable), - List.map (apply_coercion_field id) pos_cc_list) in - let fv = free_variables lam in - let (lam,s) = - List.fold_left (fun (lam,s) (id',pos,c) -> - if IdentSet.mem id' fv then - let id'' = Ident.create (Ident.name id') in - (Llet(Alias,id'', - apply_coercion Alias c (Lprim(Pfield pos,[Lvar id])),lam), - Ident.add id' (Lvar id'') s) - else (lam,s)) - (lam, Ident.empty) id_pos_list + List.map (apply_coercion_field get_field) pos_cc_list) in - if s == Ident.empty then lam else subst_lambda s lam) + wrap_id_pos_list id_pos_list get_field lam) | Tcoerce_functor(cc_arg, cc_res) -> let param = Ident.create "funarg" in name_lambda strict arg (fun id -> @@ -111,8 +102,26 @@ let rec apply_coercion strict restr arg = name_lambda strict arg (fun id -> apply_coercion Alias cc (transl_normal_path path)) -and apply_coercion_field id (pos, cc) = - apply_coercion Alias cc (Lprim(Pfield pos, [Lvar id])) +and apply_coercion_field get_field (pos, cc) = + apply_coercion Alias cc (get_field pos) + +and wrap_id_pos_list id_pos_list get_field lam = + let fv = free_variables lam in + (*Format.eprintf "%a@." Printlambda.lambda lam; + IdentSet.iter (fun id -> Format.eprintf "%a " Ident.print id) fv; + Format.eprintf "@.";*) + let (lam,s) = + List.fold_left (fun (lam,s) (id',pos,c) -> + if IdentSet.mem id' fv then + let id'' = Ident.create (Ident.name id') in + (Llet(Alias,id'', + apply_coercion Alias c (get_field pos),lam), + Ident.add id' (Lvar id'') s) + else (lam,s)) + (lam, Ident.empty) id_pos_list + in + if s == Ident.empty then lam else subst_lambda s lam + (* Compose two coercions apply_coercion c1 (apply_coercion c2 e) behaves like @@ -154,7 +163,7 @@ let compose_coercions c1 c2 = let c3 = compose_coercions c1 c2 in let open Includemod in Format.eprintf "@[<2>compose_coercions@ (%a)@ (%a) =@ %a@]@." - print_coercion c1 print_coercion c2 print_coercion c2; + print_coercion c1 print_coercion c2 print_coercion c3; c3 *) @@ -322,7 +331,7 @@ let rec transl_module cc rootpath mexp = | _ -> match mexp.mod_desc with Tmod_ident (path,_) -> - apply_coercion StrictOpt cc + apply_coercion Strict cc (transl_path ~loc:mexp.mod_loc mexp.mod_env path) | Tmod_structure str -> transl_struct [] cc rootpath str @@ -362,18 +371,26 @@ and transl_structure fields cc rootpath = function Lprim(Pmakeblock(0, Immutable), List.map (fun id -> Lvar id) (List.rev fields)) | Tcoerce_structure(pos_cc_list, id_pos_list) -> - (* ignore id_pos_list as the ids are already bound *) + (* Do not ignore id_pos_list ! *) + (*Format.eprintf "%a@.@[" Includemod.print_coercion cc; + List.iter (fun l -> Format.eprintf "%a@ " Ident.print l) + fields; + Format.eprintf "@]@.";*) let v = Array.of_list (List.rev fields) in - (*List.fold_left - (fun lam (id, pos) -> Llet(Alias, id, Lvar v.(pos), lam))*) + let get_field pos = Lvar v.(pos) + and ids = List.fold_right IdentSet.add fields IdentSet.empty in + let lam = (Lprim(Pmakeblock(0, Immutable), List.map (fun (pos, cc) -> match cc with Tcoerce_primitive p -> transl_primitive Location.none p - | _ -> apply_coercion Strict cc (Lvar v.(pos))) + | _ -> apply_coercion Strict cc (get_field pos)) pos_cc_list)) - (*id_pos_list*) + and id_pos_list = + List.filter (fun (id,_,_) -> not (IdentSet.mem id ids)) id_pos_list + in + wrap_id_pos_list id_pos_list get_field lam | _ -> fatal_error "Translmod.transl_structure" end diff --git a/byterun/gc_ctrl.c b/byterun/gc_ctrl.c index 7e61f0c1..1ab099da 100644 --- a/byterun/gc_ctrl.c +++ b/byterun/gc_ctrl.c @@ -321,7 +321,7 @@ CAMLprim value caml_gc_get(value v) res = caml_alloc_tuple (7); Store_field (res, 0, Val_long (Wsize_bsize (caml_minor_heap_size))); /* s */ - Store_field (res, 1,Val_long(Wsize_bsize(caml_major_heap_increment)));/* i */ + Store_field (res, 1, Val_long (caml_major_heap_increment)); /* i */ Store_field (res, 2, Val_long (caml_percent_free)); /* o */ Store_field (res, 3, Val_long (caml_verb_gc)); /* v */ Store_field (res, 4, Val_long (caml_percent_max)); /* O */ diff --git a/config/Makefile.mingw b/config/Makefile.mingw index d9e7607f..c2049803 100644 --- a/config/Makefile.mingw +++ b/config/Makefile.mingw @@ -110,7 +110,7 @@ CPP=$(BYTECC) -E ### Flexlink FLEXLINK=flexlink -chain mingw -stack 16777216 -link -static-libgcc -FLEXDIR=$(shell $(FLEXLINK) -where) +FLEXDIR:=$(shell $(FLEXLINK) -where) IFLEXDIR=-I"$(FLEXDIR)" MKDLL=$(FLEXLINK) MKEXE=$(FLEXLINK) -exe diff --git a/config/Makefile.mingw64 b/config/Makefile.mingw64 index 44784b68..0a3bdfbd 100644 --- a/config/Makefile.mingw64 +++ b/config/Makefile.mingw64 @@ -110,7 +110,7 @@ CPP=$(BYTECC) -E ### Flexlink FLEXLINK=flexlink -chain mingw64 -stack 33554432 -FLEXDIR=$(shell $(FLEXLINK) -where) +FLEXDIR:=$(shell $(FLEXLINK) -where) IFLEXDIR=-I"$(FLEXDIR)" MKDLL=$(FLEXLINK) MKEXE=$(FLEXLINK) -exe diff --git a/config/Makefile.msvc b/config/Makefile.msvc index 3ab6c6eb..93cf94b6 100644 --- a/config/Makefile.msvc +++ b/config/Makefile.msvc @@ -63,7 +63,7 @@ SUPPORTS_SHARED_LIBRARIES=true SHAREDCCCOMPOPTS= NATIVECCPROFOPTS= NATIVECCRPATH= -ASM=ml /nologo /coff /Cp /c /Fo +ASM=ml -nologo -coff -Cp -c -Fo ASPP= ASPPPROFFLAGS= PROFILING=noprof @@ -81,35 +81,35 @@ GRAPHLIB=win32graph ########## Configuration for the bytecode compiler ### Which C compiler to use for the bytecode interpreter. -BYTECC=cl /nologo -D_CRT_SECURE_NO_DEPRECATE +BYTECC=cl -nologo -D_CRT_SECURE_NO_DEPRECATE ### Additional compile-time options for $(BYTECC). (For static linking.) -BYTECCCOMPOPTS=/Ox /MD +BYTECCCOMPOPTS=-Ox -MD ### Additional link-time options for $(BYTECC). (For static linking.) BYTECCLINKOPTS= ### Additional compile-time options for $(BYTECC). (For building a DLL.) -DLLCCCOMPOPTS=/Ox /MD +DLLCCCOMPOPTS=-Ox -MD ### Libraries needed BYTECCLIBS=advapi32.lib ws2_32.lib NATIVECCLIBS=advapi32.lib ws2_32.lib ### How to invoke the C preprocessor -CPP=cl /nologo /EP +CPP=cl -nologo -EP ### Flexlink FLEXLINK=flexlink -merge-manifest -stack 16777216 -FLEXDIR=$(shell $(FLEXLINK) -where) +FLEXDIR:=$(shell $(FLEXLINK) -where) IFLEXDIR=-I"$(FLEXDIR)" MKDLL=$(FLEXLINK) MKEXE=$(FLEXLINK) -exe MKMAINDLL=$(FLEXLINK) -maindll ### How to build a static library -MKLIB=link /lib /nologo /out:$(1) $(2) -#ml let mklib out files opts = Printf.sprintf "link /lib /nologo /out:%s %s %s" out opts files;; +MKLIB=link -lib -nologo -out:$(1) $(2) +#ml let mklib out files opts = Printf.sprintf "link -lib -nologo -out:%s %s %s" out opts files;; MKSHAREDLIBRPATH= ### Canonicalize the name of a system library @@ -135,16 +135,16 @@ MODEL=default SYSTEM=win32 ### Which C compiler to use for the native-code compiler. -NATIVECC=cl /nologo -D_CRT_SECURE_NO_DEPRECATE +NATIVECC=cl -nologo -D_CRT_SECURE_NO_DEPRECATE ### Additional compile-time options for $(NATIVECC). -NATIVECCCOMPOPTS=/Ox /MD +NATIVECCCOMPOPTS=-Ox -MD ### Additional link-time options for $(NATIVECC) NATIVECCLINKOPTS= ### Build partially-linked object file -PACKLD=link /lib /nologo /out:# there must be no space after this '/out:' +PACKLD=link -lib -nologo -out:# there must be no space after this '-out:' ### Clear this to disable compiling ocamldebug WITH_DEBUGGER=ocamldebugger diff --git a/config/Makefile.msvc64 b/config/Makefile.msvc64 index 8437cf4b..1b2e1888 100644 --- a/config/Makefile.msvc64 +++ b/config/Makefile.msvc64 @@ -63,7 +63,7 @@ SUPPORTS_SHARED_LIBRARIES=true SHAREDCCCOMPOPTS= NATIVECCPROFOPTS= NATIVECCRPATH= -ASM=ml64 /nologo /Cp /c /Fo +ASM=ml64 -nologo -Cp -c -Fo ASPP= ASPPPROFFLAGS= PROFILING=noprof @@ -80,19 +80,19 @@ GRAPHLIB=win32graph ########## Configuration for the bytecode compiler ### Which C compiler to use for the bytecode interpreter. -BYTECC=cl /nologo -D_CRT_SECURE_NO_DEPRECATE +BYTECC=cl -nologo -D_CRT_SECURE_NO_DEPRECATE ### Additional compile-time options for $(BYTECC). (For static linking.) -BYTECCCOMPOPTS=/Ox /MD +BYTECCCOMPOPTS=-Ox -MD ### Additional compile-time options for $(BYTECC). (For debug version.) -BYTECCDBGCOMPOPTS=-DDEBUG /Zi /W3 /Wp64 +BYTECCDBGCOMPOPTS=-DDEBUG -Zi -W3 -Wp64 ### Additional link-time options for $(BYTECC). (For static linking.) BYTECCLINKOPTS= ### Additional compile-time options for $(BYTECC). (For building a DLL.) -DLLCCCOMPOPTS=/Ox /MD +DLLCCCOMPOPTS=-Ox -MD ### Libraries needed #EXTRALIBS=bufferoverflowu.lib # for the old PSDK compiler only @@ -101,19 +101,19 @@ BYTECCLIBS=advapi32.lib ws2_32.lib $(EXTRALIBS) NATIVECCLIBS=advapi32.lib ws2_32.lib $(EXTRALIBS) ### How to invoke the C preprocessor -CPP=cl /nologo /EP +CPP=cl -nologo -EP ### Flexlink FLEXLINK=flexlink -x64 -merge-manifest -stack 33554432 -FLEXDIR=$(shell $(FLEXLINK) -where) +FLEXDIR:=$(shell $(FLEXLINK) -where) IFLEXDIR=-I"$(FLEXDIR)" MKDLL=$(FLEXLINK) MKEXE=$(FLEXLINK) -exe MKMAINDLL=$(FLEXLINK) -maindll ### How to build a static library -MKLIB=link /lib /nologo /machine:AMD64 /out:$(1) $(2) -#ml let mklib out files opts = Printf.sprintf "link /lib /nologo /machine:AMD64 /out:%s %s %s" out opts files;; +MKLIB=link -lib -nologo -machine:AMD64 /out:$(1) $(2) +#ml let mklib out files opts = Printf.sprintf "link -lib -nologo -machine:AMD64 -out:%s %s %s" out opts files;; MKSHAREDLIBRPATH= ### Canonicalize the name of a system library @@ -139,16 +139,16 @@ MODEL=default SYSTEM=win64 ### Which C compiler to use for the native-code compiler. -NATIVECC=cl /nologo +NATIVECC=cl -nologo ### Additional compile-time options for $(NATIVECC). -NATIVECCCOMPOPTS=/Ox /MD +NATIVECCCOMPOPTS=-Ox -MD ### Additional link-time options for $(NATIVECC) NATIVECCLINKOPTS= ### Build partially-linked object file -PACKLD=link /lib /nologo /machine:AMD64 /out:# must have no space after '/out:' +PACKLD=link -lib -nologo -machine:AMD64 -out:# must have no space after '-out:' ### Clear this to disable compiling ocamldebug WITH_DEBUGGER=ocamldebugger diff --git a/config/s-nt.h b/config/s-nt.h index 6df440b8..e8aa8785 100644 --- a/config/s-nt.h +++ b/config/s-nt.h @@ -27,3 +27,4 @@ #define HAS_LOCALE #define HAS_BROKEN_PRINTF #define HAS_IPV6 +#define HAS_NICE diff --git a/config/s-templ.h b/config/s-templ.h index d0748ae2..383b4015 100644 --- a/config/s-templ.h +++ b/config/s-templ.h @@ -212,3 +212,7 @@ The value of this symbol is the number of arguments of gethostbyaddr_r(): either 7 or 8 depending on prototype. (7 is the Solaris version, 8 is the Linux version). */ + +#define HAS_NICE + +/* Define HAS_NICE if you have nice(). */ diff --git a/configure b/configure index dbc61780..3edb9fd2 100755 --- a/configure +++ b/configure @@ -333,6 +333,10 @@ case "$bytecc,$target" in echo "#ifndef __PIC__" >> m.h echo "# define ARCH_CODE32" >> m.h echo "#endif" >> m.h;; + *,*-*-haiku*) + bytecccompopts="-fno-defer-pop $gcc_warnings" + # No -lm library + mathlib="";; *,*-*-beos*) bytecccompopts="-fno-defer-pop $gcc_warnings" # No -lm library @@ -655,7 +659,7 @@ if test $with_sharedlibs = "yes"; then mksharedlib="$flexlink" mkmaindll="$flexlink -maindll" shared_libraries_supported=true;; - *-*-linux-gnu|*-*-linux|*-*-freebsd[3-9]*|*-*-freebsd[1-9][0-9]*|*-*-openbsd*|*-*-netbsd*|*-*-gnu*) + *-*-linux-gnu|*-*-linux|*-*-freebsd[3-9]*|*-*-freebsd[1-9][0-9]*|*-*-openbsd*|*-*-netbsd*|*-*-gnu*|*-*-haiku*) sharedcccompopts="-fPIC" mksharedlib="$bytecc -shared" bytecclinkopts="$bytecclinkopts -Wl,-E" @@ -767,6 +771,7 @@ if test $with_sharedlibs = "yes"; then i[3456]86-*-netbsd*) natdynlink=true;; x86_64-*-netbsd*) natdynlink=true;; i386-*-gnu0.3) natdynlink=true;; + i[3456]86-*-haiku*) natdynlink=true;; arm*-*-linux*) natdynlink=true;; arm*-*-freebsd*) natdynlink=true;; aarch64-*-linux*) natdynlink=true;; @@ -799,6 +804,7 @@ case "$target" in else arch=i386; system=solaris fi;; + i[3456]86-*-haiku*) arch=i386; system=beos;; i[3456]86-*-beos*) arch=i386; system=beos;; i[3456]86-*-cygwin*) arch=i386; system=cygwin;; i[3456]86-*-darwin*) if $arch64; then @@ -875,7 +881,7 @@ esac asppprofflags='-DPROFILING' case "$arch,$system" in - amd64,macosx) if ./searchpath clang; then + amd64,macosx) if sh ./searchpath clang; then as='clang -arch x86_64 -c' aspp='clang -arch x86_64 -c' else @@ -1046,11 +1052,17 @@ if sh ./hasgot socket socketpair bind listen accept connect; then inf "You have BSD sockets." echo "#define HAS_SOCKETS" >> s.h has_sockets=yes -elif sh ./hasgot -lnsl -lsocket socket socketpair bind listen accept connect; then +elif sh ./hasgot -lnsl -lsocket socket socketpair bind listen accept connect +then inf "You have BSD sockets (with libraries '-lnsl -lsocket')" cclibs="$cclibs -lnsl -lsocket" echo "#define HAS_SOCKETS" >> s.h has_sockets=yes +elif sh ./hasgot -lnetwork socket socketpair bind listen accept connect; then + echo "You have BSD sockets (with library '-lnetwork')" + cclibs="$cclibs -lnetwork" + echo "#define HAS_SOCKETS" >> s.h + has_sockets=yes else case "$target" in *-*-mingw*) @@ -1309,6 +1321,11 @@ if sh ./hasgot mkstemp; then echo "#define HAS_MKSTEMP" >> s.h fi +if sh ./hasgot nice; then + inf "nice() found" + echo "#define HAS_NICE" >> s.h +fi + # Determine if the debugger is supported if test -n "$with_debugger"; then @@ -1324,7 +1341,8 @@ fi # Determine if system stack overflows can be detected case "$arch,$system" in - i386,linux_elf|amd64,linux|power,rhapsody|amd64,macosx|i386,macosx) + i386,linux_elf|amd64,linux|power,rhapsody|amd64,macosx|i386,macosx \ + |amd64,openbsd|i386,bsd_elf) inf "System stack overflow can be detected." echo "#define HAS_STACK_OVERFLOW_DETECTION" >> s.h;; *) @@ -1360,10 +1378,12 @@ if test "$pthread_wanted" = "yes"; then pthread_caml_link="-cclib -pthread";; *-*-openbsd*) pthread_link="-pthread" pthread_caml_link="-cclib -pthread";; + *-*-haiku*) pthread_link="" + pthread_caml_link="";; *) pthread_link="-lpthread" pthread_caml_link="-cclib -lpthread";; esac - if ./hasgot -i pthread.h $pthread_link pthread_self; then + if sh ./hasgot -i pthread.h $pthread_link pthread_self; then inf "POSIX threads library supported." systhread_support=true otherlibraries="$otherlibraries systhreads" @@ -1390,7 +1410,8 @@ if test "$pthread_wanted" = "yes"; then else pthread_link="" fi -echo "PTHREAD_LINK=$pthread_caml_link" >> Makefile +echo "PTHREAD_LINK=$pthread_link" >> Makefile +echo "PTHREAD_CAML_LINK=$pthread_caml_link" >> Makefile # Determine if the bytecode thread library is supported @@ -1553,7 +1574,7 @@ if test "x11_include" != "not found"; then if test "$x11_include" = "-I/usr/include"; then x11_include="" fi - if ./hasgot $x11_include $x11_link -i X11/Xlib.h XrmInitialize; then + if sh ./hasgot $x11_include $x11_link -i X11/Xlib.h XrmInitialize; then inf "X11 works" else wrn "Cannot compile X11 program." @@ -1581,8 +1602,8 @@ echo "X11_LINK=$x11_link" >> Makefile # Look for BFD library -if ./hasgot -i bfd.h && \ - ./hasgot -lbfd -ldl -liberty -lz bfd_openr; then +if sh ./hasgot -DPACKAGE=ocaml -i bfd.h && \ + sh ./hasgot -DPACKAGE=ocaml -lbfd -ldl -liberty -lz bfd_openr; then inf "BFD library found." echo "#define HAS_LIBBFD" >> s.h echo "LIBBFD_LINK=-lbfd -ldl -liberty -lz" >> Makefile diff --git a/debugger/source.ml b/debugger/source.ml index af69fbc7..aa9ec708 100644 --- a/debugger/source.ml +++ b/debugger/source.ml @@ -50,10 +50,10 @@ let source_of_module pos mdle = try find_in_path_uncap path (innermost_module ^ ext) with Not_found -> loop exts in loop source_extensions - else if Filename.is_implicit fname then - find_in_path path fname - else - fname + else if Filename.is_relative fname then + find_in_path_rel path fname + else if Sys.file_exists fname then fname + else raise Not_found (*** Buffer cache ***) diff --git a/driver/main_args.ml b/driver/main_args.ml index 4f9668c7..7636abe0 100644 --- a/driver/main_args.ml +++ b/driver/main_args.ml @@ -501,7 +501,7 @@ module type Common_options = sig val anonymous : string -> unit end;; -module type Compiler_options = sig +module type Compiler_options = sig val _a : unit -> unit val _annot : unit -> unit val _binannot : unit -> unit @@ -608,6 +608,22 @@ module type Opttop_options = sig val _stdin : unit -> unit end;; +module type Ocamldoc_options = sig + include Common_options + val _impl : string -> unit + val _intf : string -> unit + val _intf_suffix : string -> unit + val _pp : string -> unit + val _principal : unit -> unit + val _rectypes : unit -> unit + val _safe_string : unit -> unit + val _short_paths : unit -> unit + val _thread : unit -> unit + val _v : unit -> unit + val _verbose : unit -> unit + val _vmthread : unit -> unit +end;; + module type Arg_list = sig val list : (string * Arg.spec * string) list end;; @@ -874,3 +890,40 @@ module Make_opttop_options (F : Opttop_options) = struct mk_dstartup F._dstartup; ] end;; + +module Make_ocamldoc_options (F : Ocamldoc_options) = +struct + let list = [ + mk_absname F._absname; + mk_I F._I; + mk_impl F._impl; + mk_intf F._intf; + mk_intf_suffix F._intf_suffix; + mk_intf_suffix_2 F._intf_suffix; + mk_labels F._labels; + mk_modern F._labels; + mk_no_alias_deps F._no_alias_deps; + mk_no_app_funct F._no_app_funct; + mk_noassert F._noassert; + mk_nolabels F._nolabels; + mk_nostdlib F._nostdlib; + mk_open F._open; + mk_pp F._pp; + mk_ppx F._ppx; + mk_principal F._principal; + mk_rectypes F._rectypes; + mk_safe_string F._safe_string; + mk_short_paths F._short_paths; + mk_strict_sequence F._strict_sequence; + mk_strict_formats F._strict_formats; + mk_thread F._thread; + mk_unsafe_string F._unsafe_string; + mk_v F._v; + mk_verbose F._verbose; + mk_version F._version; + mk_vmthread F._vmthread; + mk_vnum F._vnum; + mk_w F._w; + mk__ F.anonymous; + ] +end;; diff --git a/driver/main_args.mli b/driver/main_args.mli index 95b7c69e..18ade80b 100644 --- a/driver/main_args.mli +++ b/driver/main_args.mli @@ -10,6 +10,9 @@ (* *) (***********************************************************************) +(* ATTENTION ! When you add or modify a parsing or typing option, do not forget + to update ocamldoc options too, in odoc_args.ml. *) + module type Common_options = sig val _absname : unit -> unit val _I : string -> unit @@ -152,6 +155,22 @@ module type Opttop_options = sig val _stdin : unit -> unit end;; +module type Ocamldoc_options = sig + include Common_options + val _impl : string -> unit + val _intf : string -> unit + val _intf_suffix : string -> unit + val _pp : string -> unit + val _principal : unit -> unit + val _rectypes : unit -> unit + val _safe_string : unit -> unit + val _short_paths : unit -> unit + val _thread : unit -> unit + val _v : unit -> unit + val _verbose : unit -> unit + val _vmthread : unit -> unit +end + module type Arg_list = sig val list : (string * Arg.spec * string) list end;; @@ -160,3 +179,4 @@ module Make_bytecomp_options (F : Bytecomp_options) : Arg_list;; module Make_bytetop_options (F : Bytetop_options) : Arg_list;; module Make_optcomp_options (F : Optcomp_options) : Arg_list;; module Make_opttop_options (F : Opttop_options) : Arg_list;; +module Make_ocamldoc_options (F : Ocamldoc_options) : Arg_list;; diff --git a/driver/pparse.ml b/driver/pparse.ml index 08b9bc73..4b2553f2 100644 --- a/driver/pparse.ml +++ b/driver/pparse.ml @@ -39,6 +39,10 @@ let remove_preprocessed inputfile = None -> () | Some _ -> Misc.remove_file inputfile + +(* Note: some of the functions here should go to Ast_mapper instead, + which would encapsulate the "binary AST" protocol. *) + let write_ast magic ast = let fn = Filename.temp_file "camlppx" "" in let oc = open_out_bin fn in @@ -87,41 +91,34 @@ let read_ast magic fn = Misc.remove_file fn; raise exn -let apply_rewriters ~tool_name magic ast = - let ctx = Ast_mapper.ppx_context ~tool_name () in +let rewrite magic ast ppxs = + read_ast magic + (List.fold_left (apply_rewriter magic) (write_ast magic ast) + (List.rev ppxs)) + +let apply_rewriters_str ?(restore = true) ~tool_name ast = match !Clflags.all_ppx with | [] -> ast | ppxs -> - let ast = - if magic = Config.ast_impl_magic_number - then Obj.magic (Ast_helper.Str.attribute ctx :: (Obj.magic ast)) - else Obj.magic (Ast_helper.Sig.attribute ctx :: (Obj.magic ast)) - in - let fn = - List.fold_left (apply_rewriter magic) (write_ast magic ast) - (List.rev ppxs) - in - let ast = read_ast magic fn in - let open Parsetree in - if magic = Config.ast_impl_magic_number then - let ast = - match Obj.magic ast with - | {pstr_desc = Pstr_attribute({Location.txt = "ocaml.ppx.context"}, _)} - :: items -> - items - | items -> items - in - Obj.magic ast - else - let ast = - match Obj.magic ast with - | {psig_desc = Psig_attribute({Location.txt = "ocaml.ppx.context"}, _)} - :: items -> - items - | items -> items - in - Obj.magic ast + let ast = Ast_mapper.add_ppx_context_str ~tool_name ast in + let ast = rewrite Config.ast_impl_magic_number ast ppxs in + Ast_mapper.drop_ppx_context_str ~restore ast +let apply_rewriters_sig ?(restore = true) ~tool_name ast = + match !Clflags.all_ppx with + | [] -> ast + | ppxs -> + let ast = Ast_mapper.add_ppx_context_sig ~tool_name ast in + let ast = rewrite Config.ast_intf_magic_number ast ppxs in + Ast_mapper.drop_ppx_context_sig ~restore ast + +let apply_rewriters ?restore ~tool_name magic ast = + if magic = Config.ast_impl_magic_number then + Obj.magic (apply_rewriters_str ?restore ~tool_name (Obj.magic ast)) + else if magic = Config.ast_intf_magic_number then + Obj.magic (apply_rewriters_sig ?restore ~tool_name (Obj.magic ast)) + else + assert false (* Parse a file or get a dumped syntax tree from it *) @@ -160,7 +157,7 @@ let file ppf ~tool_name inputfile parse_fun ast_magic = with x -> close_in ic; raise x in close_in ic; - apply_rewriters ~tool_name ast_magic ast + apply_rewriters ~restore:false ~tool_name ast_magic ast let report_error ppf = function | CannotRun cmd -> diff --git a/driver/pparse.mli b/driver/pparse.mli index d45adf91..bcff4e78 100644 --- a/driver/pparse.mli +++ b/driver/pparse.mli @@ -21,7 +21,14 @@ exception Error of error val preprocess : string -> string val remove_preprocessed : string -> unit val file : formatter -> tool_name:string -> string -> (Lexing.lexbuf -> 'a) -> string -> 'a -val apply_rewriters : tool_name:string -> string -> 'a -> 'a +val apply_rewriters: ?restore:bool -> tool_name:string -> string -> 'a -> 'a + (** If [restore = true] (the default), cookies set by external rewriters will be + kept for later calls. *) + +val apply_rewriters_str: ?restore:bool -> tool_name:string -> Parsetree.structure -> Parsetree.structure +val apply_rewriters_sig: ?restore:bool -> tool_name:string -> Parsetree.signature -> Parsetree.signature + + val report_error : formatter -> error -> unit diff --git a/emacs/caml-types.el b/emacs/caml-types.el index 47060a2c..4bc22665 100644 --- a/emacs/caml-types.el +++ b/emacs/caml-types.el @@ -113,9 +113,9 @@ type call ident" (make-variable-buffer-local 'caml-types-annotation-date) (defvar caml-types-buffer-name "*caml-types*" - "Name of buffer for diplaying caml types") + "Name of buffer for displaying caml types") (defvar caml-types-buffer nil - "buffer for diplaying caml types") + "buffer for displaying caml types") (defun caml-types-show-type (arg) "Show the type of expression or pattern at point. diff --git a/man/ocaml.m b/man/ocaml.m index 6764d52c..79f81df0 100644 --- a/man/ocaml.m +++ b/man/ocaml.m @@ -142,8 +142,9 @@ the statements open! module1;; ... open! moduleN;; were input. .BI \-ppx \ command After parsing, pipe the abstract syntax tree through the preprocessor .IR command . -The format of the input and output of the preprocessor -are not yet documented. +The module +.BR Ast_mapper (3) +implements the external interface of a preprocessor. .TP .B \-principal Check information path during type-checking, to make sure that all diff --git a/man/ocamlc.m b/man/ocamlc.m index 8661a76a..090f1c68 100644 --- a/man/ocamlc.m +++ b/man/ocamlc.m @@ -502,8 +502,9 @@ implementation (.ml) file. .BI \-ppx \ command After parsing, pipe the abstract syntax tree through the preprocessor .IR command . -The format of the input and output of the preprocessor -are not yet documented. +The module +.BR Ast_mapper (3) +implements the external interface of a preprocessor. .TP .B \-principal Check information path during type-checking, to make sure that all diff --git a/man/ocamlopt.m b/man/ocamlopt.m index b1b173af..fb20ca99 100644 --- a/man/ocamlopt.m +++ b/man/ocamlopt.m @@ -457,8 +457,9 @@ errors, the intermediate file is deleted afterwards. .BI \-ppx \ command After parsing, pipe the abstract syntax tree through the preprocessor .IR command . -The format of the input and output of the preprocessor -are not yet documented. +The module +.BR Ast_mapper (3) +implements the external interface of a preprocessor. .TP .B \-principal Check information path during type-checking, to make sure that all diff --git a/ocamlbuild/ocaml_specific.ml b/ocamlbuild/ocaml_specific.ml index 134a1533..79517a86 100644 --- a/ocamlbuild/ocaml_specific.ml +++ b/ocamlbuild/ocaml_specific.ml @@ -612,6 +612,8 @@ let () = (fun param -> S [A "-w"; A param]); pflag ["ocaml";"compile";] "warn_error" (fun param -> S [A "-warn-error"; A param]); + pflag ["ocaml"; "ocamldep"] "open" + (fun param -> S [A "-open"; A param]); pflag ["ocaml"; "compile"] "open" (fun param -> S [A "-open"; A param]); () @@ -668,7 +670,9 @@ flag ["ocaml"; "link"; "native"; "output_obj"] (A"-output-obj");; flag ["ocaml"; "link"; "byte"; "output_obj"] (A"-output-obj");; flag ["ocaml"; "dtypes"; "compile"] (A "-dtypes");; flag ["ocaml"; "annot"; "compile"] (A "-annot");; +flag ["ocaml"; "annot"; "pack"] (A "-annot");; flag ["ocaml"; "bin_annot"; "compile"] (A "-bin-annot");; +flag ["ocaml"; "bin_annot"; "pack"] (A "-bin-annot");; flag ["ocaml"; "safe_string"; "compile"] (A "-safe-string");; flag ["ocaml"; "safe_string"; "infer_interface"] (A "-safe-string");; flag ["ocaml"; "unsafe_string"; "compile"] (A "-unsafe-string");; diff --git a/ocamlbuild/options.ml b/ocamlbuild/options.ml index 5ee51220..5193b9b9 100644 --- a/ocamlbuild/options.ml +++ b/ocamlbuild/options.ml @@ -238,8 +238,7 @@ let spec = ref ( "-ocamlyacc", set_cmd ocamlyacc, " Set the ocamlyacc tool"; "-menhir", set_cmd ocamlyacc, " Set the menhir tool (use it after -use-menhir)"; "-ocamllex", set_cmd ocamllex, " Set the ocamllex tool"; - (* Not set since we perhaps want to replace ocamlmklib *) - (* "-ocamlmklib", set_cmd ocamlmklib, " Set the ocamlmklib tool"; *) + "-ocamlmklib", set_cmd ocamlmklib, " Set the ocamlmklib tool"; "-ocamlmktop", set_cmd ocamlmktop, " Set the ocamlmktop tool"; "-ocamlrun", set_cmd ocamlrun, " Set the ocamlrun tool"; @@ -316,6 +315,7 @@ let init () = "ocamlopt", ocamlopt; "ocamldep", ocamldep; "ocamldoc", ocamldoc; + "ocamlmklib", ocamlmklib; "ocamlmktop", ocamlmktop; ] end; diff --git a/ocamlbuild/testsuite/internal.ml b/ocamlbuild/testsuite/internal.ml index fc7ff98d..d0071543 100644 --- a/ocamlbuild/testsuite/internal.ml +++ b/ocamlbuild/testsuite/internal.ml @@ -303,4 +303,15 @@ let () = test "OpenTag" ~matching:[M.f "test.byte"] ~targets:("test.byte",[]) ();; +let () = test "OpenDependencies" + ~description:"Test dependency computation for the new -open feature (PR#6584)" + ~options:[`no_ocamlfind] + ~tree:[ + T.f "a.ml" ~content:"let x = 1"; + T.f "b.ml" ~content:"print_int x; print_newline ()"; + T.f "_tags" ~content: ": open(A)"; + ] + ~matching:[M.f "b.byte"] + ~targets:("b.byte",[]) ();; + run ~root:"_test_internal";; diff --git a/ocamldoc/.depend b/ocamldoc/.depend index 0f692a22..b98bb57f 100644 --- a/ocamldoc/.depend +++ b/ocamldoc/.depend @@ -22,12 +22,18 @@ odoc_analyse.cmx : ../utils/warnings.cmx ../typing/types.cmx \ odoc_comments.cmx odoc_class.cmx odoc_ast.cmx ../utils/misc.cmx \ ../parsing/location.cmx ../typing/env.cmx ../utils/config.cmx \ ../utils/clflags.cmx odoc_analyse.cmi -odoc_args.cmo : odoc_types.cmi odoc_texi.cmo odoc_messages.cmo odoc_man.cmo \ - odoc_latex.cmo odoc_html.cmo odoc_global.cmi odoc_gen.cmi odoc_dot.cmo \ - odoc_config.cmi ../utils/misc.cmi ../utils/config.cmi odoc_args.cmi -odoc_args.cmx : odoc_types.cmx odoc_texi.cmx odoc_messages.cmx odoc_man.cmx \ - odoc_latex.cmx odoc_html.cmx odoc_global.cmx odoc_gen.cmx odoc_dot.cmx \ - odoc_config.cmx ../utils/misc.cmx ../utils/config.cmx odoc_args.cmi +odoc_args.cmo : ../utils/warnings.cmi odoc_types.cmi odoc_texi.cmo \ + odoc_messages.cmo odoc_man.cmo odoc_latex.cmo odoc_html.cmo \ + odoc_global.cmi odoc_gen.cmi odoc_dot.cmo odoc_config.cmi \ + ../utils/misc.cmi ../driver/main_args.cmi ../parsing/location.cmi \ + ../utils/config.cmi ../driver/compenv.cmi ../utils/clflags.cmi \ + odoc_args.cmi +odoc_args.cmx : ../utils/warnings.cmx odoc_types.cmx odoc_texi.cmx \ + odoc_messages.cmx odoc_man.cmx odoc_latex.cmx odoc_html.cmx \ + odoc_global.cmx odoc_gen.cmx odoc_dot.cmx odoc_config.cmx \ + ../utils/misc.cmx ../driver/main_args.cmx ../parsing/location.cmx \ + ../utils/config.cmx ../driver/compenv.cmx ../utils/clflags.cmx \ + odoc_args.cmi odoc_ast.cmo : ../typing/types.cmi ../typing/typedtree.cmi \ ../typing/predef.cmi ../typing/path.cmi ../parsing/parsetree.cmi \ odoc_value.cmo odoc_types.cmi odoc_type.cmo odoc_sig.cmi \ diff --git a/ocamldoc/Makefile b/ocamldoc/Makefile index 0e8b288b..7a487c6c 100644 --- a/ocamldoc/Makefile +++ b/ocamldoc/Makefile @@ -148,6 +148,7 @@ OCAMLCMXFILES=$(OCAMLCMOFILES:.cmo=.cmx) STDLIB_MLIS=../stdlib/*.mli \ + ../parsing/*.mli \ ../otherlibs/$(UNIXLIB)/unix.mli \ ../otherlibs/str/str.mli \ ../otherlibs/bigarray/bigarray.mli \ diff --git a/ocamldoc/odoc_args.ml b/ocamldoc/odoc_args.ml index be5ce12f..77b59025 100644 --- a/ocamldoc/odoc_args.ml +++ b/ocamldoc/odoc_args.ml @@ -172,29 +172,73 @@ let add_hidden_modules s = let set_generator (g : Odoc_gen.generator) = current_generator := Some g +let anonymous f = + let sf = + if Filename.check_suffix f "ml" then + Odoc_global.Impl_file f + else + if Filename.check_suffix f !Config.interface_suffix then + Odoc_global.Intf_file f + else + if Filename.check_suffix f "txt" then + Odoc_global.Text_file f + else + failwith (Odoc_messages.unknown_extension f) + in + Odoc_global.files := !Odoc_global.files @ [sf] + +module Options = Main_args.Make_ocamldoc_options(struct + let set r () = r := true + let unset r () = r := false + let _absname = set Location.absname + let _I s = Odoc_global.include_dirs := + (Misc.expand_directory Config.standard_library s) :: !Odoc_global.include_dirs + let _impl s = Odoc_global.files := !Odoc_global.files @ [Odoc_global.Impl_file s] + let _intf s = Odoc_global.files := !Odoc_global.files @ [Odoc_global.Intf_file s] + let _intf_suffix s = Config.interface_suffix := s + let _labels = unset Clflags.classic + let _no_alias_deps = set Clflags.transparent_modules + let _no_app_funct = unset Clflags.applicative_functors + let _noassert = set Clflags.noassert + let _nolabels = set Clflags.classic + let _nostdlib = set Clflags.no_std_include + let _open s = Clflags.open_modules := s :: !Clflags.open_modules + let _pp s = Clflags.preprocessor := Some s + let _ppx s = Clflags.all_ppx := s :: !Clflags.all_ppx + let _principal = set Clflags.principal + let _rectypes = set Clflags.recursive_types + let _safe_string = unset Clflags.unsafe_string + let _short_paths = unset Clflags.real_paths + let _strict_sequence = set Clflags.strict_sequence + let _strict_formats = set Clflags.strict_formats + let _thread = set Clflags.use_threads + let _vmthread = set Clflags.use_vmthreads + let _unsafe () = assert false + let _unsafe_string = set Clflags.unsafe_string + let _v () = Compenv.print_version_and_library "documentation generator" + let _version = Compenv.print_version_string + let _vnum = Compenv.print_version_string + let _w = (Warnings.parse_options false) + let _warn_error _ = assert false + let _warn_help _ = assert false + let _where = Compenv.print_standard_library + let _verbose = set Clflags.verbose + let _nopervasives = set Clflags.nopervasives + let _dsource = set Clflags.dump_source + let _dparsetree = set Clflags.dump_parsetree + let _dtypedtree = set Clflags.dump_typedtree + let _drawlambda = set Clflags.dump_rawlambda + let _dlambda = set Clflags.dump_lambda + let _dinstr = set Clflags.dump_instr + let anonymous = anonymous +end) + (** The default option list *) -let default_options = [ - "-version", Arg.Unit (fun () -> print_string M.message_version ; print_newline () ; exit 0) , M.option_version ; - "-vnum", Arg.Unit (fun () -> print_string M.config_version ; - print_newline () ; exit 0) , M.option_version ; - "-v", Arg.Unit (fun () -> Odoc_global.verbose := true), M.verbose_mode ; - "-I", Arg.String (fun s -> - Odoc_global.include_dirs := - (Misc.expand_directory Config.standard_library s) :: !Odoc_global.include_dirs), - M.include_dirs ; - "-pp", Arg.String (fun s -> Odoc_global.preprocessor := Some s), M.preprocess ; - "-ppx", Arg.String (fun s -> Odoc_global.ppx := s :: !Odoc_global.ppx), M.ppx ; - "-impl", Arg.String (fun s -> - Odoc_global.files := !Odoc_global.files @ [Odoc_global.Impl_file s]), - M.option_impl ; - "-intf", Arg.String (fun s -> - Odoc_global.files := !Odoc_global.files @ [Odoc_global.Intf_file s]), - M.option_intf ; +let default_options = Options.list @ +[ "-text", Arg.String (fun s -> Odoc_global.files := !Odoc_global.files @ [Odoc_global.Text_file s]), M.option_text ; - "-rectypes", Arg.Set Odoc_global.recursive_types, M.rectypes ; - "-nolabels", Arg.Unit (fun () -> Odoc_global.classic := true), M.nolabels ; "-warn-error", Arg.Set Odoc_global.warn_error, M.werr ; "-hide-warnings", Arg.Clear Odoc_config.print_warnings, M.hide_warnings ; "-o", Arg.String (fun s -> Odoc_global.out_file := s), M.out_file ; @@ -338,24 +382,9 @@ let add_option o = options := iter !options let parse () = - let anonymous f = - let sf = - if Filename.check_suffix f "ml" then - Odoc_global.Impl_file f - else - if Filename.check_suffix f "mli" then - Odoc_global.Intf_file f - else - if Filename.check_suffix f "txt" then - Odoc_global.Text_file f - else - failwith (Odoc_messages.unknown_extension f) - in - Odoc_global.files := !Odoc_global.files @ [sf] - in if modified_options () then append_last_doc "\n"; let options = !options @ !help_options in - let _ = Arg.parse options + let _ = Arg.parse (Arg.align ~limit:13 options) anonymous (M.usage^M.options_are) in diff --git a/ocamldoc/odoc_global.ml b/ocamldoc/odoc_global.ml index 901febf1..9c3efb98 100644 --- a/ocamldoc/odoc_global.ml +++ b/ocamldoc/odoc_global.ml @@ -40,13 +40,6 @@ let dump = ref (None : string option) let load = ref ([] : string list) -(** Allow arbitrary recursive types. *) -let recursive_types = Clflags.recursive_types - -(** Optional preprocessor command. *) -let preprocessor = Clflags.preprocessor -let ppx = Clflags.all_ppx - let sort_modules = ref false let no_custom_tags = ref false @@ -65,11 +58,9 @@ let hidden_modules = ref ([] : string list) let files = ref [] - - let out_file = ref Odoc_messages.default_out_file -let verbose = ref false +let verbose = Clflags.verbose let target_dir = ref Filename.current_dir_name diff --git a/ocamldoc/odoc_global.mli b/ocamldoc/odoc_global.mli index 2cf846c3..641d40c0 100644 --- a/ocamldoc/odoc_global.mli +++ b/ocamldoc/odoc_global.mli @@ -21,13 +21,6 @@ type source_file = (** The include_dirs in the OCaml compiler. *) val include_dirs : string list ref -(** Optional preprocessor command to pass to ocaml compiler. *) -val preprocessor : string option ref (* -pp *) -val ppx : string list ref (* -ppx *) - -(** Recursive types flag to passe to ocaml compiler. *) -val recursive_types : bool ref - (** The merge options to be used. *) val merge_options : Odoc_types.merge_option list ref diff --git a/ocamldoc/odoc_messages.ml b/ocamldoc/odoc_messages.ml index 4c409a3a..0ac45ba9 100644 --- a/ocamldoc/odoc_messages.ml +++ b/ocamldoc/odoc_messages.ml @@ -16,13 +16,11 @@ let ok = "Ok" let software = "OCamldoc" let config_version = Config.version let magic = config_version^"" -let message_version = software^" "^config_version (** Messages for command line *) let usage = "Usage: "^(Sys.argv.(0))^" [options] \n" let options_are = "Options are:" -let option_version = "\tPrint version and exit" let latex_only = "(LaTeX only)" let texi_only = "(TeXinfo only)" let latex_texi_only = "(LaTeX and TeXinfo only)" @@ -30,51 +28,45 @@ let html_only = "(HTML only)" let html_latex_only = "(HTML and LaTeX only)" let html_latex_texi_only = "(HTML, LaTeX and TeXinfo only)" let man_only = "(man only)" -let verbose_mode = "\t\tverbose mode" -let include_dirs = "\tAdd to the list of include directories" -let rectypes = "\tAllow arbitrary recursive types" -let preprocess = "\tPipe sources through preprocessor " -let ppx = "\n\t\tPipe abstract syntax tree through preprocessor " -let option_impl ="\tConsider as a .ml file" -let option_intf ="\tConsider as a .mli file" -let option_text ="\tConsider as a .txt file" -let display_custom_generators_dir = "\tDisplay custom generators standard directory and exit" -let add_load_dir = "\tAdd the given directory to the search path for custom\n"^ +let option_impl =" Consider as a .ml file" +let option_intf =" Consider as a .mli file" +let option_text =" Consider as a .txt file" +let display_custom_generators_dir = "Display custom generators standard directory and exit" +let add_load_dir = " Add the given directory to the search path for custom\n"^ "\t\tgenerators" -let load_file = "\n\t\tLoad file defining a new documentation generator" -let nolabels = "\tIgnore non-optional labels in types" -let werr = "\tTreat ocamldoc warnings as errors" -let hide_warnings = "\n\t\tdo not print ocamldoc warnings" -let target_dir = "\tGenerate files in directory , rather than in current\n"^ +let load_file = " Load file defining a new documentation generator" +let werr = " Treat ocamldoc warnings as errors" +let hide_warnings = " do not print ocamldoc warnings" +let target_dir = " Generate files in directory , rather than in current\n"^ "\t\tdirectory (for man and HTML generators)" -let dump = "\tDump collected information into " -let load = "\tLoad information from ; may be used several times" -let css_style = "\n\t\tUse content of as CSS style definition "^html_only -let index_only = "\tGenerate index files only "^html_only -let colorize_code = "\n\t\tColorize code even in documentation pages "^html_only -let html_short_functors = "\n\t\tUse short form to display functor types "^html_only +let dump = " Dump collected information into " +let load = " Load information from ; may be used several times" +let css_style = " Use content of as CSS style definition "^html_only +let index_only = " Generate index files only "^html_only +let colorize_code = " Colorize code even in documentation pages "^html_only +let html_short_functors = " Use short form to display functor types "^html_only let charset c = Printf.sprintf - "\n\t\tAdd information about character encoding being s\n\t\t(default is %s)" + " Add information about character encoding being s\n\t\t(default is %s)" c -let generate_html = "\tGenerate HTML documentation" -let generate_latex = "\tGenerate LaTeX documentation" -let generate_texinfo = "\tGenerate TeXinfo documentation" -let generate_man = "\t\tGenerate man pages" -let generate_dot = "\t\tGenerate dot code of top modules dependencies" +let generate_html = " Generate HTML documentation" +let generate_latex = " Generate LaTeX documentation" +let generate_texinfo = " Generate TeXinfo documentation" +let generate_man = " Generate man pages" +let generate_dot = " Generate dot code of top modules dependencies" let option_not_in_native_code op = "Option "^op^" not available in native code version." let default_out_file = "ocamldoc.out" let out_file = - "\tSet the output file name, used by texi, latex and dot generators\n"^ + " Set the output file name, used by texi, latex and dot generators\n"^ "\t\t(default is "^default_out_file^")\n"^ "\t\tor the prefix of index files for the HTML generator\n"^ "\t\t(default is index)" let dot_include_all = - "\n\t\tInclude all modules in the dot output, not only the\n"^ + " Include all modules in the dot output, not only the\n"^ "\t\tmodules given on the command line" -let dot_types = "\tGenerate dependency graph for types instead of modules" +let dot_types = " Generate dependency graph for types instead of modules" let default_dot_colors = [ [ "darkturquoise" ; "darkgoldenrod2" ; "cyan" ; "green" ; ] ; [ "magenta" ; "yellow" ; "burlywood1" ; "aquamarine" ; "floralwhite" ; "lightpink" ] ; @@ -82,36 +74,37 @@ let default_dot_colors = ] let dot_colors = - "\n\t\tUse colors c1,c1,...,cn in the dot output\n"^ + " \n"^ + "\t\tUse colors c1,c1,...,cn in the dot output\n"^ "\t\t(default list is "^ (String.concat ",\n\t\t" (List.map (String.concat ",") default_dot_colors))^")" let dot_reduce = - "\tPerform a transitive reduction on the selected dependency graph\n"^ + " Perform a transitive reduction on the selected dependency graph\n"^ "\t\tbefore the dot output" -let man_mini = "\tGenerate man pages only for modules, module types, classes\n"^ +let man_mini = " Generate man pages only for modules, module types, classes\n"^ "\t\tand class types "^man_only let default_man_section = "3" -let man_section = "
\n\t\tUse
in man page files "^ +let man_section = "
Use
in man page files "^ "(default is "^default_man_section^") "^man_only^"\n" let default_man_suffix = default_man_section^"o" -let man_suffix = "\n\t\tUse for man page files "^ +let man_suffix = " Use for man page files "^ "(default is "^default_man_suffix^") "^man_only^"\n" -let option_title = "\tUse <title> as title for the generated documentation" +let option_title = "<title> Use <title> as title for the generated documentation" let option_intro = - "<file>\tUse content of <file> as ocamldoc text to use as introduction\n"^ + "<file> Use content of <file> as ocamldoc text to use as introduction\n"^ "\t\t"^(html_latex_texi_only) -let with_parameter_list = "\tDisplay the complete list of parameters for functions and\n"^ +let with_parameter_list = " Display the complete list of parameters for functions and\n"^ "\t\tmethods "^html_only -let hide_modules = "<M1,M2.M3,...>\n\t\tHide the given complete module names in generated doc" -let no_header = "\tSuppress header in generated documentation\n\t\t"^latex_texi_only -let no_trailer = "\tSuppress trailer in generated documentation\n\t\t"^latex_texi_only -let separate_files = "\tGenerate one file per toplevel module "^latex_only +let hide_modules = "<M1,M2.M3,...> Hide the given complete module names in generated doc" +let no_header = " Suppress header in generated documentation\n\t\t"^latex_texi_only +let no_trailer = " Suppress trailer in generated documentation\n\t\t"^latex_texi_only +let separate_files = " Generate one file per toplevel module "^latex_only let latex_title ref_titles = - "n,style\n\t\tAssociate {n } to the given sectionning style\n"^ + "n,style Associate {n } to the given sectionning style\n"^ "\t\t(e.g. 'section') in the latex output "^latex_only^"\n"^ "\t\tDefault sectionning is:\n\t\t"^ (String.concat "\n\t\t" @@ -119,67 +112,78 @@ let latex_title ref_titles = let default_latex_value_prefix = "val:" let latex_value_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of values.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of values.\n"^ "\t\t(default is \""^default_latex_value_prefix^"\")" let default_latex_type_prefix = "type:" let latex_type_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of types.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of types.\n"^ "\t\t(default is \""^default_latex_type_prefix^"\")" let default_latex_type_elt_prefix = "typeelt:" let latex_type_elt_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of type elements.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of type elements.\n"^ "\t\t(default is \""^default_latex_type_elt_prefix^"\")" let default_latex_extension_prefix = "extension:" let latex_extension_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of extensions.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of extensions.\n"^ "\t\t(default is \""^default_latex_extension_prefix^"\")" let default_latex_exception_prefix = "exception:" let latex_exception_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of exceptions.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of exceptions.\n"^ "\t\t(default is \""^default_latex_exception_prefix^"\")" let default_latex_module_prefix = "module:" let latex_module_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of modules.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of modules.\n"^ "\t\t(default is \""^default_latex_module_prefix^"\")" let default_latex_module_type_prefix = "moduletype:" let latex_module_type_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of module types.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of module types.\n"^ "\t\t(default is \""^default_latex_module_type_prefix^"\")" let default_latex_class_prefix = "class:" let latex_class_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of classes.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of classes.\n"^ "\t\t(default is \""^default_latex_class_prefix^"\")" let default_latex_class_type_prefix = "classtype:" let latex_class_type_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of class types.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of class types.\n"^ "\t\t(default is \""^default_latex_class_type_prefix^"\")" let default_latex_attribute_prefix = "val:" let latex_attribute_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of attributes.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of attributes.\n"^ "\t\t(default is \""^default_latex_attribute_prefix^"\")" let default_latex_method_prefix = "method:" let latex_method_prefix = - "<string>\n\t\tUse <string> as prefix for the LaTeX labels of methods.\n"^ + "<string>\n"^ + "\t\tUse <string> as prefix for the LaTeX labels of methods.\n"^ "\t\t(default is \""^default_latex_method_prefix^"\")" -let no_toc = "\tDo not generate table of contents "^latex_only -let sort_modules = "\tSort the list of top modules before generating the documentation" -let no_stop = "\tDo not stop at (**/**) comments" -let no_custom_tags = "\n\t\tDo not allow custom @-tags" -let remove_stars = "\tRemove beginning blanks of comment lines, until the first '*'" -let keep_code = "\tAlways keep code when available" -let inverse_merge_ml_mli = "\n\t\tInverse implementations and interfaces when merging" -let no_filter_with_module_constraints = "\n\t\tDo not filter module elements using module type constraints" +let no_toc = " Do not generate table of contents "^latex_only +let sort_modules = " Sort the list of top modules before generating the documentation" +let no_stop = " Do not stop at (**/**) comments" +let no_custom_tags = " Do not allow custom @-tags" +let remove_stars = " Remove beginning blanks of comment lines, until the first '*'" +let keep_code = " Always keep code when available" +let inverse_merge_ml_mli = " Inverse implementations and interfaces when merging" +let no_filter_with_module_constraints = "Do not filter module elements using module type constraints" let merge_description = ('d', "merge description") let merge_author = ('a', "merge @author") let merge_version = ('v', "merge @version") @@ -193,10 +197,10 @@ let merge_return_value = ('r', "merge @return") let merge_custom = ('c', "merge custom @-tags") let merge_all = ('A', "merge all") -let no_index = "\tDo not build index for Info files "^texi_only -let esc_8bits = "\tEscape accentuated characters in Info files "^texi_only -let info_section = "Specify section of Info directory "^texi_only -let info_entry = "\tSpecify Info directory entry "^texi_only +let no_index = " Do not build index for Info files "^texi_only +let esc_8bits = " Escape accentuated characters in Info files "^texi_only +let info_section = " Specify section of Info directory "^texi_only +let info_entry = " Specify Info directory entry "^texi_only let options_can_be = "<options> can be one or more of the following characters:" let string_of_options_list l = @@ -205,7 +209,7 @@ let string_of_options_list l = l let merge_options = - "<options>\tspecify merge options between .mli and .ml\n\t\t"^ + "<options> specify merge options between .mli and .ml\n\t\t"^ options_can_be^ (string_of_options_list [ merge_description ; @@ -222,7 +226,7 @@ let merge_options = merge_all ] ) -let help = "\t\tDisplay this list of options" +let help = " Display this list of options" (** Error and warning messages *) diff --git a/otherlibs/systhreads/Makefile b/otherlibs/systhreads/Makefile index a08bf34b..f24af23b 100644 --- a/otherlibs/systhreads/Makefile +++ b/otherlibs/systhreads/Makefile @@ -31,7 +31,7 @@ all: libthreads.a threads.cma allopt: libthreadsnat.a threads.cmxa libthreads.a: $(BYTECODE_C_OBJS) - $(MKLIB) -o threads $(BYTECODE_C_OBJS) -lpthread + $(MKLIB) -o threads $(BYTECODE_C_OBJS) $(PTHREAD_LINK) st_stubs_b.o: st_stubs.c st_posix.h $(BYTECC) -O -I../../byterun $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) \ @@ -51,12 +51,12 @@ st_stubs_n.o: st_stubs.c st_posix.h threads.cma: $(THREAD_OBJS) $(MKLIB) -ocamlc '$(CAMLC)' -o threads $(THREAD_OBJS) \ - -cclib -lunix $(PTHREAD_LINK) + -cclib -lunix $(PTHREAD_CAML_LINK) # See remark above: force static linking of libthreadsnat.a threads.cmxa: $(THREAD_OBJS:.cmo=.cmx) $(CAMLOPT) -a -o threads.cmxa $(THREAD_OBJS:.cmo=.cmx) \ - -cclib -lthreadsnat $(PTHREAD_LINK) + -cclib -lthreadsnat $(PTHREAD_CAML_LINK) # Note: I removed "-cclib -lunix" from the line above. # Indeed, if we link threads.cmxa, then we must also link unix.cmxa, diff --git a/otherlibs/threads/Makefile b/otherlibs/threads/Makefile index 1c4434f5..4b783333 100644 --- a/otherlibs/threads/Makefile +++ b/otherlibs/threads/Makefile @@ -27,21 +27,21 @@ CAML_OBJS=thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo LIB=../../stdlib -LIB_OBJS=$(LIB)/camlinternalFormatBasics.cmo pervasives.cmo \ - $(LIB)/array.cmo $(LIB)/list.cmo $(LIB)/char.cmo $(LIB)/string.cmo \ - $(LIB)/sys.cmo $(LIB)/sort.cmo marshal.cmo $(LIB)/obj.cmo \ - $(LIB)/int32.cmo $(LIB)/int64.cmo $(LIB)/nativeint.cmo \ - $(LIB)/lexing.cmo $(LIB)/parsing.cmo $(LIB)/set.cmo $(LIB)/map.cmo \ - $(LIB)/stack.cmo $(LIB)/queue.cmo $(LIB)/camlinternalLazy.cmo \ - $(LIB)/lazy.cmo $(LIB)/stream.cmo $(LIB)/buffer.cmo \ - $(LIB)/printf.cmo $(LIB)/arg.cmo $(LIB)/printexc.cmo $(LIB)/gc.cmo \ - $(LIB)/digest.cmo $(LIB)/random.cmo $(LIB)/hashtbl.cmo \ - $(LIB)/format.cmo $(LIB)/scanf.cmo $(LIB)/callback.cmo \ - $(LIB)/camlinternalOO.cmo \ - $(LIB)/oo.cmo $(LIB)/camlinternalMod.cmo $(LIB)/genlex.cmo \ - $(LIB)/weak.cmo $(LIB)/filename.cmo \ - $(LIB)/complex.cmo $(LIB)/arrayLabels.cmo $(LIB)/listLabels.cmo \ - $(LIB)/stringLabels.cmo $(LIB)/stdLabels.cmo $(LIB)/moreLabels.cmo +LIB_OBJS=$(LIB)/camlinternalFormatBasics.cmo pervasives.cmo \ + $(LIB)/array.cmo $(LIB)/list.cmo $(LIB)/char.cmo $(LIB)/bytes.cmo \ + $(LIB)/string.cmo $(LIB)/sys.cmo $(LIB)/sort.cmo $(LIB)/marshal.cmo \ + $(LIB)/obj.cmo $(LIB)/int32.cmo $(LIB)/int64.cmo \ + $(LIB)/nativeint.cmo $(LIB)/lexing.cmo $(LIB)/parsing.cmo \ + $(LIB)/set.cmo $(LIB)/map.cmo $(LIB)/stack.cmo $(LIB)/queue.cmo \ + $(LIB)/camlinternalLazy.cmo $(LIB)/lazy.cmo $(LIB)/stream.cmo \ + $(LIB)/buffer.cmo $(LIB)/camlinternalFormat.cmo $(LIB)/printf.cmo \ + $(LIB)/arg.cmo $(LIB)/printexc.cmo $(LIB)/gc.cmo $(LIB)/digest.cmo \ + $(LIB)/random.cmo $(LIB)/hashtbl.cmo $(LIB)/format.cmo \ + $(LIB)/scanf.cmo $(LIB)/callback.cmo $(LIB)/camlinternalOO.cmo \ + $(LIB)/oo.cmo $(LIB)/camlinternalMod.cmo $(LIB)/genlex.cmo \ + $(LIB)/weak.cmo $(LIB)/filename.cmo $(LIB)/complex.cmo \ + $(LIB)/arrayLabels.cmo $(LIB)/listLabels.cmo $(LIB)/bytesLabels.cmo \ + $(LIB)/stringLabels.cmo $(LIB)/moreLabels.cmo $(LIB)/stdLabels.cmo UNIXLIB=../unix diff --git a/otherlibs/unix/nice.c b/otherlibs/unix/nice.c index 019e2d1c..d0956a16 100644 --- a/otherlibs/unix/nice.c +++ b/otherlibs/unix/nice.c @@ -22,7 +22,11 @@ CAMLprim value unix_nice(value incr) { int ret; errno = 0; +#ifdef HAS_NICE ret = nice(Int_val(incr)); +#else + ret = 0; +#endif if (ret == -1 && errno != 0) uerror("nice", Nothing); return Val_int(ret); } diff --git a/parsing/ast_mapper.ml b/parsing/ast_mapper.ml index f44b1233..669d0144 100644 --- a/parsing/ast_mapper.ml +++ b/parsing/ast_mapper.ml @@ -19,7 +19,6 @@ open Asttypes -open Longident open Parsetree open Ast_helper open Location @@ -625,79 +624,170 @@ let attribute_of_warning loc s = { loc; txt = "ocaml.ppwarning" }, PStr ([Str.eval ~loc (Exp.constant (Const_string (s, None)))]) +module StringMap = Map.Make(struct + type t = string + let compare = compare +end) + +let cookies = ref StringMap.empty + +let get_cookie k = + try Some (StringMap.find k !cookies) + with Not_found -> None + +let set_cookie k v = + cookies := StringMap.add k v !cookies + let tool_name_ref = ref "_none_" let tool_name () = !tool_name_ref -let restore_ppx_context payload = - let fields = - match payload with + +module PpxContext = struct + open Longident + open Asttypes + open Ast_helper + + let lid name = { txt = Lident name; loc = Location.none } + + let make_string x = Exp.constant (Const_string (x, None)) + + let make_bool x = + if x + then Exp.construct (lid "true") None + else Exp.construct (lid "false") None + + let rec make_list f lst = + match lst with + | x :: rest -> + Exp.construct (lid "::") (Some (Exp.tuple [f x; make_list f rest])) + | [] -> + Exp.construct (lid "[]") None + + let make_pair f1 f2 (x1, x2) = + Exp.tuple [f1 x1; f2 x2] + + let make_option f opt = + match opt with + | Some x -> Exp.construct (lid "Some") (Some (f x)) + | None -> Exp.construct (lid "None") None + + let get_cookies () = + lid "cookies", + make_list (make_pair make_string (fun x -> x)) + (StringMap.bindings !cookies) + + let mk fields = + { txt = "ocaml.ppx.context"; loc = Location.none }, + Parsetree.PStr [Str.eval (Exp.record fields None)] + + let make ~tool_name () = + let fields = + [ + lid "tool_name", make_string tool_name; + lid "include_dirs", make_list make_string !Clflags.include_dirs; + lid "load_path", make_list make_string !Config.load_path; + lid "open_modules", make_list make_string !Clflags.open_modules; + lid "for_package", make_option make_string !Clflags.for_package; + lid "debug", make_bool !Clflags.debug; + get_cookies () + ] + in + mk fields + + let get_fields = function | PStr [{pstr_desc = Pstr_eval ({ pexp_desc = Pexp_record (fields, None) }, [])}] -> fields | _ -> raise_errorf "Internal error: invalid [@@@ocaml.ppx.context] syntax" - in - let field name payload = - let rec get_string = function - | { pexp_desc = Pexp_constant (Const_string (str, None)) } -> str - | _ -> - raise_errorf - "Internal error: invalid [@@@ocaml.ppx.context { %s }] string syntax" - name - and get_bool pexp = - match pexp with - | {pexp_desc = Pexp_construct ({txt = Longident.Lident "true"}, None)} -> - true - | {pexp_desc = Pexp_construct ({txt = Longident.Lident "false"}, None)} -> - false - | _ -> - raise_errorf - "Internal error: invalid [@@@ocaml.ppx.context { %s }] bool syntax" - name - and get_list elem = function - | {pexp_desc = - Pexp_construct ({txt = Longident.Lident "::"}, - Some {pexp_desc = Pexp_tuple [exp; rest]}) } -> - elem exp :: get_list elem rest - | {pexp_desc = - Pexp_construct ({txt = Longident.Lident "[]"}, None)} -> - [] - | _ -> - raise_errorf - "Internal error: invalid [@@@ocaml.ppx.context { %s }] list syntax" - name - and get_option elem = function - | { pexp_desc = - Pexp_construct ({ txt = Longident.Lident "Some" }, Some exp) } -> - Some (elem exp) - | { pexp_desc = - Pexp_construct ({ txt = Longident.Lident "None" }, None) } -> - None + + let restore fields = + let field name payload = + let rec get_string = function + | { pexp_desc = Pexp_constant (Const_string (str, None)) } -> str + | _ -> + raise_errorf + "Internal error: invalid [@@@ocaml.ppx.context { %s }] string syntax" + name + and get_bool pexp = + match pexp with + | {pexp_desc = Pexp_construct ({txt = Longident.Lident "true"}, None)} -> + true + | {pexp_desc = Pexp_construct ({txt = Longident.Lident "false"}, None)} -> + false + | _ -> + raise_errorf + "Internal error: invalid [@@@ocaml.ppx.context { %s }] bool syntax" + name + and get_list elem = function + | {pexp_desc = + Pexp_construct ({txt = Longident.Lident "::"}, + Some {pexp_desc = Pexp_tuple [exp; rest]}) } -> + elem exp :: get_list elem rest + | {pexp_desc = + Pexp_construct ({txt = Longident.Lident "[]"}, None)} -> + [] + | _ -> + raise_errorf + "Internal error: invalid [@@@ocaml.ppx.context { %s }] list syntax" + name + and get_pair f1 f2 = function + | {pexp_desc = Pexp_tuple [e1; e2]} -> + (f1 e1, f2 e2) + | _ -> + raise_errorf + "Internal error: invalid [@@@ocaml.ppx.context { %s }] pair syntax" + name + and get_option elem = function + | { pexp_desc = + Pexp_construct ({ txt = Longident.Lident "Some" }, Some exp) } -> + Some (elem exp) + | { pexp_desc = + Pexp_construct ({ txt = Longident.Lident "None" }, None) } -> + None + | _ -> + raise_errorf + "Internal error: invalid [@@@ocaml.ppx.context { %s }] option syntax" + name + in + match name with + | "tool_name" -> + tool_name_ref := get_string payload + | "include_dirs" -> + Clflags.include_dirs := get_list get_string payload + | "load_path" -> + Config.load_path := get_list get_string payload + | "open_modules" -> + Clflags.open_modules := get_list get_string payload + | "for_package" -> + Clflags.for_package := get_option get_string payload + | "debug" -> + Clflags.debug := get_bool payload + | "cookies" -> + let l = get_list (get_pair get_string (fun x -> x)) payload in + cookies := + List.fold_left + (fun s (k, v) -> StringMap.add k v s) StringMap.empty + l | _ -> - raise_errorf - "Internal error: invalid [@@@ocaml.ppx.context { %s }] option syntax" - name + () in - match name with - | "tool_name" -> - tool_name_ref := get_string payload - | "include_dirs" -> - Clflags.include_dirs := get_list get_string payload - | "load_path" -> - Config.load_path := get_list get_string payload - | "open_modules" -> - Clflags.open_modules := get_list get_string payload - | "for_package" -> - Clflags.for_package := get_option get_string payload - | "debug" -> - Clflags.debug := get_bool payload - | _ -> - () - in - List.iter (function ({txt=Lident name}, x) -> field name x | _ -> ()) fields + List.iter (function ({txt=Lident name}, x) -> field name x | _ -> ()) fields -let apply ~source ~target mapper = + let update_cookies fields = + let fields = + List.filter + (function ({txt=Lident "cookies"}, _) -> false | _ -> true) + fields + in + fields @ [get_cookies ()] +end + +let ppx_context = PpxContext.make + + +let apply_lazy ~source ~target mapper = let ic = open_in_bin source in let magic = really_input_string ic (String.length Config.ast_impl_magic_number) @@ -711,12 +801,17 @@ let apply ~source ~target mapper = let implem ast = try - begin match ast with - | {pstr_desc = Pstr_attribute ({txt = "ocaml.ppx.context"}, x)} :: _ -> - restore_ppx_context x - | _ -> () - end; - mapper.structure mapper ast + let fields, ast = + match ast with + | {pstr_desc = Pstr_attribute ({txt = "ocaml.ppx.context"}, x)} :: l -> + PpxContext.get_fields x, l + | _ -> [], ast + in + PpxContext.restore fields; + let mapper = mapper () in + let ast = mapper.structure mapper ast in + let fields = PpxContext.update_cookies fields in + Str.attribute (PpxContext.mk fields) :: ast with exn -> match error_of_exn exn with | Some error -> @@ -726,12 +821,17 @@ let apply ~source ~target mapper = in let iface ast = try - begin match ast with - | {psig_desc = Psig_attribute ({txt = "ocaml.ppx.context"}, x)} :: _ -> - restore_ppx_context x - | _ -> () - end; - mapper.signature mapper ast + let fields, ast = + match ast with + | {psig_desc = Psig_attribute ({txt = "ocaml.ppx.context"}, x)} :: l -> + PpxContext.get_fields x, l + | _ -> [], ast + in + PpxContext.restore fields; + let mapper = mapper () in + let ast = mapper.signature mapper ast in + let fields = PpxContext.update_cookies fields in + Sig.attribute (PpxContext.mk fields) :: ast with exn -> match error_of_exn exn with | Some error -> @@ -750,19 +850,45 @@ let apply ~source ~target mapper = output_value oc ast; close_out oc +let drop_ppx_context_str ~restore = function + | {pstr_desc = Pstr_attribute({Location.txt = "ocaml.ppx.context"}, a)} + :: items -> + if restore then + PpxContext.restore (PpxContext.get_fields a); + items + | items -> items + +let drop_ppx_context_sig ~restore = function + | {psig_desc = Psig_attribute({Location.txt = "ocaml.ppx.context"}, a)} + :: items -> + if restore then + PpxContext.restore (PpxContext.get_fields a); + items + | items -> items + +let add_ppx_context_str ~tool_name ast = + Ast_helper.Str.attribute (ppx_context ~tool_name ()) :: ast + +let add_ppx_context_sig ~tool_name ast = + Ast_helper.Sig.attribute (ppx_context ~tool_name ()) :: ast + + +let apply ~source ~target mapper = + apply_lazy ~source ~target (fun () -> mapper) + let run_main mapper = try let a = Sys.argv in let n = Array.length a in if n > 2 then - let mapper = + let mapper () = try mapper (Array.to_list (Array.sub a 1 (n - 3))) with exn -> (* PR #6463 *) let f _ _ = raise exn in {default_mapper with structure = f; signature = f} in - apply ~source:a.(n - 2) ~target:a.(n - 1) mapper + apply_lazy ~source:a.(n - 2) ~target:a.(n - 1) mapper else begin Printf.eprintf "Usage: %s [extra_args] <infile> <outfile>\n%!" Sys.executable_name; @@ -774,38 +900,3 @@ let run_main mapper = let register_function = ref (fun _name f -> run_main f) let register name f = !register_function name f - - -let ppx_context ~tool_name () = - let open Longident in - let open Asttypes in - let open Ast_helper in - let lid name = { txt = Lident name; loc = Location.none } in - let make_string x = Exp.constant (Const_string (x, None)) in - let make_bool x = - if x - then Exp.construct (lid "true") None - else Exp.construct (lid "false") None - in - let rec make_list f lst = - match lst with - | x :: rest -> - Exp.construct (lid "::") (Some (Exp.tuple [f x; make_list f rest])) - | [] -> - Exp.construct (lid "[]") None - in - let make_option f opt = - match opt with - | Some x -> Exp.construct (lid "Some") (Some (f x)) - | None -> Exp.construct (lid "None") None - in - { txt = "ocaml.ppx.context"; loc = Location.none }, - Parsetree.PStr [Str.eval ( - Exp.record ([ - lid "tool_name", make_string tool_name; - lid "include_dirs", make_list make_string !Clflags.include_dirs; - lid "load_path", make_list make_string !Config.load_path; - lid "open_modules", make_list make_string !Clflags.open_modules; - lid "for_package", make_option make_string !Clflags.for_package; - lid "debug", make_bool !Clflags.debug; - ]) None)] diff --git a/parsing/ast_mapper.mli b/parsing/ast_mapper.mli index 786c37d6..d48971d5 100644 --- a/parsing/ast_mapper.mli +++ b/parsing/ast_mapper.mli @@ -10,7 +10,40 @@ (* *) (***********************************************************************) -(** Helpers to write Parsetree rewriters *) +(** The interface of a -ppx rewriter + + A -ppx rewriter is a program that accepts a serialized abstract syntax + tree and outputs another, possibly modified, abstract syntax tree. + This module encapsulates the interface between the compiler and + the -ppx rewriters, handling such details as the serialization format, + forwarding of command-line flags, and storing state. + + {!mapper} allows to implement AST rewriting using open recursion. + A typical mapper would be based on {!default_mapper}, a deep + identity mapper, and will fall back on it for handling the syntax it + does not modify. For example: + + {[ +open Asttypes +open Parsetree +open Ast_mapper + +let test_mapper argv = + { default_mapper with + expr = fun mapper expr -> + match expr with + | { pexp_desc = Pexp_extension ({ txt = "test" }, PStr [])} -> + Ast_helper.Exp.constant (Const_int 42) + | other -> default_mapper.expr mapper other; } + +let () = + register "ppx_test" test_mapper]} + + This -ppx rewriter, which replaces [[%test]] in expressions with + the constant [42], can be compiled using + [ocamlc -o ppx_test -I +compiler-libs ocamlcommon.cma ppx_test.ml]. + + *) open Parsetree @@ -100,7 +133,6 @@ val run_main: (string list -> mapper) -> unit val register_function: (string -> (string list -> mapper) -> unit) ref val register: string -> (string list -> mapper) -> unit - (** Apply the [register_function]. The default behavior is to run the mapper immediately, taking arguments from the process command line. This is to support a scenario where a mapper is linked as a @@ -134,8 +166,28 @@ val attribute_of_warning: Location.t -> string -> attribute (** {2 Helper functions to call external mappers} *) -val ppx_context: tool_name:string -> unit -> Parsetree.attribute +val add_ppx_context_str: tool_name:string -> Parsetree.structure -> Parsetree.structure (** Extract information from the current environment and encode it - into an attribute an attribute which can be prepended to - signature/structure items of an AST to pass the information to an - external processor. *) + into an attribute which is prepended to the list of structure + items in order to pass the information to an external + processor. *) + +val add_ppx_context_sig: tool_name:string -> Parsetree.signature -> Parsetree.signature +(** Same as [add_ppx_context_str], but for signatures. *) + +val drop_ppx_context_str: restore:bool -> Parsetree.structure -> Parsetree.structure +(** Drop the ocaml.ppx.context attribute from a structure. If + [restore] is true, also restore the associated data in the current + process. *) + +val drop_ppx_context_sig: restore:bool -> Parsetree.signature -> Parsetree.signature +(** Same as [drop_ppx_context_str], but for signatures. *) + +(** {2 Cookies} *) + +(** Cookies are used to pass information from a ppx processor to + a further invocation of itself, when called from the OCaml + toplevel (or other tools that support cookies). *) + +val set_cookie: string -> Parsetree.expression -> unit +val get_cookie: string -> Parsetree.expression option diff --git a/parsing/location.ml b/parsing/location.ml index c6d1704f..174377ee 100644 --- a/parsing/location.ml +++ b/parsing/location.ml @@ -363,10 +363,15 @@ let () = ) -let report_exception ppf exn = - match error_of_exn exn with - | Some err -> fprintf ppf "@[%a@]@." report_error err +let rec report_exception_rec n ppf exn = + try match error_of_exn exn with + | Some err -> + fprintf ppf "@[%a@]@." report_error err | None -> raise exn + with exn when n > 0 -> + report_exception_rec (n-1) ppf exn + +let report_exception ppf exn = report_exception_rec 5 ppf exn exception Error of error diff --git a/parsing/parser.mly b/parsing/parser.mly index 4e2053be..ba8e98e6 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -547,7 +547,7 @@ parse_pattern: functor_arg: LPAREN RPAREN - { mkrhs "()" 2, None } + { mkrhs "*" 2, None } | LPAREN functor_arg_name COLON module_type RPAREN { mkrhs $2 2, Some $4 } ; @@ -776,7 +776,7 @@ module_declaration: | LPAREN UIDENT COLON module_type RPAREN module_declaration { mkmty(Pmty_functor(mkrhs $2 2, Some $4, $6)) } | LPAREN RPAREN module_declaration - { mkmty(Pmty_functor(mkrhs "()" 1, None, $3)) } + { mkmty(Pmty_functor(mkrhs "*" 1, None, $3)) } ; module_rec_declarations: module_rec_declaration { [$1] } diff --git a/parsing/pprintast.ml b/parsing/pprintast.ml index ad1e5daa..7dea70c5 100644 --- a/parsing/pprintast.ml +++ b/parsing/pprintast.ml @@ -351,7 +351,7 @@ class printer ()= object(self:'self) | p -> self#pattern1 f p in if x.ppat_attributes <> [] then self#pattern f x else match x.ppat_desc with - | Ppat_variant (l, Some p) -> pp f "@[<2>`%s@;%a@]" l self#pattern1 p (*RA*) + | Ppat_variant (l, Some p) -> pp f "@[<2>`%s@;%a@]" l self#simple_pattern p | Ppat_construct (({txt=Lident("()"|"[]");_}), _) -> self#simple_pattern f x | Ppat_construct (({txt;_} as li), po) -> (* FIXME The third field always false *) if txt = Lident "::" then diff --git a/stdlib/arg.ml b/stdlib/arg.ml index 0f6480b8..d7b8ac0b 100644 --- a/stdlib/arg.ml +++ b/stdlib/arg.ml @@ -255,18 +255,24 @@ let add_padding len ksd = ksd | (kwd, (Symbol (l, _) as spec), msg) -> let cutcol = second_word msg in - let spaces = String.make (len - cutcol + 3) ' ' in + let spaces = String.make ((max 0 (len - cutcol)) + 3) ' ' in (kwd, spec, "\n" ^ spaces ^ msg) | (kwd, spec, msg) -> let cutcol = second_word msg in - let spaces = String.make (len - String.length kwd - cutcol) ' ' in - let prefix = String.sub msg 0 cutcol in - let suffix = String.sub msg cutcol (String.length msg - cutcol) in - (kwd, spec, prefix ^ spaces ^ suffix) + let kwd_len = String.length kwd in + let diff = len - kwd_len - cutcol in + if diff <= 0 then + (kwd, spec, msg) + else + let spaces = String.make diff ' ' in + let prefix = String.sub msg 0 cutcol in + let suffix = String.sub msg cutcol (String.length msg - cutcol) in + (kwd, spec, prefix ^ spaces ^ suffix) ;; -let align speclist = +let align ?(limit=max_int) speclist = let completed = add_help speclist in let len = List.fold_left max_arg_len 0 completed in + let len = min len limit in List.map (add_padding len) completed ;; diff --git a/stdlib/arg.mli b/stdlib/arg.mli index 22eda40b..0999edf5 100644 --- a/stdlib/arg.mli +++ b/stdlib/arg.mli @@ -140,12 +140,15 @@ val usage_string : (key * spec * doc) list -> usage_msg -> string (** Returns the message that would have been printed by {!Arg.usage}, if provided with the same parameters. *) -val align: (key * spec * doc) list -> (key * spec * doc) list;; +val align: ?limit: int -> (key * spec * doc) list -> (key * spec * doc) list;; (** Align the documentation strings by inserting spaces at the first space, according to the length of the keyword. Use a space as the first character in a doc string if you want to align the whole string. The doc strings corresponding to - [Symbol] arguments are aligned on the next line. *) + [Symbol] arguments are aligned on the next line. + @param limit options with keyword and message longer than + [limit] will not be used to compute the alignement. +*) val current : int ref (** Position (in {!Sys.argv}) of the argument being processed. You can diff --git a/stdlib/array.mli b/stdlib/array.mli index e9a64528..99de0c80 100644 --- a/stdlib/array.mli +++ b/stdlib/array.mli @@ -47,7 +47,7 @@ external make : int -> 'a -> 'a array = "caml_make_vect" size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use Array.make instead."] (** @deprecated [Array.create] is an alias for {!Array.make}. *) val init : int -> (int -> 'a) -> 'a array @@ -74,7 +74,7 @@ val make_matrix : int -> int -> 'a -> 'a array array size is only [Sys.max_array_length / 2]. *) val create_matrix : int -> int -> 'a -> 'a array array - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use Array.make_matrix instead."] (** @deprecated [Array.create_matrix] is an alias for {!Array.make_matrix}. *) val append : 'a array -> 'a array -> 'a array diff --git a/stdlib/arrayLabels.mli b/stdlib/arrayLabels.mli index cf8b650e..0d046378 100644 --- a/stdlib/arrayLabels.mli +++ b/stdlib/arrayLabels.mli @@ -47,7 +47,7 @@ external make : int -> 'a -> 'a array = "caml_make_vect" size is only [Sys.max_array_length / 2].*) external create : int -> 'a -> 'a array = "caml_make_vect" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use ArrayLabels.make instead."] (** @deprecated [ArrayLabels.create] is an alias for {!ArrayLabels.make}. *) val init : int -> f:(int -> 'a) -> 'a array @@ -74,7 +74,7 @@ val make_matrix : dimx:int -> dimy:int -> 'a -> 'a array array size is only [Sys.max_array_length / 2]. *) val create_matrix : dimx:int -> dimy:int -> 'a -> 'a array array - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use ArrayLabels.make_matrix instead."] (** @deprecated [ArrayLabels.create_matrix] is an alias for {!ArrayLabels.make_matrix}. *) diff --git a/stdlib/bytes.ml b/stdlib/bytes.ml index ece7c1ea..ce6e126d 100644 --- a/stdlib/bytes.ml +++ b/stdlib/bytes.ml @@ -55,7 +55,7 @@ let of_string s = copy (unsafe_of_string s) let sub s ofs len = if ofs < 0 || len < 0 || ofs > length s - len - then invalid_arg "Bytes.sub" + then invalid_arg "String.sub / Bytes.sub" else begin let r = create len in unsafe_blit s ofs r 0 len; @@ -74,7 +74,7 @@ let extend s left right = let fill s ofs len c = if ofs < 0 || len < 0 || ofs > length s - len - then invalid_arg "Bytes.fill" + then invalid_arg "String.fill / Bytes.fill" else unsafe_fill s ofs len c let blit s1 ofs1 s2 ofs2 len = @@ -86,7 +86,7 @@ let blit s1 ofs1 s2 ofs2 len = let blit_string s1 ofs1 s2 ofs2 len = if len < 0 || ofs1 < 0 || ofs1 > string_length s1 - len || ofs2 < 0 || ofs2 > length s2 - len - then invalid_arg "Bytes.blit_string" + then invalid_arg "String.blit / Bytes.blit_string" else unsafe_blit_string s1 ofs1 s2 ofs2 len let iter f a = @@ -224,7 +224,7 @@ let index s c = index_rec s (length s) 0 c;; let index_from s i c = let l = length s in - if i < 0 || i > l then invalid_arg "Bytes.index_from" else + if i < 0 || i > l then invalid_arg "String.index_from / Bytes.index_from" else index_rec s l i c;; let rec rindex_rec s i c = @@ -234,19 +234,28 @@ let rec rindex_rec s i c = let rindex s c = rindex_rec s (length s - 1) c;; let rindex_from s i c = - if i < -1 || i >= length s then invalid_arg "Bytes.rindex_from" else - rindex_rec s i c;; + if i < -1 || i >= length s then + invalid_arg "String.rindex_from / Bytes.rindex_from" + else + rindex_rec s i c +;; let contains_from s i c = let l = length s in - if i < 0 || i > l then invalid_arg "Bytes.contains_from" else - try ignore (index_rec s l i c); true with Not_found -> false;; + if i < 0 || i > l then + invalid_arg "String.contains_from / Bytes.contains_from" + else + try ignore (index_rec s l i c); true with Not_found -> false +;; let contains s c = contains_from s 0 c;; let rcontains_from s i c = - if i < 0 || i >= length s then invalid_arg "Bytes.rcontains_from" else - try ignore (rindex_rec s i c); true with Not_found -> false;; + if i < 0 || i >= length s then + invalid_arg "String.rcontains_from / Bytes.rcontains_from" + else + try ignore (rindex_rec s i c); true with Not_found -> false +;; type t = bytes diff --git a/stdlib/camlinternalFormat.ml b/stdlib/camlinternalFormat.ml index 5dda3a7f..40d76678 100644 --- a/stdlib/camlinternalFormat.ml +++ b/stdlib/camlinternalFormat.ml @@ -94,6 +94,8 @@ fun ign fmt -> match ign with Param_format_EBB (Scan_char_set (width_opt, char_set, fmt)) | Ignored_scan_get_counter counter -> Param_format_EBB (Scan_get_counter (counter, fmt)) + | Ignored_scan_next_char -> + Param_format_EBB (Scan_next_char fmt) (******************************************************************************) @@ -568,6 +570,10 @@ let bprint_fmt buf fmt = buffer_add_char buf '%'; bprint_ignored_flag buf ign_flag; buffer_add_char buf (char_of_counter counter); fmtiter rest false; + | Scan_next_char rest -> + buffer_add_char buf '%'; bprint_ignored_flag buf ign_flag; + bprint_string_literal buf "0c"; fmtiter rest false; + | Ignored_param (ign, rest) -> let Param_format_EBB fmt' = param_format_of_ignored_format ign rest in fmtiter fmt' true; @@ -842,6 +848,7 @@ fun fmtty -> match fmtty with | Scan_char_set (_, _, rest) -> String_ty (fmtty_of_fmt rest) | Scan_get_counter (_, rest) -> Int_ty (fmtty_of_fmt rest) + | Scan_next_char rest -> Char_ty (fmtty_of_fmt rest) | Ignored_param (ign, rest) -> fmtty_of_ignored_format ign rest | Formatting_lit (_, rest) -> fmtty_of_fmt rest | Formatting_gen (fmting_gen, rest) -> @@ -871,6 +878,7 @@ fun ign fmt -> match ign with | Ignored_reader -> Ignored_reader_ty (fmtty_of_fmt fmt) | Ignored_scan_char_set _ -> fmtty_of_fmt fmt | Ignored_scan_get_counter _ -> fmtty_of_fmt fmt + | Ignored_scan_next_char -> fmtty_of_fmt fmt (* Add an Int_ty node if padding is taken as an extra argument (ex: "%*s"). *) and fmtty_of_padding_fmtty : type x a b c d e f . @@ -1067,7 +1075,7 @@ fun formatting_gen fmt0 fmtty0 -> match formatting_gen with | Open_box (Format (fmt1, str)) -> let Fmt_fmtty_EBB (fmt2, fmtty2) = type_format_gen fmt1 fmtty0 in let Fmt_fmtty_EBB (fmt3, fmtty3) = type_format_gen fmt0 fmtty2 in - Fmt_fmtty_EBB (Formatting_gen (Open_tag (Format (fmt2, str)), fmt3), fmtty3) + Fmt_fmtty_EBB (Formatting_gen (Open_box (Format (fmt2, str)), fmt3), fmtty3) (* Type an Ignored_param node according to an fmtty. *) and type_ignored_param : type p q x y z t u v a b c d e f . @@ -1088,6 +1096,7 @@ fun ign fmt fmtty -> match ign with | Ignored_bool as ign' -> type_ignored_param_one ign' fmt fmtty | Ignored_scan_char_set _ as ign' -> type_ignored_param_one ign' fmt fmtty | Ignored_scan_get_counter _ as ign' -> type_ignored_param_one ign' fmt fmtty + | Ignored_scan_next_char as ign' -> type_ignored_param_one ign' fmt fmtty | Ignored_format_arg (pad_opt, sub_fmtty) -> type_ignored_param_one (Ignored_format_arg (pad_opt, sub_fmtty)) fmt fmtty | Ignored_format_subst (pad_opt, sub_fmtty) -> @@ -1229,6 +1238,18 @@ let recast : (* Add padding spaces arround a string. *) let fix_padding padty width str = let len = String.length str in + let width, padty = + abs width, + (* while literal padding widths are always non-negative, + dynamically-set widths (Arg_padding, eg. %*d) may be negative; + we interpret those as specifying a padding-to-the-left; this + means that '0' may get dropped even if it was explicitly set, + but: + - this is what the legacy implementation does, and + we preserve compatibility if possible + - we could only signal this issue by failing at runtime, + which is not very nice... *) + if width < 0 then Left else padty in if width <= len then str else let res = Bytes.make width (if padty = Zeros then '0' else ' ') in begin match padty with @@ -1247,22 +1268,25 @@ let fix_padding padty width str = (* Add '0' padding to int, int32, nativeint or int64 string representation. *) let fix_int_precision prec str = + let prec = abs prec in let len = String.length str in - if prec <= len then str else + match str.[0] with + | ('+' | '-' | ' ') as c when prec + 1 > len -> + let res = Bytes.make (prec + 1) '0' in + Bytes.set res 0 c; + String.blit str 1 res (prec - len + 2) (len - 1); + Bytes.unsafe_to_string res + | '0' when prec + 2 > len && len > 1 && (str.[1] = 'x' || str.[1] = 'X') -> + let res = Bytes.make (prec + 2) '0' in + Bytes.set res 1 str.[1]; + String.blit str 2 res (prec - len + 4) (len - 2); + Bytes.unsafe_to_string res + | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' when prec > len -> let res = Bytes.make prec '0' in - begin match str.[0] with - | ('+' | '-' | ' ') as c -> - Bytes.set res 0 c; - String.blit str 1 res (prec - len + 1) (len - 1); - | '0' when len > 1 && (str.[1] = 'x' || str.[1] = 'X') -> - Bytes.set res 1 str.[1]; - String.blit str 2 res (prec - len + 2) (len - 2); - | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' -> - String.blit str 0 res (prec - len) len; - | _ -> - assert false - end; + String.blit str 0 res (prec - len) len; Bytes.unsafe_to_string res + | _ -> + str (* Escape a string according to the OCaml lexing convention. *) let string_to_caml_string str = @@ -1291,6 +1315,7 @@ let format_of_aconv iconv c = (* Generate the format_float first argument form a float_conv. *) let format_of_fconv fconv prec = + let prec = abs prec in let symb = if fconv = Float_F then 'g' else char_of_fconv fconv in let buf = buffer_create 16 in buffer_add_char buf '%'; @@ -1309,6 +1334,7 @@ let convert_int64 iconv n = format_int64 (format_of_aconv iconv 'L') n (* Convert a float to string. *) (* Fix special case of "OCaml float format". *) let convert_float fconv prec x = + let prec = abs prec in let str = format_float (format_of_fconv fconv prec) x in if fconv <> Float_F then str else let len = String.length str in @@ -1414,6 +1440,10 @@ fun k o acc fmt -> match fmt with fun n -> let new_acc = Acc_data_string (acc, format_int "%u" n) in make_printf k o new_acc rest + | Scan_next_char rest -> + fun c -> + let new_acc = Acc_data_char (acc, c) in + make_printf k o new_acc rest | Ignored_param (ign, rest) -> make_ignored_param k o acc ign rest @@ -1453,6 +1483,7 @@ fun k o acc ign fmt -> match ign with | Ignored_reader -> assert false | Ignored_scan_char_set _ -> make_invalid_arg k o acc fmt | Ignored_scan_get_counter _ -> make_invalid_arg k o acc fmt + | Ignored_scan_next_char -> make_invalid_arg k o acc fmt (* Special case of printf "%_(". *) @@ -1789,26 +1820,39 @@ let fmt_ebb_of_string ?legacy_behavior str = in (* Raise a Failure with a friendly error message. *) + let invalid_format_message str_ind msg = + failwith_message + "invalid format %S: at character number %d, %s" + str str_ind msg; + in + (* Used when the end of the format (or the current sub-format) was encoutered unexpectedly. *) let unexpected_end_of_format end_ind = - failwith_message - "invalid format %S: at character number %d, unexpected end of format" - str end_ind; + invalid_format_message end_ind + "unexpected end of format" + in + (* Used for %0c: no other widths are implemented *) + let invalid_nonnull_char_width str_ind = + invalid_format_message str_ind + "non-zero widths are unsupported for %c conversions" + in (* Raise Failure with a friendly error message about an option dependencie problem. *) - and invalid_format_without str_ind c s = + let invalid_format_without str_ind c s = failwith_message "invalid format %S: at character number %d, '%c' without %s" str str_ind c s + in (* Raise Failure with a friendly error message about an unexpected character. *) - and expected_character str_ind expected read = + let expected_character str_ind expected read = failwith_message "invalid format %S: at character number %d, %s expected, read %C" - str str_ind expected read in + str str_ind expected read + in (* Parse the string from beg_ind (included) to end_ind (excluded). *) let rec parse : type e f . int -> int -> (_, _, e, f) fmt_ebb = @@ -1883,52 +1927,56 @@ let fmt_ebb_of_string ?legacy_behavior str = match str.[str_ind] with | '0' .. '9' -> let new_ind, width = parse_positive str_ind end_ind 0 in - parse_after_padding pct_ind new_ind end_ind plus sharp space ign + parse_after_padding pct_ind new_ind end_ind minus plus sharp space ign (Lit_padding (padty, width)) | '*' -> - parse_after_padding pct_ind (str_ind + 1) end_ind plus sharp space ign - (Arg_padding padty) + parse_after_padding pct_ind (str_ind + 1) end_ind minus plus sharp space + ign (Arg_padding padty) | _ -> - if legacy_behavior then - parse_after_padding pct_ind str_ind end_ind plus sharp space ign - No_padding - else begin match padty with + begin match padty with | Left -> - invalid_format_without (str_ind - 1) '-' "padding" + if not legacy_behavior then + invalid_format_without (str_ind - 1) '-' "padding"; + parse_after_padding pct_ind str_ind end_ind minus plus sharp space ign + No_padding | Zeros -> - invalid_format_without (str_ind - 1) '0' "padding" + (* a '0' padding indication not followed by anything should + be interpreted as a Right padding of width 0. This is used + by scanning conversions %0s and %0c *) + parse_after_padding pct_ind str_ind end_ind minus plus sharp space ign + (Lit_padding (Right, 0)) | Right -> - parse_after_padding pct_ind str_ind end_ind plus sharp space ign + parse_after_padding pct_ind str_ind end_ind minus plus sharp space ign No_padding end (* Is precision defined? *) and parse_after_padding : type x e f . - int -> int -> int -> bool -> bool -> bool -> bool -> (x, _) padding -> - (_, _, e, f) fmt_ebb = - fun pct_ind str_ind end_ind plus sharp space ign pad -> + int -> int -> int -> bool -> bool -> bool -> bool -> bool -> + (x, _) padding -> (_, _, e, f) fmt_ebb = + fun pct_ind str_ind end_ind minus plus sharp space ign pad -> if str_ind = end_ind then unexpected_end_of_format end_ind; match str.[str_ind] with | '.' -> - parse_precision pct_ind (str_ind + 1) end_ind plus sharp space ign pad + parse_precision pct_ind (str_ind + 1) end_ind minus plus sharp space ign + pad | symb -> parse_conversion pct_ind (str_ind + 1) end_ind plus sharp space ign pad - No_precision symb + No_precision pad symb (* Read the digital or '*' precision. *) and parse_precision : type x e f . - int -> int -> int -> bool -> bool -> bool -> bool -> (x, _) padding -> - (_, _, e, f) fmt_ebb = - fun pct_ind str_ind end_ind plus sharp space ign pad -> + int -> int -> int -> bool -> bool -> bool -> bool -> bool -> + (x, _) padding -> (_, _, e, f) fmt_ebb = + fun pct_ind str_ind end_ind minus plus sharp space ign pad -> if str_ind = end_ind then unexpected_end_of_format end_ind; - let parse_literal str_ind = + let parse_literal minus str_ind = let new_ind, prec = parse_positive str_ind end_ind 0 in - if new_ind = end_ind then unexpected_end_of_format end_ind; - parse_conversion pct_ind (new_ind + 1) end_ind plus sharp space ign pad - (Lit_precision prec) str.[new_ind] in + parse_after_precision pct_ind new_ind end_ind minus plus sharp space ign + pad (Lit_precision prec) in match str.[str_ind] with - | '0' .. '9' -> parse_literal str_ind - | ('+' | '-') when legacy_behavior -> + | '0' .. '9' -> parse_literal minus str_ind + | ('+' | '-') as symb when legacy_behavior -> (* Legacy mode would accept and ignore '+' or '-' before the integer describing the desired precision; not that this cannot happen for padding width, as '+' and '-' already have @@ -1937,47 +1985,67 @@ let fmt_ebb_of_string ?legacy_behavior str = That said, the idea (supported by this tweak) that width and precision literals are "integer literals" in the OCaml sense is still blatantly wrong, as 123_456 or 0xFF are rejected. *) - parse_literal (str_ind + 1) + parse_literal (minus || symb = '-') (str_ind + 1) | '*' -> - parse_after_precision pct_ind (str_ind + 1) end_ind plus sharp space ign - pad Arg_precision + parse_after_precision pct_ind (str_ind + 1) end_ind minus plus sharp space + ign pad Arg_precision | _ -> if legacy_behavior then (* note that legacy implementation did not ignore '.' without a number (as it does for padding indications), but interprets it as '.0' *) - parse_after_precision pct_ind str_ind end_ind plus sharp space ign pad (Lit_precision 0) else - invalid_format_without (str_ind - 1) '.' "precision" + parse_after_precision pct_ind str_ind end_ind minus plus sharp space ign + pad (Lit_precision 0) + else + invalid_format_without (str_ind - 1) '.' "precision" (* Try to read the conversion. *) - and parse_after_precision : type x z e f . - int -> int -> int -> bool -> bool -> bool -> bool -> (x, _) padding -> - (z, _) precision -> (_, _, e, f) fmt_ebb = - fun pct_ind str_ind end_ind plus sharp space ign pad prec -> + and parse_after_precision : type x y z t e f . + int -> int -> int -> bool -> bool -> bool -> bool -> bool -> + (x, y) padding -> (z, t) precision -> (_, _, e, f) fmt_ebb = + fun pct_ind str_ind end_ind minus plus sharp space ign pad prec -> if str_ind = end_ind then unexpected_end_of_format end_ind; - parse_conversion pct_ind (str_ind + 1) end_ind plus sharp space ign pad prec - str.[str_ind] + let parse_conv (type u) (type v) (padprec : (u, v) padding) = + parse_conversion pct_ind (str_ind + 1) end_ind plus sharp space ign pad + prec padprec str.[str_ind] in + (* in legacy mode, some formats (%s and %S) accept a weird mix of + padding and precision, which is merged as a single padding + information. For example, in %.10s the precision is implicitly + understood as padding %10s, but the left-padding component may + be specified either as a left padding or a negative precision: + %-.3s and %.-3s are equivalent to %-3s *) + match pad with + | No_padding -> ( + match minus, prec with + | _, No_precision -> parse_conv No_padding + | false, Lit_precision n -> parse_conv (Lit_padding (Right, n)) + | true, Lit_precision n -> parse_conv (Lit_padding (Left, n)) + | false, Arg_precision -> parse_conv (Arg_padding Right) + | true, Arg_precision -> parse_conv (Arg_padding Left) + ) + | pad -> parse_conv pad (* Case analysis on conversion. *) - and parse_conversion : type x y z t e f . + and parse_conversion : type x y z t u v e f . int -> int -> int -> bool -> bool -> bool -> bool -> (x, y) padding -> - (z, t) precision -> char -> (_, _, e, f) fmt_ebb = - fun pct_ind str_ind end_ind plus sharp space ign pad prec symb -> + (z, t) precision -> (u, v) padding -> char -> (_, _, e, f) fmt_ebb = + fun pct_ind str_ind end_ind plus sharp space ign pad prec padprec symb -> (* Flags used to check option usages/compatibilities. *) let plus_used = ref false and sharp_used = ref false and space_used = ref false and ign_used = ref false and pad_used = ref false and prec_used = ref false in (* Access to options, update flags. *) - let get_plus () = plus_used := true; plus - and get_sharp () = sharp_used := true; sharp - and get_space () = space_used := true; space - and get_ign () = ign_used := true; ign - and get_pad () = pad_used := true; pad - and get_prec () = prec_used := true; prec in + let get_plus () = plus_used := true; plus + and get_sharp () = sharp_used := true; sharp + and get_space () = space_used := true; space + and get_ign () = ign_used := true; ign + and get_pad () = pad_used := true; pad + and get_prec () = prec_used := true; prec + and get_padprec () = pad_used := true; padprec in (* Check that padty <> Zeros. *) - let check_no_0 symb (type a) (type b) (pad : (a,b) padding) = + let check_no_0 symb (type a) (type b) (pad : (a, b) padding) = match pad with | No_padding -> pad | Lit_padding ((Left | Right), _) -> pad @@ -1993,7 +2061,7 @@ let fmt_ebb_of_string ?legacy_behavior str = (* Get padding as a pad_option (see "%_", "%{", "%(" and "%["). (no need for legacy mode tweaking, those were rejected by the legacy parser as well) *) - let get_pad_opt c = match get_pad () with + let opt_of_pad c (type a) (type b) (pad : (a, b) padding) = match pad with | No_padding -> None | Lit_padding (Right, width) -> Some width | Lit_padding (Zeros, width) -> @@ -2002,8 +2070,10 @@ let fmt_ebb_of_string ?legacy_behavior str = | Lit_padding (Left, width) -> if legacy_behavior then Some width else incompatible_flag pct_ind str_ind c "'-'" - | Arg_padding _ -> incompatible_flag pct_ind str_ind c "'*'" + | Arg_padding _ -> incompatible_flag pct_ind str_ind c "'*'" in + let get_pad_opt c = opt_of_pad c (get_pad ()) in + let get_padprec_opt c = opt_of_pad c (get_padprec ()) in (* Get precision as a prec_option (see "%_f"). (no need for legacy mode tweaking, those were rejected by the @@ -2018,28 +2088,44 @@ let fmt_ebb_of_string ?legacy_behavior str = | ',' -> parse str_ind end_ind | 'c' -> + let char_format fmt_rest = (* %c *) + if get_ign () + then Fmt_EBB (Ignored_param (Ignored_char, fmt_rest)) + else Fmt_EBB (Char fmt_rest) + in + let scan_format fmt_rest = (* %0c *) + if get_ign () + then Fmt_EBB (Ignored_param (Ignored_scan_next_char, fmt_rest)) + else Fmt_EBB (Scan_next_char fmt_rest) + in let Fmt_EBB fmt_rest = parse str_ind end_ind in - if get_ign () then Fmt_EBB (Ignored_param (Ignored_char, fmt_rest)) - else Fmt_EBB (Char fmt_rest) + begin match get_pad_opt 'c' with + | None -> char_format fmt_rest + | Some 0 -> scan_format fmt_rest + | Some _n -> + if not legacy_behavior + then invalid_nonnull_char_width str_ind + else (* legacy ignores %c widths *) char_format fmt_rest + end | 'C' -> let Fmt_EBB fmt_rest = parse str_ind end_ind in if get_ign () then Fmt_EBB (Ignored_param (Ignored_caml_char,fmt_rest)) else Fmt_EBB (Caml_char fmt_rest) | 's' -> - let pad = check_no_0 symb (get_pad ()) in + let pad = check_no_0 symb (get_padprec ()) in let Fmt_EBB fmt_rest = parse str_ind end_ind in if get_ign () then - let ignored = Ignored_string (get_pad_opt '_') in + let ignored = Ignored_string (get_padprec_opt '_') in Fmt_EBB (Ignored_param (ignored, fmt_rest)) else let Padding_fmt_EBB (pad', fmt_rest') = make_padding_fmt_ebb pad fmt_rest in Fmt_EBB (String (pad', fmt_rest')) | 'S' -> - let pad = check_no_0 symb (get_pad ()) in + let pad = check_no_0 symb (get_padprec ()) in let Fmt_EBB fmt_rest = parse str_ind end_ind in if get_ign () then - let ignored = Ignored_caml_string (get_pad_opt '_') in + let ignored = Ignored_caml_string (get_padprec_opt '_') in Fmt_EBB (Ignored_param (ignored, fmt_rest)) else let Padding_fmt_EBB (pad', fmt_rest') = @@ -2053,8 +2139,31 @@ let fmt_ebb_of_string ?legacy_behavior str = let ignored = Ignored_int (iconv, get_pad_opt '_') in Fmt_EBB (Ignored_param (ignored, fmt_rest)) else + (* %5.3d is accepted and meaningful: pad to length 5 with + spaces, but first pad with zeros upto length 3 (0-padding + is the interpretation of "precision" for integer formats). + + %05.3d is redundant: pad to length 5 *with zeros*, but + first pad with zeros... To add insult to the injury, the + legacy implementation ignores the 0-padding indication and + does the 5 padding with spaces instead. We reuse this + interpretation for compatiblity, but statically reject this + format when the legacy mode is disabled, to protect strict + users from this corner case. + *) + let pad = match get_pad (), get_prec () with + | pad, No_precision -> pad + | No_padding, _ -> No_padding + | Lit_padding (Zeros, n), _ -> + if legacy_behavior then Lit_padding (Right, n) + else incompatible_flag pct_ind str_ind '0' "precision" + | Arg_padding Zeros, _ -> + if legacy_behavior then Arg_padding Right + else incompatible_flag pct_ind str_ind '0' "precision" + | Lit_padding _ as pad, _ -> pad + | Arg_padding _ as pad, _ -> pad in let Padprec_fmt_EBB (pad', prec', fmt_rest') = - make_padprec_fmt_ebb (get_pad ()) (get_prec ()) fmt_rest in + make_padprec_fmt_ebb pad (get_prec ()) fmt_rest in Fmt_EBB (Int (iconv, pad', prec', fmt_rest')) | 'N' -> let Fmt_EBB fmt_rest = parse str_ind end_ind in @@ -2294,7 +2403,7 @@ let fmt_ebb_of_string ?legacy_behavior str = fun str_ind end_ind -> let next_ind, formatting_lit = try - if str_ind = end_ind || str.[str_ind] <> '<' then raise Not_found; + if str_ind = end_ind || str.[str_ind] <> '<' then raise Not_found; let str_ind_1 = parse_spaces (str_ind + 1) end_ind in match str.[str_ind_1] with | '0' .. '9' | '-' -> ( @@ -2542,24 +2651,24 @@ let fmt_ebb_of_string ?legacy_behavior str = | _, true, _, 'x' when legacy_behavior -> Int_Cx | _, true, _, 'X' when legacy_behavior -> Int_CX | _, true, _, 'o' when legacy_behavior -> Int_Co - | _, true, _, _ -> + | _, true, _, ('d' | 'i' | 'u') -> if legacy_behavior then (* ignore *) compute_int_conv pct_ind str_ind plus false space symb else incompatible_flag pct_ind str_ind symb "'#'" - | true, false, true, _ -> + | true, _, true, _ -> if legacy_behavior then (* plus and space: legacy implementation prefers plus *) compute_int_conv pct_ind str_ind plus sharp false symb else incompatible_flag pct_ind str_ind ' ' "'+'" - | false, false, true, _ -> + | false, _, true, _ -> if legacy_behavior then (* ignore *) compute_int_conv pct_ind str_ind plus sharp false symb else incompatible_flag pct_ind str_ind symb "' '" - | true, false, false, _ -> + | true, _, false, _ -> if legacy_behavior then (* ignore *) compute_int_conv pct_ind str_ind false sharp space symb else incompatible_flag pct_ind str_ind symb "'+'" - | false, false, false, _ -> assert false + | false, _, false, _ -> assert false (* Convert (plus, symb) to its associated float_conv. *) and compute_float_conv pct_ind str_ind plus space symb = diff --git a/stdlib/camlinternalFormatBasics.ml b/stdlib/camlinternalFormatBasics.ml index e51e4e2c..f45f434c 100644 --- a/stdlib/camlinternalFormatBasics.ml +++ b/stdlib/camlinternalFormatBasics.ml @@ -410,6 +410,9 @@ and ('a, 'b, 'c, 'd, 'e, 'f) fmt = | Scan_get_counter : (* %[nlNL] *) counter * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (int -> 'a, 'b, 'c, 'd, 'e, 'f) fmt + | Scan_next_char : (* %0c *) + ('a, 'b, 'c, 'd, 'e, 'f) fmt -> + (char -> 'a, 'b, 'c, 'd, 'e, 'f) fmt | Ignored_param : (* %_ *) ('a, 'b, 'c, 'd, 'y, 'x) ignored * ('x, 'b, 'c, 'y, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt @@ -453,6 +456,8 @@ and ('a, 'b, 'c, 'd, 'e, 'f) ignored = pad_option * char_set -> ('a, 'b, 'c, 'd, 'd, 'a) ignored | Ignored_scan_get_counter : (* %_[nlNL] *) counter -> ('a, 'b, 'c, 'd, 'd, 'a) ignored + | Ignored_scan_next_char : (* %_0c *) + ('a, 'b, 'c, 'd, 'd, 'a) ignored and ('a, 'b, 'c, 'd, 'e, 'f) format6 = Format of ('a, 'b, 'c, 'd, 'e, 'f) fmt * string @@ -602,6 +607,8 @@ fun fmt1 fmt2 -> match fmt1 with Scan_char_set (width_opt, char_set, concat_fmt rest fmt2) | Scan_get_counter (counter, rest) -> Scan_get_counter (counter, concat_fmt rest fmt2) + | Scan_next_char (rest) -> + Scan_next_char (concat_fmt rest fmt2) | Ignored_param (ign, rest) -> Ignored_param (ign, concat_fmt rest fmt2) diff --git a/stdlib/camlinternalFormatBasics.mli b/stdlib/camlinternalFormatBasics.mli index 52f428ad..4e579f3a 100644 --- a/stdlib/camlinternalFormatBasics.mli +++ b/stdlib/camlinternalFormatBasics.mli @@ -225,6 +225,11 @@ and ('a, 'b, 'c, 'd, 'e, 'f) fmt = | Scan_get_counter : (* %[nlNL] *) counter * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (int -> 'a, 'b, 'c, 'd, 'e, 'f) fmt +| Scan_next_char : (* %0c *) + ('a, 'b, 'c, 'd, 'e, 'f) fmt -> + (char -> 'a, 'b, 'c, 'd, 'e, 'f) fmt + (* %0c behaves as %c for printing, but when scanning it does not + consume the character from the input stream *) | Ignored_param : (* %_ *) ('a, 'b, 'c, 'd, 'y, 'x) ignored * ('x, 'b, 'c, 'y, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt @@ -265,6 +270,8 @@ and ('a, 'b, 'c, 'd, 'e, 'f) ignored = pad_option * char_set -> ('a, 'b, 'c, 'd, 'd, 'a) ignored | Ignored_scan_get_counter : counter -> ('a, 'b, 'c, 'd, 'd, 'a) ignored + | Ignored_scan_next_char : + ('a, 'b, 'c, 'd, 'd, 'a) ignored and ('a, 'b, 'c, 'd, 'e, 'f) format6 = Format of ('a, 'b, 'c, 'd, 'e, 'f) fmt * string diff --git a/stdlib/camlinternalMod.ml b/stdlib/camlinternalMod.ml index 5f1882a2..5265a712 100644 --- a/stdlib/camlinternalMod.ml +++ b/stdlib/camlinternalMod.ml @@ -67,5 +67,4 @@ let rec update_mod shape o n = for i = 0 to Array.length comps - 1 do update_mod comps.(i) (Obj.field o i) (Obj.field n i) done - | Value v -> - overwrite o n + | Value v -> () (* the value is already there *) diff --git a/stdlib/filename.mli b/stdlib/filename.mli index a4ea3aaa..c2cc6a48 100644 --- a/stdlib/filename.mli +++ b/stdlib/filename.mli @@ -117,7 +117,8 @@ val set_temp_dir_name : string -> unit @since 4.00.0 *) -val temp_dir_name : string [@@ocaml.deprecated] +val temp_dir_name : string + [@@ocaml.deprecated "Use Filename.get_temp_dir_name instead"] (** The name of the initial temporary directory: Under Unix, the value of the [TMPDIR] environment variable, or "/tmp" if the variable is not set. diff --git a/stdlib/format.mli b/stdlib/format.mli index b44fc0a9..541ffbe3 100644 --- a/stdlib/format.mli +++ b/stdlib/format.mli @@ -724,7 +724,7 @@ val bprintf : Buffer.t -> ('a, formatter, unit) format -> 'a use regular calls to [Format.fprintf] on formatter [to_b]. *) val kprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use Format.ksprintf instead."] ;; (** @deprecated An alias for [ksprintf]. *) @@ -734,7 +734,7 @@ val set_all_formatter_output_functions : newline:(unit -> unit) -> spaces:(int -> unit) -> unit -[@@ocaml.deprecated] +[@@ocaml.deprecated "Use Format.set_formatter_out_functions instead."] ;; (** @deprecated Subsumed by [set_formatter_out_functions]. *) @@ -745,14 +745,14 @@ val get_all_formatter_output_functions : (unit -> unit) * (unit -> unit) * (int -> unit) -[@@ocaml.deprecated] +[@@ocaml.deprecated "Use Format.get_formatter_out_functions instead."] ;; (** @deprecated Subsumed by [get_formatter_out_functions]. *) val pp_set_all_formatter_output_functions : formatter -> out:(string -> int -> int -> unit) -> flush:(unit -> unit) -> newline:(unit -> unit) -> spaces:(int -> unit) -> unit -[@@ocaml.deprecated] +[@@ocaml.deprecated "Use Format.pp_set_formatter_out_functions instead."] ;; (** @deprecated Subsumed by [pp_set_formatter_out_functions]. *) @@ -761,7 +761,7 @@ val pp_get_all_formatter_output_functions : formatter -> unit -> (string -> int -> int -> unit) * (unit -> unit) * (unit -> unit) * (int -> unit) -[@@ocaml.deprecated] +[@@ocaml.deprecated "Use Format.pp_get_formatter_out_functions instead."] ;; (** @deprecated Subsumed by [pp_get_formatter_out_functions]. *) diff --git a/stdlib/gc.mli b/stdlib/gc.mli index 8cd2a719..f86a1e68 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -83,7 +83,7 @@ type stat = type control = { mutable minor_heap_size : int; (** The size (in words) of the minor heap. Changing - this parameter will trigger a minor collection. Default: 32k. *) + this parameter will trigger a minor collection. Default: 256k. *) mutable major_heap_increment : int; (** How much to add to the major heap when increasing it. If this @@ -131,7 +131,7 @@ type control = mutable stack_limit : int; (** The maximum size of the stack (in words). This is only relevant to the byte-code runtime, as the native code runtime - uses the operating system's stack. Default: 256k. *) + uses the operating system's stack. Default: 1024k. *) mutable allocation_policy : int; (** The policy used for allocating in the heap. Possible diff --git a/stdlib/lazy.mli b/stdlib/lazy.mli index 6ade2e3d..f2541b7f 100644 --- a/stdlib/lazy.mli +++ b/stdlib/lazy.mli @@ -75,11 +75,14 @@ val is_val : 'a t -> bool;; did not raise an exception. @since 4.00.0 *) -val lazy_from_fun : (unit -> 'a) -> 'a t [@@ocaml.deprecated];; +val lazy_from_fun : (unit -> 'a) -> 'a t + [@@ocaml.deprecated "Use Lazy.from_fun instead."];; (** @deprecated synonym for [from_fun]. *) -val lazy_from_val : 'a -> 'a t [@@ocaml.deprecated];; +val lazy_from_val : 'a -> 'a t + [@@ocaml.deprecated "Use Lazy.from_val instead."];; (** @deprecated synonym for [from_val]. *) -val lazy_is_val : 'a t -> bool [@@ocaml.deprecated];; +val lazy_is_val : 'a t -> bool + [@@ocaml.deprecated "Use Lazy.is_val instead."];; (** @deprecated synonym for [is_val]. *) diff --git a/stdlib/obj.mli b/stdlib/obj.mli index 08b8a4f6..3395fa86 100644 --- a/stdlib/obj.mli +++ b/stdlib/obj.mli @@ -47,7 +47,8 @@ val string_tag : int (* both [string] and [bytes] *) val double_tag : int val double_array_tag : int val custom_tag : int -val final_tag : int [@@ocaml.deprecated] +val final_tag : int + [@@ocaml.deprecated "Replaced by custom_tag."] val int_tag : int val out_of_heap_tag : int @@ -60,5 +61,7 @@ val extension_slot : 'a -> t (** The following two functions are deprecated. Use module {!Marshal} instead. *) -val marshal : t -> bytes [@@ocaml.deprecated] -val unmarshal : bytes -> int -> t * int [@@ocaml.deprecated] +val marshal : t -> bytes + [@@ocaml.deprecated "Use Marshal.to_bytes instead."] +val unmarshal : bytes -> int -> t * int + [@@ocaml.deprecated "Use Marshal.from_bytes and Marshal.total_size instead."] diff --git a/stdlib/pervasives.mli b/stdlib/pervasives.mli index d471a4eb..64138291 100644 --- a/stdlib/pervasives.mli +++ b/stdlib/pervasives.mli @@ -130,7 +130,7 @@ external ( && ) : bool -> bool -> bool = "%sequand" [e2] is not evaluated at all. *) external ( & ) : bool -> bool -> bool = "%sequand" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use (&&) instead."] (** @deprecated {!Pervasives.( && )} should be used instead. *) external ( || ) : bool -> bool -> bool = "%sequor" @@ -139,7 +139,7 @@ external ( || ) : bool -> bool -> bool = "%sequor" [e2] is not evaluated at all. *) external ( or ) : bool -> bool -> bool = "%sequor" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use (||) instead."] (** @deprecated {!Pervasives.( || )} should be used instead.*) (** {6 Debugging} *) diff --git a/stdlib/printf.mli b/stdlib/printf.mli index 21e28159..4a725665 100644 --- a/stdlib/printf.mli +++ b/stdlib/printf.mli @@ -92,7 +92,9 @@ val fprintf : out_channel -> ('a, out_channel, unit) format -> 'a sign if positive. - space: for signed numerical conversions, prefix number with a space if positive. - - [#]: request an alternate formatting style for numbers. + - [#]: request an alternate formatting style for the hexadecimal + and octal integer types ([x], [X], [o], [lx], [lX], [lo], [Lx], + [LX], [Lo]). The optional [width] is an integer indicating the minimal width of the result. For instance, [%6d] prints an integer, diff --git a/stdlib/scanf.ml b/stdlib/scanf.ml index 2a63ced9..1372c41a 100644 --- a/stdlib/scanf.ml +++ b/stdlib/scanf.ml @@ -1032,6 +1032,7 @@ fun k fmt -> match fmt with | Scan_char_set (_, _, rest) -> take_format_readers k rest | Scan_get_counter (_, rest) -> take_format_readers k rest + | Scan_next_char rest -> take_format_readers k rest | Formatting_lit (_, rest) -> take_format_readers k rest | Formatting_gen (Open_tag (Format (fmt, _)), rest) -> take_format_readers k (concat_fmt fmt rest) @@ -1096,6 +1097,7 @@ fun k ign fmt -> match ign with | Ignored_format_subst (_, fmtty) -> take_fmtty_format_readers k fmtty fmt | Ignored_scan_char_set _ -> take_format_readers k fmt | Ignored_scan_get_counter _ -> take_format_readers k fmt + | Ignored_scan_next_char -> take_format_readers k fmt (******************************************************************************) (* Generic scanning *) @@ -1225,6 +1227,9 @@ fun ib fmt readers -> match fmt with | Scan_get_counter (counter, rest) -> let count = get_counter ib counter in Cons (count, make_scanf ib rest readers) + | Scan_next_char rest -> + let c = Scanning.checked_peek_char ib in + Cons (c, make_scanf ib rest readers) | Formatting_lit (formatting_lit, rest) -> String.iter (check_char ib) (string_of_formatting_lit formatting_lit); diff --git a/stdlib/sort.mli b/stdlib/sort.mli index a9be27e1..2da46cd7 100644 --- a/stdlib/sort.mli +++ b/stdlib/sort.mli @@ -20,13 +20,13 @@ *) val list : ('a -> 'a -> bool) -> 'a list -> 'a list - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use List.sort instead."] (** Sort a list in increasing order according to an ordering predicate. The predicate should return [true] if its first argument is less than or equal to its second argument. *) val array : ('a -> 'a -> bool) -> 'a array -> unit - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use Array.sort instead."] (** Sort an array in increasing order according to an ordering predicate. The predicate should return [true] if its first argument is @@ -34,7 +34,7 @@ val array : ('a -> 'a -> bool) -> 'a array -> unit The array is sorted in place. *) val merge : ('a -> 'a -> bool) -> 'a list -> 'a list -> 'a list - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use List.merge instead."] (** Merge two lists according to the given predicate. Assuming the two argument lists are sorted according to the predicate, [merge] returns a sorted list containing the elements diff --git a/stdlib/string.mli b/stdlib/string.mli index 8f1e178b..56065bbf 100644 --- a/stdlib/string.mli +++ b/stdlib/string.mli @@ -57,7 +57,7 @@ external get : string -> int -> char = "%string_safe_get" external set : bytes -> int -> char -> unit = "%string_safe_set" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use Bytes.set instead."] (** [String.set s n c] modifies byte sequence [s] in place, replacing the byte at index [n] with [c]. You can also write [s.[n] <- c] instead of [String.set s n c]. @@ -66,7 +66,8 @@ external set : bytes -> int -> char -> unit = "%string_safe_set" @deprecated This is a deprecated alias of {!Bytes.set}.[ ] *) -external create : int -> bytes = "caml_create_string" [@@ocaml.deprecated] +external create : int -> bytes = "caml_create_string" + [@@ocaml.deprecated "Use Bytes.create instead."] (** [String.create n] returns a fresh byte sequence of length [n]. The sequence is uninitialized and contains arbitrary bytes. @@ -104,7 +105,8 @@ val sub : string -> int -> int -> string Raise [Invalid_argument] if [start] and [len] do not designate a valid substring of [s]. *) -val fill : bytes -> int -> int -> char -> unit [@@ocaml.deprecated] +val fill : bytes -> int -> int -> char -> unit + [@@ocaml.deprecated "Use Bytes.fill instead."] (** [String.fill s start len c] modifies byte sequence [s] in place, replacing [len] bytes with [c], starting at [start]. diff --git a/stdlib/stringLabels.mli b/stdlib/stringLabels.mli index 1cf5d51e..6f6f997e 100644 --- a/stdlib/stringLabels.mli +++ b/stdlib/stringLabels.mli @@ -23,22 +23,23 @@ external get : string -> int -> char = "%string_safe_get" Raise [Invalid_argument] if [n] not a valid index in [s]. *) external set : bytes -> int -> char -> unit = "%string_safe_set" - [@@ocaml.deprecated] + [@@ocaml.deprecated "Use BytesLabels.set instead."] (** [String.set s n c] modifies byte sequence [s] in place, replacing the byte at index [n] with [c]. You can also write [s.[n] <- c] instead of [String.set s n c]. Raise [Invalid_argument] if [n] is not a valid index in [s]. - @deprecated This is a deprecated alias of {!Bytes.set}. *) + @deprecated This is a deprecated alias of {!BytesLabels.set}. *) -external create : int -> bytes = "caml_create_string" [@@ocaml.deprecated] +external create : int -> bytes = "caml_create_string" + [@@ocaml.deprecated "Use BytesLabels.create instead."] (** [String.create n] returns a fresh byte sequence of length [n]. The sequence is uninitialized and contains arbitrary bytes. Raise [Invalid_argument] if [n < 0] or [n > ]{!Sys.max_string_length}. - @deprecated This is a deprecated alias of {!Bytes.create}. *) + @deprecated This is a deprecated alias of {!BytesLabels.create}. *) val make : int -> char -> string (** [String.make n c] returns a fresh string of length [n], @@ -63,14 +64,15 @@ val sub : string -> pos:int -> len:int -> string Raise [Invalid_argument] if [start] and [len] do not designate a valid substring of [s]. *) -val fill : bytes -> pos:int -> len:int -> char -> unit [@@ocaml.deprecated] +val fill : bytes -> pos:int -> len:int -> char -> unit + [@@ocaml.deprecated "Use BytesLabels.fill instead."] (** [String.fill s start len c] modifies byte sequence [s] in place, replacing [len] bytes by [c], starting at [start]. Raise [Invalid_argument] if [start] and [len] do not designate a valid substring of [s]. - @deprecated This is a deprecated alias of {!Bytes.fill}. *) + @deprecated This is a deprecated alias of {!BytesLabels.fill}. *) val blit : src:string -> src_pos:int -> dst:bytes -> dst_pos:int -> len:int diff --git a/testsuite/tests/backtrace/Makefile b/testsuite/tests/backtrace/Makefile index 1ca390f9..33ca1ed8 100644 --- a/testsuite/tests/backtrace/Makefile +++ b/testsuite/tests/backtrace/Makefile @@ -16,6 +16,7 @@ EXECNAME=program$(EXE) ABCDFILES=backtrace.ml OTHERFILES=backtrace2.ml raw_backtrace.ml \ backtrace_deprecated.ml backtrace_slots.ml +OTHERFILESNOINLINING=backtraces_and_finalizers.ml default: $(MAKE) byte @@ -69,6 +70,16 @@ native: >$$F.native.result 2>&1; \ $(DIFF) $$F.reference $$F.native.result >/dev/null \ && echo " => passed" || echo " => failed"; \ + done; + @for file in $(OTHERFILESNOINLINING); do \ + rm -f program program.exe; \ + $(OCAMLOPT) -inline 0 -g -o $(EXECNAME) $$file; \ + printf " ... testing '$$file' with ocamlopt:"; \ + F="`basename $$file .ml`"; \ + (OCAMLRUNPARAM=b=1 ./$(EXECNAME) $$arg || true) \ + >$$F.native.result 2>&1; \ + $(DIFF) $$F.reference $$F.native.result >/dev/null \ + && echo " => passed" || echo " => failed"; \ done .PHONY: promote diff --git a/testsuite/tests/backtrace/backtraces_and_finalizers.ml b/testsuite/tests/backtrace/backtraces_and_finalizers.ml new file mode 100644 index 00000000..22acf1af --- /dev/null +++ b/testsuite/tests/backtrace/backtraces_and_finalizers.ml @@ -0,0 +1,25 @@ +let () = Printexc.record_backtrace true + +let finaliser _ = try raise Exit with _ -> () + +let create () = + let x = ref () in + Gc.finalise finaliser x; + x + +let f () = raise Exit + +let () = + let minor_size = (Gc.get ()).Gc.minor_heap_size in + for i = 1 to 100 do + Gc.minor (); + try + ignore (create () : unit ref); + f () + with _ -> + for i = 1 to minor_size / 2 - 1 do + ignore (ref ()) + done; + ignore (Printexc.get_backtrace () : string) + done; + Printf.printf "ok\n" diff --git a/testsuite/tests/backtrace/backtraces_and_finalizers.reference b/testsuite/tests/backtrace/backtraces_and_finalizers.reference new file mode 100644 index 00000000..9766475a --- /dev/null +++ b/testsuite/tests/backtrace/backtraces_and_finalizers.reference @@ -0,0 +1 @@ +ok diff --git a/testsuite/tests/formats-transition/invalid_formats.ml b/testsuite/tests/formats-transition/invalid_formats.ml new file mode 100644 index 00000000..16697ca9 --- /dev/null +++ b/testsuite/tests/formats-transition/invalid_formats.ml @@ -0,0 +1,67 @@ +(***********************************************************************) +(* *) +(* OCaml *) +(* *) +(* Damien Doligez, EPI Gallium, INRIA Rocquencourt *) +(* *) +(* Copyright 2014 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + +(* WARNING: this file MUST NOT be merged into the trunk, it is for the + 4.02 branch only, to test compatibility with the old implementation + of printf. Starting with 4.03, all these formats will be statically + refused by the compiler. +*) + +open Printf;; + +let show arg f = + printf "%8s --> |" (string_of_format f); + printf f arg; + printf "|\n"; +in + + List.iter (show 12.3) [ + "%0.3f"; + "%0.f"; + "%+ .3f"; + "%.f"; + "%3.f"; + "%-9.f"; + "%0.16g"; + ]; + + List.iter (show "ab") [ + "%.30s"; + "%-.30s"; + "%-s"; + "%0s"; + "%03s"; + "% s"; + ]; + + List.iter (show 4) [ + "%0.3d"; + "%0X"; + "%0x"; + ]; + + List.iter (show 'a') [ + "%5c"; + ]; +;; + +let fmt = format_of_string "%0.*f" in +printf "%8s --> |" (string_of_format fmt); +printf fmt 3 12.3; +printf "|\n"; +;; + +let fmt = format_of_string "%.2%" in +printf "%8s --> |" (string_of_format fmt); +printf fmt; +printf "|\n"; +;; diff --git a/testsuite/tests/formats-transition/invalid_formats.ml.reference b/testsuite/tests/formats-transition/invalid_formats.ml.reference new file mode 100644 index 00000000..65881b42 --- /dev/null +++ b/testsuite/tests/formats-transition/invalid_formats.ml.reference @@ -0,0 +1,24 @@ + +# * * * * # %0.3f --> |12.300| + %0.f --> |12| + %+ .3f --> |+12.300| + %.f --> |12| + %3.f --> | 12| + %-9.f --> |12 | + %0.16g --> |12.3| + %.30s --> | ab| + %-.30s --> |ab | + %-s --> |ab| + %0s --> |ab| + %03s --> | ab| + % s --> |ab| + %0.3d --> |004| + %0X --> |4| + %0x --> |4| + %5c --> |a| +- : unit = () +# %0.*f --> |12.300| +- : unit = () +# %.2% --> |%| +- : unit = () +# diff --git a/testsuite/tests/lib-dynlink-native/Makefile b/testsuite/tests/lib-dynlink-native/Makefile index 54126ff5..f4f9d099 100644 --- a/testsuite/tests/lib-dynlink-native/Makefile +++ b/testsuite/tests/lib-dynlink-native/Makefile @@ -49,7 +49,7 @@ run: main$(EXE): api.cmx main.cmx @$(OCAMLOPT) -thread -o main$(EXE) -linkall unix.cmxa threads.cmxa \ - dynlink.cmxa api.cmx main.cmx $(PTHREAD_LINK) + dynlink.cmxa api.cmx main.cmx main_ext$(EXE): api.cmx main.cmx factorial.$(O) @$(OCAMLOPT) -o main_ext$(EXE) dynlink.cmxa api.cmx main.cmx \ diff --git a/testsuite/tests/lib-format/Makefile b/testsuite/tests/lib-format/Makefile index 7a6297b6..9805d2db 100644 --- a/testsuite/tests/lib-format/Makefile +++ b/testsuite/tests/lib-format/Makefile @@ -10,11 +10,8 @@ # # ######################################################################### -MAIN_MODULE=tformat -ADD_COMPFLAGS=-I $(OTOPDIR)/testsuite/lib -ADD_MODULES=testing - BASEDIR=../.. +MODULES=testing -include $(BASEDIR)/makefiles/Makefile.one +include $(BASEDIR)/makefiles/Makefile.several include $(BASEDIR)/makefiles/Makefile.common diff --git a/testsuite/tests/lib-format/tformat.ml b/testsuite/tests/lib-format/tformat.ml index a627b47f..13c6094b 100644 --- a/testsuite/tests/lib-format/tformat.ml +++ b/testsuite/tests/lib-format/tformat.ml @@ -31,6 +31,7 @@ try test (sprintf "% d/% i" 42 43 = " 42/ 43"); test (sprintf "%#d/%#i" 42 43 = "42/43"); test (sprintf "%4d/%5i" 42 43 = " 42/ 43"); + test (sprintf "%*d" (-4) 42 = "42 "); test (sprintf "%*d/%*i" 4 42 5 43 = " 42/ 43"); test (sprintf "%-0+#4d/%-0 #5i" 42 43 = "+42 / 43 "); @@ -42,6 +43,7 @@ try test (sprintf "% d/% i" (-42) (-43) = "-42/-43"); test (sprintf "%#d/%#i" (-42) (-43) = "-42/-43"); test (sprintf "%4d/%5i" (-42) (-43) = " -42/ -43"); + test (sprintf "%*d" (-4) (-42) = "-42 "); test (sprintf "%*d/%*i" 4 (-42) 5 (-43) = " -42/ -43"); test (sprintf "%-0+ #4d/%-0+ #5i" (-42) (-43) = "-42 /-43 "); @@ -54,7 +56,7 @@ try test (sprintf "%#u" 42 = "42"); test (sprintf "%4u" 42 = " 42"); test (sprintf "%*u" 4 42 = " 42"); - test (sprintf "%-0+ #6d" 42 = "+42 "); + test (sprintf "%*u" (-4) 42 = "42 "); say "\nu negative\n%!"; begin match Sys.word_size with @@ -74,6 +76,10 @@ try test (sprintf "%#x" 42 = "0x2a"); test (sprintf "%4x" 42 = " 2a"); test (sprintf "%*x" 5 42 = " 2a"); + test (sprintf "%*x" (-5) 42 = "2a "); + test (sprintf "%#*x" 5 42 = " 0x2a"); + test (sprintf "%#*x" (-5) 42 = "0x2a "); + test (sprintf "%#-*x" 5 42 = "0x2a "); test (sprintf "%-0+ #*x" 5 42 = "0x2a "); say "\nx negative\n%!"; @@ -135,6 +141,7 @@ try test (sprintf "%5s" "foo" = " foo"); test (sprintf "%1s" "foo" = "foo"); test (sprintf "%*s" 6 "foo" = " foo"); + test (sprintf "%*s" (-6) "foo" = "foo "); test (sprintf "%*s" 2 "foo" = "foo"); test (sprintf "%-0+ #5s" "foo" = "foo "); test (sprintf "%s@@" "foo" = "foo@"); @@ -143,16 +150,19 @@ try say "\nS\n%!"; test (sprintf "%S" "fo\"o" = "\"fo\\\"o\""); -(* test (sprintf "%-5S" "foo" = "\"foo\" "); padding not done *) -(* test (sprintf "%05S" "foo" = " \"foo\""); padding not done *) + test (sprintf "%-7S" "foo" = "\"foo\" "); +(* test (sprintf "%07S" "foo" = " \"foo\""); *) + (* %S is incompatible with '0' *) test (sprintf "%+S" "foo" = "\"foo\""); test (sprintf "% S" "foo" = "\"foo\""); test (sprintf "%#S" "foo" = "\"foo\""); -(* test (sprintf "%5S" "foo" = " \"foo\""); padding not done *) + test (sprintf "%7S" "foo" = " \"foo\""); test (sprintf "%1S" "foo" = "\"foo\""); -(* test (sprintf "%*S" 6 "foo" = " \"foo\""); padding not done *) + test (sprintf "%*S" 8 "foo" = " \"foo\""); + test (sprintf "%*S" (-8) "foo" = "\"foo\" "); test (sprintf "%*S" 2 "foo" = "\"foo\""); (* test (sprintf "%-0+ #5S" "foo" = "\"foo\" "); padding not done *) + (* %S is incompatible with '0','+' and ' ' *) test (sprintf "%S@@" "foo" = "\"foo\"@"); test (sprintf "%S@@inria.fr" "foo" = "\"foo\"@inria.fr"); test (sprintf "%S@@%S" "foo" "inria.fr" = "\"foo\"@\"inria.fr\""); @@ -229,7 +239,13 @@ try test (sprintf "%F" 42.42e42 =* "4.242e+43"); test (sprintf "%F" 42.00 = "42."); test (sprintf "%F" 0.042 = "0.042"); -(* no padding, no precision + test (sprintf "%4F" 3. = " 3."); + test (sprintf "%-4F" 3. = "3. "); + test (sprintf "%04F" 3. = "003."); +(* plus-padding unsupported + test (sprintf "%+4F" 3. = " +3."); +*) +(* no precision test (sprintf "%.3F" 42.42 = "42.420"); test (sprintf "%12.3F" 42.42e42 = " 4.242e+43"); test (sprintf "%.3F" 42.00 = "42.000"); @@ -297,6 +313,8 @@ try say "\nB\n%!"; test (sprintf "%B" true = "true"); test (sprintf "%B" false = "false"); + (* test (sprintf "%8B" false = " false"); *) + (* padding not done *) say "\nld/li positive\n%!"; test (sprintf "%ld/%li" 42l 43l = "42/43"); @@ -485,8 +503,8 @@ try test (sprintf "@@" = "@"); test (sprintf "@@@@" = "@@"); test (sprintf "@@%%" = "@%"); - say "\nend of tests\n%!"; + with e -> say "unexpected exception: %s\n%!" (Printexc.to_string e); test false; diff --git a/testsuite/tests/lib-format/tformat.reference b/testsuite/tests/lib-format/tformat.reference index 387dfb85..cf2b241c 100644 --- a/testsuite/tests/lib-format/tformat.reference +++ b/testsuite/tests/lib-format/tformat.reference @@ -1,91 +1,91 @@ d/i positive - 0 1 2 3 4 5 6 7 8 + 0 1 2 3 4 5 6 7 8 9 d/i negative - 9 10 11 12 13 14 15 16 17 + 10 11 12 13 14 15 16 17 18 19 u positive - 18 19 20 21 22 23 24 25 26 + 20 21 22 23 24 25 26 27 28 u negative - 27 + 29 x positive - 28 29 30 31 32 33 34 35 36 + 30 31 32 33 34 35 36 37 38 39 40 41 42 x negative - 37 + 43 X positive - 38 39 40 41 42 43 44 45 46 + 44 45 46 47 48 49 50 51 52 x negative - 47 + 53 o positive - 48 49 50 51 52 53 54 55 56 + 54 55 56 57 58 59 60 61 62 o negative - 57 + 63 s - 58 59 60 61 62 63 64 65 66 67 68 69 70 71 + 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 S - 72 73 74 75 76 77 78 79 80 + 79 80 81 82 83 84 85 86 87 88 89 90 91 c - 81 82 83 84 + 92 93 94 95 C - 85 86 87 88 89 + 96 97 98 99 100 f - 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 + 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 F - 108 109 110 111 + 119 120 121 122 123 124 125 e - 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 + 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 E - 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 + 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 B - 148 149 + 162 163 ld/li positive - 150 151 152 153 154 155 156 157 158 + 164 165 166 167 168 169 170 171 172 ld/li negative - 159 160 161 162 163 164 165 166 167 + 173 174 175 176 177 178 179 180 181 lu positive - 168 169 170 171 172 173 174 175 176 + 182 183 184 185 186 187 188 189 190 lu negative - 177 + 191 lx positive - 178 179 180 181 182 183 184 185 186 + 192 193 194 195 196 197 198 199 200 lx negative - 187 + 201 lX positive - 188 189 190 191 192 193 194 195 196 + 202 203 204 205 206 207 208 209 210 lx negative - 197 + 211 lo positive - 198 199 200 201 202 203 204 205 206 + 212 213 214 215 216 217 218 219 220 lo negative - 207 + 221 Ld/Li positive - 208 209 210 211 212 213 214 215 216 + 222 223 224 225 226 227 228 229 230 Ld/Li negative - 217 218 219 220 221 222 223 224 225 + 231 232 233 234 235 236 237 238 239 Lu positive - 226 227 228 229 230 231 232 233 234 + 240 241 242 243 244 245 246 247 248 Lu negative - 235 + 249 Lx positive - 236 237 238 239 240 241 242 243 244 + 250 251 252 253 254 255 256 257 258 Lx negative - 245 + 259 LX positive - 246 247 248 249 250 251 252 253 254 + 260 261 262 263 264 265 266 267 268 Lx negative - 255 + 269 Lo positive - 256 257 258 259 260 261 262 263 264 + 270 271 272 273 274 275 276 277 278 Lo negative - 265 + 279 a - 266 + 280 t - 267 + 281 {...%} - 268 + 282 (...%) - 269 + 283 ! % @ , and constants - 270 271 272 273 274 275 276 + 284 285 286 287 288 289 290 end of tests All tests succeeded. diff --git a/testsuite/tests/lib-printf/Makefile b/testsuite/tests/lib-printf/Makefile index dc31633e..4a74a3fd 100644 --- a/testsuite/tests/lib-printf/Makefile +++ b/testsuite/tests/lib-printf/Makefile @@ -10,11 +10,8 @@ # # ######################################################################### -#MODULES= -MAIN_MODULE=tprintf -ADD_COMPFLAGS=-I $(OTOPDIR)/testsuite/lib -ADD_MODULES=testing - +MODULES=testing BASEDIR=../.. -include $(BASEDIR)/makefiles/Makefile.one + +include $(BASEDIR)/makefiles/Makefile.several include $(BASEDIR)/makefiles/Makefile.common diff --git a/testsuite/tests/lib-printf/pr6534.ml b/testsuite/tests/lib-printf/pr6534.ml new file mode 100644 index 00000000..a356d521 --- /dev/null +++ b/testsuite/tests/lib-printf/pr6534.ml @@ -0,0 +1,19 @@ +(* these are not valid under -strict-formats, but we test them here + for backward-compatibility *) +open Printf + +let () = + printf "1 [%.5s]\n" "foo"; + printf "2 [%.*s]\n" 5 "foo"; + printf "3 [%.-5s]\n" "foo"; + printf "4 [%-.5s]\n" "foo"; + printf "5 [%-.*s]\n" 5 "foo"; + printf "6 [%.*s]\n" (-5) "foo"; + + printf "1 [%.7S]\n" "foo"; + printf "2 [%.*S]\n" 7 "foo"; + printf "3 [%.-7S]\n" "foo"; + printf "4 [%-.7S]\n" "foo"; + printf "5 [%-.*S]\n" 7 "foo"; + printf "6 [%.*S]\n" (-7) "foo"; + () diff --git a/testsuite/tests/lib-printf/pr6534.reference b/testsuite/tests/lib-printf/pr6534.reference new file mode 100644 index 00000000..c3e2a7ff --- /dev/null +++ b/testsuite/tests/lib-printf/pr6534.reference @@ -0,0 +1,14 @@ +1 [ foo] +2 [ foo] +3 [foo ] +4 [foo ] +5 [foo ] +6 [foo ] +1 [ "foo"] +2 [ "foo"] +3 ["foo" ] +4 ["foo" ] +5 ["foo" ] +6 ["foo" ] + +All tests succeeded. diff --git a/testsuite/tests/lib-printf/tprintf.ml b/testsuite/tests/lib-printf/tprintf.ml index 2922f8e3..cb4ee657 100644 --- a/testsuite/tests/lib-printf/tprintf.ml +++ b/testsuite/tests/lib-printf/tprintf.ml @@ -30,6 +30,7 @@ try (*test (sprintf "%#d/%#i" 42 43 = "42/43");*) (* >> '#' is incompatible with 'd' *) test (sprintf "%4d/%5i" 42 43 = " 42/ 43"); + test (sprintf "%*d" (-4) 42 = "42 "); test (sprintf "%*d/%*i" 4 42 5 43 = " 42/ 43"); (*test (sprintf "%-0+#4d/%-0 #5i" 42 43 = "+42 / 43 ");*) (* >> '#' is incompatible with 'd' *) @@ -43,6 +44,7 @@ try (*test (sprintf "%#d/%#i" (-42) (-43) = "-42/-43");*) (* >> '#' is incompatible with 'd' *) test (sprintf "%4d/%5i" (-42) (-43) = " -42/ -43"); + test (sprintf "%*d" (-4) (-42) = "-42 "); test (sprintf "%*d/%*i" 4 (-42) 5 (-43) = " -42/ -43"); (*test (sprintf "%-0+ #4d/%-0+ #5i" (-42) (-43) = "-42 /-43 ");*) (* >> '0' is incompatible with '-', '#' is incompatible with 'd' *) @@ -59,8 +61,7 @@ try (* >> '#' is incompatible with 'u' *) test (sprintf "%4u" 42 = " 42"); test (sprintf "%*u" 4 42 = " 42"); - (*test (sprintf "%-0+ #6d" 42 = "+42 ");*) - (* >> '-' is incompatible with '0', '#' is incompatible with 'd' *) + test (sprintf "%*u" (-4) 42 = "42 "); printf "\nu negative\n%!"; begin match Sys.word_size with @@ -82,8 +83,11 @@ try test (sprintf "%#x" 42 = "0x2a"); test (sprintf "%4x" 42 = " 2a"); test (sprintf "%*x" 5 42 = " 2a"); - (*test (sprintf "%-0+ #*x" 5 42 = "0x2a ");*) - (* >> '-' is incompatible with '0' *) + test (sprintf "%*x" (-5) 42 = "2a "); + test (sprintf "%#*x" 5 42 = " 0x2a"); + test (sprintf "%#*x" (-5) 42 = "0x2a "); + test (sprintf "%#-*x" 5 42 = "0x2a "); + test (sprintf "%-0+ #*x" 5 42 = "0x2a "); printf "\nx negative\n%!"; begin match Sys.word_size with @@ -154,6 +158,7 @@ try test (sprintf "%5s" "foo" = " foo"); test (sprintf "%1s" "foo" = "foo"); test (sprintf "%*s" 6 "foo" = " foo"); + test (sprintf "%*s" (-6) "foo" = "foo "); test (sprintf "%*s" 2 "foo" = "foo"); (*test (sprintf "%-0+ #5s" "foo" = "foo ");*) (* >> '-' is incompatible with '0', '#' is incompatible with 's' *) @@ -173,7 +178,8 @@ try (* >> '#' is incompatible with 'S' *) (* test (sprintf "%5S" "foo" = " \"foo\""); padding not done *) test (sprintf "%1S" "foo" = "\"foo\""); -(* test (sprintf "%*S" 6 "foo" = " \"foo\""); padding not done *) + test (sprintf "%*S" 8 "foo" = " \"foo\""); + test (sprintf "%*S" (-8) "foo" = "\"foo\" "); test (sprintf "%*S" 2 "foo" = "\"foo\""); (* test (sprintf "%-0+ #5S" "foo" = "\"foo\" "); padding not done *) test (sprintf "%S@" "foo" = "\"foo\"@"); @@ -222,6 +228,11 @@ try (*test (sprintf "%-0+ #12f" 42.42 = "+42.420000 ");*) (* >> '-' is incompatible with '0', '#' is incompatible with 'f' *) test (sprintf "%.3f" (-42.42) = "-42.420"); + test (sprintf "%.*f" (-3) 42.42 = "42.420"); + (* dynamically-provided negative precisions are currently silently + turned into their absolute value; we could error on this + in the future (the behavior is unspecified), but the previous + buggy output "%.0-3f-" is not desirable. *) test (sprintf "%-13.3f" (-42.42) = "-42.420 "); test (sprintf "%013.3f" (-42.42) = "-00000042.420"); test (sprintf "%+.3f" 42.42 = "+42.420"); @@ -262,7 +273,13 @@ try test (sprintf "%F" 42.42e42 =* "4.242e+43"); test (sprintf "%F" 42.00 = "42."); test (sprintf "%F" 0.042 = "0.042"); -(* no padding, no precision + test (sprintf "%4F" 3. = " 3."); + test (sprintf "%-4F" 3. = "3. "); + test (sprintf "%04F" 3. = "003."); +(* plus-padding unsupported + test (sprintf "%+4F" 3. = " +3."); +*) +(* no precision test (sprintf "%.3F" 42.42 = "42.420"); test (sprintf "%12.3F" 42.42e42 = " 4.242e+43"); test (sprintf "%.3F" 42.00 = "42.000"); diff --git a/testsuite/tests/lib-printf/tprintf.reference b/testsuite/tests/lib-printf/tprintf.reference index 11ee3a74..3a6c3f0d 100644 --- a/testsuite/tests/lib-printf/tprintf.reference +++ b/testsuite/tests/lib-printf/tprintf.reference @@ -1,91 +1,91 @@ d/i positive - 0 1 2 3 4 5 6 + 0 1 2 3 4 5 6 7 d/i negative - 7 8 9 10 11 12 13 + 8 9 10 11 12 13 14 15 u positive - 14 15 16 17 18 + 16 17 18 19 20 21 u negative - 19 + 22 x positive - 20 21 22 23 24 25 + 23 24 25 26 27 28 29 30 31 32 33 x negative - 26 + 34 X positive - 27 28 29 30 31 32 + 35 36 37 38 39 40 x negative - 33 + 41 o positive - 34 35 36 37 38 39 + 42 43 44 45 46 47 o negative - 40 + 48 s - 41 42 43 44 45 46 47 48 49 + 49 50 51 52 53 54 55 56 57 58 S - 50 51 52 53 54 55 + 59 60 61 62 63 64 65 66 c - 56 + 67 C - 57 58 + 68 69 f - 59 60 61 62 63 64 65 66 67 68 69 70 71 72 + 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 F - 73 74 75 76 + 85 86 87 88 89 90 91 e - 77 78 79 80 81 82 83 84 85 86 87 88 89 90 + 92 93 94 95 96 97 98 99 100 101 102 103 104 105 E - 91 92 93 94 95 96 97 98 99 100 101 102 103 104 + 106 107 108 109 110 111 112 113 114 115 116 117 118 119 B - 105 106 + 120 121 ld/li positive - 107 108 109 110 111 112 113 + 122 123 124 125 126 127 128 ld/li negative - 114 115 116 117 118 119 120 + 129 130 131 132 133 134 135 lu positive - 121 122 123 124 125 + 136 137 138 139 140 lu negative - 126 + 141 lx positive - 127 128 129 130 131 132 + 142 143 144 145 146 147 lx negative - 133 + 148 lX positive - 134 135 136 137 138 139 + 149 150 151 152 153 154 lx negative - 140 + 155 lo positive - 141 142 143 144 145 146 + 156 157 158 159 160 161 lo negative - 147 + 162 Ld/Li positive - 148 149 150 151 152 + 163 164 165 166 167 Ld/Li negative - 153 154 155 156 157 + 168 169 170 171 172 Lu positive - 158 159 160 161 162 + 173 174 175 176 177 Lu negative - 163 + 178 Lx positive - 164 165 166 167 168 169 + 179 180 181 182 183 184 Lx negative - 170 + 185 LX positive - 171 172 173 174 175 176 + 186 187 188 189 190 191 Lx negative - 177 + 192 Lo positive - 178 179 180 181 182 183 + 193 194 195 196 197 198 Lo negative - 184 + 199 a - 185 + 200 t - 186 + 201 {...%} - 187 + 202 (...%) - 188 + 203 ! % @ , and constants - 189 190 191 192 193 194 195 + 204 205 206 207 208 209 210 end of tests All tests succeeded. diff --git a/testsuite/tests/lib-scanf/tscanf.ml b/testsuite/tests/lib-scanf/tscanf.ml index 8e6a252b..33054b66 100644 --- a/testsuite/tests/lib-scanf/tscanf.ml +++ b/testsuite/tests/lib-scanf/tscanf.ml @@ -1439,6 +1439,8 @@ let test58 () = test (test58 ()) ;; +(* skip test number "59" which is commented below *) +let () = test (true);; (* let test59 () = ;; @@ -1470,3 +1472,15 @@ let scan_record scan_field ib = let scan_field ib = bscanf ib "%s = %[^;]" (fun finame ficont -> finame, ficont);; *) + +(* testing formats that do not consume their input *) +let test60 () = + sscanf "abc" "%0c%0c%c%n" (fun c1 c2 c3 n -> + c1 = 'a' && c2 = 'a' && c3 = 'a' && n = 1) + && + sscanf "abc" "%0s%s" (fun s1 s2 -> s1 = "" && s2 = "abc") + && + sscanf "abc" "%1s%s" (fun s1 s2 -> s1 = "a" && s2 = "bc") +;; + +test (test60 ()); diff --git a/testsuite/tests/lib-scanf/tscanf.reference b/testsuite/tests/lib-scanf/tscanf.reference index 18fe92ba..5b2859cb 100644 --- a/testsuite/tests/lib-scanf/tscanf.reference +++ b/testsuite/tests/lib-scanf/tscanf.reference @@ -1,2 +1,2 @@ - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 All tests succeeded. diff --git a/testsuite/tests/tool-debugger/basic/Makefile b/testsuite/tests/tool-debugger/basic/Makefile index f95b4803..3c171390 100644 --- a/testsuite/tests/tool-debugger/basic/Makefile +++ b/testsuite/tests/tool-debugger/basic/Makefile @@ -10,7 +10,7 @@ # # ######################################################################### -BASEDIR=../.. +BASEDIR=../../.. MAIN_MODULE=debuggee ADD_COMPFLAGS=-g -custom LD_PATH=$(TOPDIR)/otherlibs/$(UNIXLIBVAR)unix diff --git a/testsuite/tests/tool-debugger/no_debug_event/.ignore b/testsuite/tests/tool-debugger/no_debug_event/.ignore new file mode 100644 index 00000000..cfbcf5c6 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/.ignore @@ -0,0 +1,4 @@ +compiler-libs +out +c +c.exe diff --git a/testsuite/tests/tool-debugger/no_debug_event/Makefile b/testsuite/tests/tool-debugger/no_debug_event/Makefile new file mode 100644 index 00000000..c9a08d25 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/Makefile @@ -0,0 +1,57 @@ +######################################################################### +# # +# OCaml # +# # +# Damien Doligez, EPI Gallium, INRIA Rocquencourt # +# # +# Copyright 2013 Institut National de Recherche en Informatique et # +# en Automatique. All rights reserved. This file is distributed # +# under the terms of the Q Public License version 1.0. # +# # +######################################################################### + +BASEDIR=../../.. +ADD_COMPFLAGS=-g -custom +LD_PATH=$(TOPDIR)/otherlibs/$(UNIXLIBVAR)unix + +.PHONY: default +default: + @if ! $(SUPPORTS_SHARED_LIBRARIES); then \ + echo 'skipped (shared libraries not available)'; \ + else \ + $(MAKE) compile; \ + $(SET_LD_PATH) OCAMLLIB=. $(MAKE) run; \ + fi + +.PHONY: compile +compile: $(ML_FILES) $(CMO_FILES) + @rm -f c$(EXE) + @$(OCAMLC) $(ADD_COMPFLAGS) -c a.ml -for-pack foo + @$(OCAMLC) $(ADD_COMPFLAGS) a.cmo -pack -o foo.cmo + @$(OCAMLC) $(ADD_COMPFLAGS) -c b.ml + @$(OCAMLC) $(ADD_COMPFLAGS) foo.cmo b.cmo -o c$(EXE) + @mkdir -p compiler-libs + @cp $(TOPDIR)/toplevel/topdirs.cmi compiler-libs/ + +.PHONY: run +run: + @printf " ... testing with ocamlc" + @rm -f noev.result + @echo 'source input_script' | \ + $(OCAMLRUN) `$(CYGPATH) $(TOPDIR)/debugger/ocamldebug$(EXE)` \ + c$(EXE) >noev.raw.result 2>&1 \ + && sed -e '/Debugger version/d' -e '/^Time:/d' \ + -e '/Breakpoint [0-9]* at [0-9]*:/d' -e '$$d' \ + noev.raw.result >noev.result \ + && $(DIFF) noev.reference noev.result >/dev/null \ + && echo " => passed" || echo " => failed" + +.PHONY: promote +promote: defaultpromote + +.PHONY: clean +clean: defaultclean + @rm -f *.result *.cm* c$(EXE) + @rm -rf compiler-libs + +include $(BASEDIR)/makefiles/Makefile.common diff --git a/testsuite/tests/tool-debugger/no_debug_event/a.ml b/testsuite/tests/tool-debugger/no_debug_event/a.ml new file mode 100644 index 00000000..0547b3d0 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/a.ml @@ -0,0 +1 @@ +let x = 1 diff --git a/testsuite/tests/tool-debugger/no_debug_event/b.ml b/testsuite/tests/tool-debugger/no_debug_event/b.ml new file mode 100644 index 00000000..83502097 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/b.ml @@ -0,0 +1,3 @@ +let () = + print_int Foo.A.x; + print_newline () diff --git a/testsuite/tests/tool-debugger/no_debug_event/input_script b/testsuite/tests/tool-debugger/no_debug_event/input_script new file mode 100644 index 00000000..58afc787 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/input_script @@ -0,0 +1,2 @@ +run +quit diff --git a/testsuite/tests/tool-debugger/no_debug_event/noev.reference b/testsuite/tests/tool-debugger/no_debug_event/noev.reference new file mode 100644 index 00000000..d4a69fc9 --- /dev/null +++ b/testsuite/tests/tool-debugger/no_debug_event/noev.reference @@ -0,0 +1,4 @@ + +(ocd) Loading program... done. +1 +Program exit. diff --git a/testsuite/tests/typing-extensions/open_types.ml.reference b/testsuite/tests/typing-extensions/open_types.ml.reference index 5fb9684d..841a94ba 100644 --- a/testsuite/tests/typing-extensions/open_types.ml.reference +++ b/testsuite/tests/typing-extensions/open_types.ml.reference @@ -76,7 +76,9 @@ Error: Signature mismatch: ^^^^^^^^^^^^^^^^^^ Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: -*extension* +_ +Matching over values of open types must include +a wild card pattern in order to be exhaustive. type foo = .. type foo += Foo val f : foo -> unit = <fun> diff --git a/testsuite/tests/typing-modules-bugs/pr6572_ok.ml b/testsuite/tests/typing-modules-bugs/pr6572_ok.ml new file mode 100644 index 00000000..00c2f091 --- /dev/null +++ b/testsuite/tests/typing-modules-bugs/pr6572_ok.ml @@ -0,0 +1,19 @@ +module type S = sig + include Set.S + module E : sig val x : int end +end + +module Make(O : Set.OrderedType) : S with type elt = O.t = + struct + include Set.Make(O) + module E = struct let x = 1 end + end + +module rec A : Set.OrderedType = struct + type t = int + let compare = Pervasives.compare +end +and B : S = struct + module C = Make(A) + include C +end diff --git a/testsuite/tests/typing-modules/aliases.ml b/testsuite/tests/typing-modules/aliases.ml index 3eca5271..7580bebe 100644 --- a/testsuite/tests/typing-modules/aliases.ml +++ b/testsuite/tests/typing-modules/aliases.ml @@ -235,3 +235,12 @@ module R = struct module Q = M end;; module R' : S = R;; (* should be ok *) + +(* PR#6578 *) + +module M = struct let f x = x end +module rec R : sig module M : sig val f : 'a -> 'a end end = + struct module M = M end;; +R.M.f 3;; +module rec R : sig module M = M end = struct module M = M end;; +R.M.f 3;; diff --git a/testsuite/tests/typing-modules/aliases.ml.reference b/testsuite/tests/typing-modules/aliases.ml.reference index 2bb3231d..6f0fe745 100644 --- a/testsuite/tests/typing-modules/aliases.ml.reference +++ b/testsuite/tests/typing-modules/aliases.ml.reference @@ -411,4 +411,9 @@ Error: Signature mismatch: sig module N = M.N module P = M.P end In module Q.N: Modules do not match: sig end is not included in (module M.N) +# module M : sig val f : 'a -> 'a end +module rec R : sig module M : sig val f : 'a -> 'a end end +# - : int = 3 +# module rec R : sig module M = M end +# - : int = 3 # diff --git a/testsuite/tests/typing-short-paths/short-paths.ml b/testsuite/tests/typing-short-paths/short-paths.ml index 56160906..a9812f4f 100644 --- a/testsuite/tests/typing-short-paths/short-paths.ml +++ b/testsuite/tests/typing-short-paths/short-paths.ml @@ -46,3 +46,9 @@ module M1 = struct type u = v and v = t1 end;; module N1 = struct type u = v and v = M1.v end;; type t1 = B;; module N2 = struct type u = v and v = M1.v end;; + + +(* PR#6566 *) +module type PR6566 = sig type t = string end;; +module PR6566 = struct type t = int end;; +module PR6566' : PR6566 = PR6566;; diff --git a/testsuite/tests/typing-short-paths/short-paths.ml.reference b/testsuite/tests/typing-short-paths/short-paths.ml.reference index 657a5214..53309ad3 100644 --- a/testsuite/tests/typing-short-paths/short-paths.ml.reference +++ b/testsuite/tests/typing-short-paths/short-paths.ml.reference @@ -69,4 +69,15 @@ type u = M.u = C # module N1 : sig type u = v and v = t1 end # type t1 = B # module N2 : sig type u = v and v = N1.v end +# module type PR6566 = sig type t = bytes end +# module PR6566 : sig type t = int end +# Characters 26-32: + module PR6566' : PR6566 = PR6566;; + ^^^^^^ +Error: Signature mismatch: + Modules do not match: sig type t = int end is not included in PR6566 + Type declarations do not match: + type t = int + is not included in + type t = bytes # diff --git a/tools/.depend b/tools/.depend index b0407009..c33f5c6f 100644 --- a/tools/.depend +++ b/tools/.depend @@ -1,4 +1,4 @@ -depend.cmi : ../parsing/parsetree.cmi +depend.cmi : ../parsing/parsetree.cmi ../parsing/longident.cmi profiling.cmi : tast_iter.cmi : ../typing/typedtree.cmi ../parsing/asttypes.cmi untypeast.cmi : ../typing/typedtree.cmi ../typing/path.cmi \ @@ -52,11 +52,13 @@ ocaml299to3.cmx : ocamlcp.cmo : ../driver/main_args.cmi ocamlcp.cmx : ../driver/main_args.cmx ocamldep.cmo : ../driver/pparse.cmi ../parsing/parsetree.cmi \ - ../parsing/parse.cmi ../utils/misc.cmi ../parsing/location.cmi depend.cmi \ - ../utils/config.cmi ../driver/compenv.cmi ../utils/clflags.cmi + ../parsing/parse.cmi ../utils/misc.cmi ../parsing/longident.cmi \ + ../parsing/location.cmi depend.cmi ../utils/config.cmi \ + ../driver/compenv.cmi ../utils/clflags.cmi ocamldep.cmx : ../driver/pparse.cmx ../parsing/parsetree.cmi \ - ../parsing/parse.cmx ../utils/misc.cmx ../parsing/location.cmx depend.cmx \ - ../utils/config.cmx ../driver/compenv.cmx ../utils/clflags.cmx + ../parsing/parse.cmx ../utils/misc.cmx ../parsing/longident.cmx \ + ../parsing/location.cmx depend.cmx ../utils/config.cmx \ + ../driver/compenv.cmx ../utils/clflags.cmx ocamlmklib.cmo : ocamlmklibconfig.cmo ocamlmklib.cmx : ocamlmklibconfig.cmx ocamlmklibconfig.cmo : diff --git a/tools/depend.ml b/tools/depend.ml index c6dc1433..aeb121cb 100644 --- a/tools/depend.ml +++ b/tools/depend.ml @@ -21,20 +21,21 @@ module StringSet = Set.Make(struct type t = string let compare = compare end) let free_structure_names = ref StringSet.empty -let rec addmodule bv lid = - match lid with - Lident s -> +let rec add_path bv = function + | Lident s -> if not (StringSet.mem s bv) then free_structure_names := StringSet.add s !free_structure_names - | Ldot(l, _s) -> addmodule bv l - | Lapply(l1, l2) -> addmodule bv l1; addmodule bv l2 + | Ldot(l, _s) -> add_path bv l + | Lapply(l1, l2) -> add_path bv l1; add_path bv l2 + +let open_module bv lid = add_path bv lid let add bv lid = match lid.txt with - Ldot(l, _s) -> addmodule bv l + Ldot(l, _s) -> add_path bv l | _ -> () -let addmodule bv lid = addmodule bv lid.txt +let addmodule bv lid = add_path bv lid.txt let rec add_type bv ty = match ty.ptyp_desc with @@ -192,7 +193,7 @@ let rec add_expr bv exp = let bv = add_pattern bv pat in List.iter (add_class_field bv) fieldl | Pexp_newtype (_, e) -> add_expr bv e | Pexp_pack m -> add_module bv m - | Pexp_open (_ovf, m, e) -> addmodule bv m; add_expr bv e + | Pexp_open (_ovf, m, e) -> open_module bv m.txt; add_expr bv e | Pexp_extension _ -> () and add_cases bv cases = @@ -260,7 +261,7 @@ and add_sig_item bv item = end; bv | Psig_open od -> - addmodule bv od.popen_lid; bv + open_module bv od.popen_lid.txt; bv | Psig_include incl -> add_modtype bv incl.pincl_mod; bv | Psig_class cdl -> @@ -321,7 +322,7 @@ and add_struct_item bv item = end; bv | Pstr_open od -> - addmodule bv od.popen_lid; bv + open_module bv od.popen_lid.txt; bv | Pstr_class cdl -> List.iter (add_class_declaration bv) cdl; bv | Pstr_class_type cdtl -> diff --git a/tools/depend.mli b/tools/depend.mli index f859cfef..93fc084f 100644 --- a/tools/depend.mli +++ b/tools/depend.mli @@ -16,6 +16,8 @@ module StringSet : Set.S with type elt = string val free_structure_names : StringSet.t ref +val open_module : StringSet.t -> Longident.t -> unit + val add_use_file : StringSet.t -> Parsetree.toplevel_phrase list -> unit val add_signature : StringSet.t -> Parsetree.signature -> unit diff --git a/tools/ocamldep.ml b/tools/ocamldep.ml index 59fecc41..db0695c9 100644 --- a/tools/ocamldep.ml +++ b/tools/ocamldep.ml @@ -56,18 +56,21 @@ let readdir dir = dirs := StringMap.add dir contents !dirs; contents +let add_to_list li s = + li := s :: !li + let add_to_load_path dir = try let dir = Misc.expand_directory Config.standard_library dir in let contents = readdir dir in - load_path := (dir, contents) :: !load_path + add_to_list load_path (dir, contents) with Sys_error msg -> Format.fprintf Format.err_formatter "@[Bad -I option: %s@]@." msg; error_occurred := true let add_to_synonym_list synonyms suffix = if (String.length suffix) > 1 && suffix.[0] = '.' then - synonyms := suffix :: !synonyms + add_to_list synonyms suffix else begin Format.fprintf Format.err_formatter "@[Bad suffix: '%s'@]@." suffix; error_occurred := true @@ -220,8 +223,14 @@ let read_parse_and_extract parse_function extract_function magic source_file = let input_file = Pparse.preprocess source_file in begin try let ast = - Pparse.file ~tool_name Format.err_formatter input_file parse_function magic in - extract_function Depend.StringSet.empty ast; + Pparse.file ~tool_name Format.err_formatter + input_file parse_function magic + in + let bound_vars = Depend.StringSet.empty in + List.iter (fun modname -> + Depend.open_module bound_vars (Longident.Lident modname) + ) !Clflags.open_modules; + extract_function bound_vars ast; Pparse.remove_preprocessed input_file; !Depend.free_structure_names with x -> @@ -405,14 +414,14 @@ let print_version_num () = let _ = Clflags.classic := false; - first_include_dirs := Filename.current_dir_name :: !first_include_dirs; + add_to_list first_include_dirs Filename.current_dir_name; Compenv.readenv ppf Before_args; Arg.parse [ "-absname", Arg.Set Location.absname, " Show absolute filenames in error messages"; "-all", Arg.Set all_dependencies, " Generate dependencies on all files"; - "-I", Arg.String (fun s -> Clflags.include_dirs := s :: !Clflags.include_dirs), + "-I", Arg.String (add_to_list Clflags.include_dirs), "<dir> Add <dir> to the list of include directories"; "-impl", Arg.String (file_dependencies_as ML), "<f> Process <f> as a .ml file"; @@ -428,9 +437,11 @@ let _ = " Generate dependencies for native-code only (no .cmo files)"; "-one-line", Arg.Set one_line, " Output one line per file, regardless of the length"; + "-open", Arg.String (add_to_list Clflags.open_modules), + "<module> Opens the module <module> before typing"; "-pp", Arg.String(fun s -> Clflags.preprocessor := Some s), "<cmd> Pipe sources through preprocessor <cmd>"; - "-ppx", Arg.String(fun s -> first_ppx := s :: !first_ppx), + "-ppx", Arg.String (add_to_list first_ppx), "<cmd> Pipe abstract syntax trees through preprocessor <cmd>"; "-slash", Arg.Set Clflags.force_slash, " (Windows) Use forward slash / instead of backslash \\ in file paths"; diff --git a/toplevel/topdirs.ml b/toplevel/topdirs.ml index d3387a3f..4773c3f0 100644 --- a/toplevel/topdirs.ml +++ b/toplevel/topdirs.ml @@ -62,7 +62,7 @@ let check_consistency ppf filename cu = try List.iter (fun (name, crco) -> - Env.imported_units := name :: !Env.imported_units; + Env.add_import name; match crco with None -> () | Some crc-> @@ -271,6 +271,8 @@ let dir_trace ppf lid = (* Nothing to do if it's not a closure *) if Obj.is_block clos && (Obj.tag clos = Obj.closure_tag || Obj.tag clos = Obj.infix_tag) + && (match Ctype.(repr (expand_head !toplevel_env desc.val_type)) + with {desc=Tarrow _} -> true | _ -> false) then begin match is_traced clos with | Some opath -> diff --git a/toplevel/toploop.ml b/toplevel/toploop.ml index 482150a1..9fa802ca 100644 --- a/toplevel/toploop.ml +++ b/toplevel/toploop.ml @@ -323,11 +323,14 @@ let protect r newval body = let use_print_results = ref true -let phrase ppf phr = +let preprocess_phrase ppf phr = let phr = match phr with | Ptop_def str -> - Ptop_def (Pparse.apply_rewriters ~tool_name:"ocaml" ast_impl_magic_number str) + let str = + Pparse.apply_rewriters_str ~restore:true ~tool_name:"ocaml" str + in + Ptop_def str | phr -> phr in if !Clflags.dump_parsetree then Printast.top_phrase ppf phr; @@ -354,7 +357,7 @@ let use_file ppf wrap_mod name = try List.iter (fun ph -> - let ph = phrase ppf ph in + let ph = preprocess_phrase ppf ph in if not (execute_phrase !use_print_results ppf ph) then raise Exit) (if wrap_mod then parse_mod_use_file name lb @@ -429,7 +432,7 @@ let _ = Compmisc.init_path false; List.iter (fun (name, crco) -> - Env.imported_units := name :: !Env.imported_units; + Env.add_import name; match crco with None -> () | Some crc-> @@ -480,7 +483,7 @@ let loop ppf = Location.reset(); first_line := true; let phr = try !parse_toplevel_phrase lb with Exit -> raise PPerror in - let phr = phrase ppf phr in + let phr = preprocess_phrase ppf phr in Env.reset_cache_toplevel (); ignore(execute_phrase true ppf phr) with diff --git a/toplevel/toploop.mli b/toplevel/toploop.mli index 5f0b86e2..1867c001 100644 --- a/toplevel/toploop.mli +++ b/toplevel/toploop.mli @@ -53,6 +53,9 @@ val execute_phrase : bool -> formatter -> Parsetree.toplevel_phrase -> bool phrase executed with no errors and [false] otherwise. First bool says whether the values and types of the results should be printed. Uncaught exceptions are always printed. *) +val preprocess_phrase : formatter -> Parsetree.toplevel_phrase -> Parsetree.toplevel_phrase + (* Preprocess the given toplevel phrase using regular and ppx + preprocessors. Return the updated phrase. *) val use_file : formatter -> string -> bool val use_silently : formatter -> string -> bool val mod_use_file : formatter -> string -> bool diff --git a/toplevel/topmain.ml b/toplevel/topmain.ml index d1dbeca9..0d8f2d4c 100644 --- a/toplevel/topmain.ml +++ b/toplevel/topmain.ml @@ -41,6 +41,7 @@ let file_argument name = let newargs = Array.sub Sys.argv !Arg.current (Array.length Sys.argv - !Arg.current) in + Compenv.readenv ppf Before_link; if prepare ppf && Toploop.run_script ppf name newargs then exit 0 else exit 2 diff --git a/typing/env.ml b/typing/env.ml index c5c3a5ff..7df15660 100644 --- a/typing/env.ml +++ b/typing/env.ml @@ -296,6 +296,7 @@ type pers_struct = ps_sig: signature; ps_comps: module_components; ps_crcs: (string * Digest.t option) list; + mutable ps_crcs_checked: bool; ps_filename: string; ps_flags: pers_flags list } @@ -305,22 +306,31 @@ let persistent_structures = (* Consistency between persistent structures *) let crc_units = Consistbl.create() -let imported_units = ref ([] : string list) + +module StringSet = + Set.Make(struct type t = string let compare = String.compare end) + +let imported_units = ref StringSet.empty + +let add_import s = + imported_units := StringSet.add s !imported_units let clear_imports () = Consistbl.clear crc_units; - imported_units := [] + imported_units := StringSet.empty let check_consistency ps = + if not ps.ps_crcs_checked then try List.iter (fun (name, crco) -> match crco with None -> () | Some crc -> - imported_units := name :: !imported_units; + add_import name; Consistbl.check crc_units name crc ps.ps_filename) - ps.ps_crcs + ps.ps_crcs; + ps.ps_crcs_checked <- true; with Consistbl.Inconsistency(name, source, auth) -> error (Inconsistent_import(name, auth, source)) @@ -342,10 +352,12 @@ let read_pers_struct modname filename = ps_comps = comps; ps_crcs = crcs; ps_filename = filename; - ps_flags = flags } in + ps_flags = flags; + ps_crcs_checked = false; + } in if ps.ps_name <> modname then error (Illegal_renaming(modname, ps.ps_name, filename)); - imported_units := name :: !imported_units; + add_import name; List.iter (function Rectypes -> if not !Clflags.recursive_types then @@ -1597,7 +1609,7 @@ let crc_of_unit name = (* Return the list of imported interfaces with their CRCs *) let imports() = - Consistbl.extract !imported_units crc_units + Consistbl.extract (StringSet.elements !imported_units) crc_units (* Save a signature to a file *) @@ -1628,10 +1640,12 @@ let save_signature_with_imports sg modname filename imports = ps_comps = comps; ps_crcs = (cmi.cmi_name, Some crc) :: imports; ps_filename = filename; - ps_flags = cmi.cmi_flags } in + ps_flags = cmi.cmi_flags; + ps_crcs_checked = false; + } in Hashtbl.add persistent_structures modname (Some ps); Consistbl.set crc_units modname crc filename; - imported_units := modname :: !imported_units; + add_import modname; sg with exn -> close_out oc; diff --git a/typing/env.mli b/typing/env.mli index 4db5a847..ed2f6f1c 100644 --- a/typing/env.mli +++ b/typing/env.mli @@ -168,7 +168,7 @@ val imports: unit -> (string * Digest.t option) list (* Direct access to the table of imported compilation units with their CRC *) val crc_units: Consistbl.t -val imported_units: string list ref +val add_import: string -> unit (* Summaries -- compact representation of an environment, to be exported in debugging information. *) diff --git a/typing/includemod.ml b/typing/includemod.ml index 223214f3..91f37d7c 100644 --- a/typing/includemod.ml +++ b/typing/includemod.ml @@ -61,12 +61,12 @@ let value_descriptions env cxt subst id vd1 vd2 = (* Inclusion between type declarations *) -let type_declarations env cxt subst id decl1 decl2 = +let type_declarations env ?(old_env=env) cxt subst id decl1 decl2 = Env.mark_type_used env (Ident.name id) decl1; let decl2 = Subst.type_declaration subst decl2 in let err = Includecore.type_declarations env (Ident.name id) decl1 id decl2 in if err <> [] then - raise(Error[cxt, env, Type_declarations(id, decl1, decl2, err)]) + raise(Error[cxt, old_env, Type_declarations(id, decl1, decl2, err)]) (* Inclusion between extension constructors *) @@ -78,19 +78,20 @@ let extension_constructors env cxt subst id ext1 ext2 = (* Inclusion between class declarations *) -let class_type_declarations env cxt subst id decl1 decl2 = +let class_type_declarations ~old_env env cxt subst id decl1 decl2 = let decl2 = Subst.cltype_declaration subst decl2 in match Includeclass.class_type_declarations env decl1 decl2 with [] -> () | reason -> - raise(Error[cxt, env, Class_type_declarations(id, decl1, decl2, reason)]) + raise(Error[cxt, old_env, + Class_type_declarations(id, decl1, decl2, reason)]) -let class_declarations env cxt subst id decl1 decl2 = +let class_declarations ~old_env env cxt subst id decl1 decl2 = let decl2 = Subst.class_declaration subst decl2 in match Includeclass.class_declarations env decl1 decl2 with [] -> () | reason -> - raise(Error[cxt, env, Class_declarations(id, decl1, decl2, reason)]) + raise(Error[cxt, old_env, Class_declarations(id, decl1, decl2, reason)]) (* Expand a module type identifier when possible *) @@ -314,7 +315,7 @@ and signatures env cxt subst sig1 sig2 = begin match unpaired with [] -> let cc = - signature_components new_env cxt subst (List.rev paired) + signature_components env new_env cxt subst (List.rev paired) in if len1 = len2 then (* see PR#5098 *) simplify_structure_coercion cc id_pos_list @@ -363,36 +364,38 @@ and signatures env cxt subst sig1 sig2 = (* Inclusion between signature components *) -and signature_components env cxt subst = function +and signature_components old_env env cxt subst paired = + let comps_rec rem = signature_components old_env env cxt subst rem in + match paired with [] -> [] | (Sig_value(id1, valdecl1), Sig_value(id2, valdecl2), pos) :: rem -> let cc = value_descriptions env cxt subst id1 valdecl1 valdecl2 in begin match valdecl2.val_kind with - Val_prim p -> signature_components env cxt subst rem - | _ -> (pos, cc) :: signature_components env cxt subst rem + Val_prim p -> comps_rec rem + | _ -> (pos, cc) :: comps_rec rem end | (Sig_type(id1, tydecl1, _), Sig_type(id2, tydecl2, _), pos) :: rem -> - type_declarations env cxt subst id1 tydecl1 tydecl2; - signature_components env cxt subst rem + type_declarations ~old_env env cxt subst id1 tydecl1 tydecl2; + comps_rec rem | (Sig_typext(id1, ext1, _), Sig_typext(id2, ext2, _), pos) :: rem -> extension_constructors env cxt subst id1 ext1 ext2; - (pos, Tcoerce_none) :: signature_components env cxt subst rem + (pos, Tcoerce_none) :: comps_rec rem | (Sig_module(id1, mty1, _), Sig_module(id2, mty2, _), pos) :: rem -> let cc = modtypes env (Module id1::cxt) subst (Mtype.strengthen env mty1.md_type (Pident id1)) mty2.md_type in - (pos, cc) :: signature_components env cxt subst rem + (pos, cc) :: comps_rec rem | (Sig_modtype(id1, info1), Sig_modtype(id2, info2), pos) :: rem -> modtype_infos env cxt subst id1 info1 info2; - signature_components env cxt subst rem + comps_rec rem | (Sig_class(id1, decl1, _), Sig_class(id2, decl2, _), pos) :: rem -> - class_declarations env cxt subst id1 decl1 decl2; - (pos, Tcoerce_none) :: signature_components env cxt subst rem + class_declarations ~old_env env cxt subst id1 decl1 decl2; + (pos, Tcoerce_none) :: comps_rec rem | (Sig_class_type(id1, info1, _), Sig_class_type(id2, info2, _), pos) :: rem -> - class_type_declarations env cxt subst id1 info1 info2; - signature_components env cxt subst rem + class_type_declarations ~old_env env cxt subst id1 info1 info2; + comps_rec rem | _ -> assert false @@ -540,7 +543,7 @@ let rec context ppf = function | Modtype id :: rem -> fprintf ppf "@[<2>module type %a =@ %a@]" ident id context_mty rem | Body x :: rem -> - fprintf ppf "functor (%a) ->@ %a" ident x context_mty rem + fprintf ppf "functor (%s) ->@ %a" (argname x) context_mty rem | Arg x :: rem -> fprintf ppf "functor (%a : %a) -> ..." ident x context_mty rem | [] -> @@ -551,11 +554,14 @@ and context_mty ppf = function | cxt -> context ppf cxt and args ppf = function Body x :: rem -> - fprintf ppf "(%a)%a" ident x args rem + fprintf ppf "(%s)%a" (argname x) args rem | Arg x :: rem -> fprintf ppf "(%a :@ %a) : ..." ident x context_mty rem | cxt -> fprintf ppf " :@ %a" context_mty cxt +and argname x = + let s = Ident.name x in + if s = "*" then "" else s let path_of_context = function Module id :: rem -> diff --git a/typing/mtype.ml b/typing/mtype.ml index dd766a91..21d6b871 100644 --- a/typing/mtype.ml +++ b/typing/mtype.ml @@ -350,7 +350,9 @@ let rec remove_aliases env excl mty = Mty_signature sg -> Mty_signature (remove_aliases_sig env excl sg) | Mty_alias _ -> - remove_aliases env excl (Env.scrape_alias env mty) + let mty' = Env.scrape_alias env mty in + if mty' = mty then mty else + remove_aliases env excl mty' | mty -> mty diff --git a/typing/parmatch.ml b/typing/parmatch.ml index 17297974..6732be7a 100644 --- a/typing/parmatch.ml +++ b/typing/parmatch.ml @@ -1809,7 +1809,11 @@ let do_check_partial ?pred exhaust loc casel pss = match pss with None -> Total | Some v -> let errmsg = - try + match v.pat_desc with + Tpat_construct (_, {cstr_name="*extension*"}, _) -> + "_\nMatching over values of open types must include\n\ + a wild card pattern in order to be exhaustive." + | _ -> try let buf = Buffer.create 16 in let fmt = formatter_of_buffer buf in top_pretty fmt v; @@ -1825,9 +1829,11 @@ let do_check_partial ?pred exhaust loc casel pss = match pss with end ; Buffer.contents buf with _ -> - "" in + "" + in Location.prerr_warning loc (Warnings.Partial_match errmsg) ; - Partial end + Partial + end | _ -> fatal_error "Parmatch.check_partial" end diff --git a/typing/typecore.ml b/typing/typecore.ml index 16a310d6..b173d99c 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -2905,6 +2905,8 @@ and type_format loc str env = mk_constr "Ignored_scan_get_counter" [ mk_counter counter ] + | Ignored_scan_next_char -> + mk_constr "Ignored_scan_next_char" [] and mk_padding : type x y . (x, y) padding -> Parsetree.expression = fun pad -> match pad with | No_padding -> mk_constr "No_padding" [] @@ -2970,6 +2972,8 @@ and type_format loc str env = mk_int_opt width_opt; mk_string char_set; mk_fmt rest ] | Scan_get_counter (cnt, rest) -> mk_constr "Scan_get_counter" [ mk_counter cnt; mk_fmt rest ] + | Scan_next_char rest -> + mk_constr "Scan_next_char" [ mk_fmt rest ] | Ignored_param (ign, rest) -> mk_constr "Ignored_param" [ mk_ignored ign; mk_fmt rest ] | End_of_format -> diff --git a/utils/consistbl.ml b/utils/consistbl.ml index 6adaf411..37f6a2b1 100644 --- a/utils/consistbl.ml +++ b/utils/consistbl.ml @@ -41,12 +41,9 @@ let set tbl name crc source = Hashtbl.add tbl name (crc, source) let source tbl name = snd (Hashtbl.find tbl name) let extract l tbl = + let l = List.sort_uniq String.compare l in List.fold_left (fun assc name -> - try - ignore (List.assoc name assc); - assc - with Not_found -> try let (crc, _) = Hashtbl.find tbl name in (name, Some crc) :: assc diff --git a/utils/misc.ml b/utils/misc.ml index 898880cb..2eb8088e 100644 --- a/utils/misc.ml +++ b/utils/misc.ml @@ -87,6 +87,22 @@ let find_in_path path name = in try_dir path end +let find_in_path_rel path name = + let rec simplify s = + let open Filename in + let base = basename s in + let dir = dirname s in + if dir = s then dir + else if base = current_dir_name then simplify dir + else concat (simplify dir) base + in + let rec try_dir = function + [] -> raise Not_found + | dir::rem -> + let fullname = simplify (Filename.concat dir name) in + if Sys.file_exists fullname then fullname else try_dir rem + in try_dir path + let find_in_path_uncap path name = let uname = String.uncapitalize name in let rec try_dir = function diff --git a/utils/misc.mli b/utils/misc.mli index 4a3c84b2..5168a6a9 100644 --- a/utils/misc.mli +++ b/utils/misc.mli @@ -42,6 +42,8 @@ val may_map: ('a -> 'b) -> 'a option -> 'b option val find_in_path: string list -> string -> string (* Search a file in a list of directories. *) +val find_in_path_rel: string list -> string -> string + (* Search a relative file in a list of directories. *) val find_in_path_uncap: string list -> string -> string (* Same, but search also for uncapitalized name, i.e. if name is Foo.ml, allow /path/Foo.ml and /path/foo.ml -- 2.30.2